RDK Documentation (Open Sourced RDK Components)
indicator.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 #include "indicator.hpp"
20 #include "frontPanelConfig.hpp"
21 static const unsigned int INVALID_COLOR = 0xFFFFFFFF;
22 
23 /**
24  * @addtogroup LED_APIS
25  * @{
26  */
27 
28 
29  /**
30  * @brief Callback function to perform indicator brightness with type "Blink".
31  *
32  * @param[in] data address of indicator class.
33  *
34  * @return Returns corresponding blink pattern info structure.
35  */
36  static gboolean masterBlinkCallbackFunction(gpointer data)
37 {
38  indicator *ptr = (indicator *)data;
39  DEBUG("Enter\n");
40  ptr->timerCallback();
41  return false;
42 }
43 
44 /**
45  * @brief Callback function to preform indicator brightness with flare value.
46  *
47  * @param[in] data address of indicator class.
48  *
49  * @return Returns corresponding blink pattern info structure.
50  */
51 static gboolean masterFlareCallbackFunction(gpointer data)
52 {
53  indicator *ptr = (indicator *)data;
54  DEBUG("Enter\n");
55  ptr->flareCallback();
56  return false;
57 }
58 
59 indicator::indicator(const std::string &name)
60 {
61  m_name = name;
62  m_source_id = 0;
63  m_saved_properties.isValid = false;
64  pthread_mutexattr_t mutex_attribute;
65  REPORT_IF_UNEQUAL(0, pthread_mutexattr_init(&mutex_attribute));
66  REPORT_IF_UNEQUAL(0, pthread_mutexattr_settype(&mutex_attribute, PTHREAD_MUTEX_RECURSIVE));
67  REPORT_IF_UNEQUAL(0, pthread_mutex_init(&m_mutex, &mutex_attribute));
68 
69  /*Caching a reference to the DS instance of the indicator. This is safe because
70  * we don't expect the indicator instances in DS to change once initialized.
71  * Below line may throw an exception*/
72  m_indicator = &(device::FrontPanelConfig::getInstance().getIndicator(m_name));
73  #if 0 //Temporarily disabled until DELIA-6363 is available in stable2
74  m_state = (true == m_indicator->getState() ? STATE_STEADY_ON : STATE_STEADY_OFF);
75  #else
76  m_state = STATE_STEADY_OFF; //safe default
77  #endif
78  INFO("Indicator %s initialized to state 0x%x\n", m_name.c_str(), m_state);
79 }
80 
81 indicator::~indicator()
82 {
83  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
84  if(0 != m_source_id)
85  {
86  REPORT_IF_UNEQUAL(true, g_source_remove(m_source_id));
87  m_source_id = 0;
88  }
89  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
90  pthread_mutex_destroy(&m_mutex);
91 }
92 
93 /**
94  * @brief API to return the indicator name.
95  *
96  * @return Returns indicator name.
97  */
98 const std::string& indicator::getName() const
99 {
100  return m_name;
101 }
102 
103 /**
104  * @brief This API sets the indicator color.
105  *
106  * @param[in] color indicator color to be set.
107  *
108  */
109 void indicator::setColor(const unsigned int color)
110 {
111  using namespace device;
112  try
113  {
114  m_indicator->setColor(color, false);
115  }
116  catch(...)
117  {
118  ERROR("Error setting color!\n");
119  }
120 }
121 
122 /**
123  * @brief This API sets the brightness of the specified LED.
124  *
125  * @param[in] intensity intensity value of brightness.
126  */
127 void indicator::setBrightness(unsigned int intensity)
128 {
129  using namespace device;
130  try
131  {
132  m_indicator->setBrightness(intensity, false);
133  }
134  catch(...)
135  {
136  ERROR("Error setting indicator brightness!\n");
137  }
138 }
139 
140 /**
141  * @brief This API enables the indicator to blink with the specified blinking pattern.
142  *
143  * @param[in] pattern blink pattern.
144  * @param[in] repetitions number of repetition count.
145  *
146  * @return Returns status of the operation.
147  */
148 int indicator::setBlink(const blinkPattern_t *pattern, int repetitions)
149 {
150  if((0 == repetitions) || (2 > pattern->num_sequences))
151  {
152  ERROR("Bad inputs!\n");
153  return -1;
154  }
155  INFO("Start\n");
156  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
157 
158 
159  /*Cancel previous blink pattern if any*/
160  if(0 != m_source_id)
161  {
162  REPORT_IF_UNEQUAL(true, g_source_remove(m_source_id));
163  m_source_id = 0;
164  }
165  /*Check whether the indicator is currently disabled. Enable
166  * it if it is.*/
167  else if(STATE_STEADY_OFF == m_state)
168  {
169  DEBUG("Indicator is currently disabled. Turning it back on.\n");
170  enableIndicator(true);
171  }
172 
173  m_state = STATE_BLINKING;
174  m_pattern_ptr = pattern;
175  m_pattern_repetitions = repetitions;
176  m_sequence_read_offset = 0;
177  step();
178  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
179  INFO("Done\n");
180  return 0;
181 }
182 
183 /**
184  * @brief This API is to register timer callback function depends on iteration pattern(indefinite iteration and finite iteration).
185  *
186  * @return Returns status of the operation.
187  */
189 {
190  DEBUG("Start\n");
191  unsigned char offset = m_sequence_read_offset;
192  enableIndicator(m_pattern_ptr->sequence[offset].isOn);
193 
194  /* Advance offset (in other words, the pattern's read-pointer)
195  * for next the next step.*/
196  m_sequence_read_offset = (m_sequence_read_offset + 1) % m_pattern_ptr->num_sequences;
197  //TODO: Temporary, for developer confidence
198  if(m_sequence_read_offset == m_pattern_ptr->num_sequences)
199  {
200  ERROR("Out of bounds access!\n");
201  }
202 
203  /* Evaluate whether a callback is necessary:
204  * A callback is necessary when at least one of the below conditions is true:
205  * 1. Pattern is required to iterate indefinitely (m_pattern_repetitions = -1).
206  * 2. There are remaining iterations to be executed.
207  * 3. There are steps remaining to be executed in the present iteration of the
208  * pattern.
209  * */
210  if(-1 == m_pattern_repetitions)
211  {
212  registerCallback(m_pattern_ptr->sequence[offset].length);
213  }
214  else
215  {
216  /* Only finite iterations are to be executed. Check whether there are
217  * steps or iterations remaining.*/
218  if(0 == m_sequence_read_offset)
219  {
220  /* We've completed an iteration. Since we're executing limited iterations,
221  * update the counter*/
222  m_pattern_repetitions--;
223  if(0 < m_pattern_repetitions)
224  {
225  /* There are iterations pending */
226  registerCallback(m_pattern_ptr->sequence[offset].length);
227  DEBUG("End iteration\n");
228  }
229  else
230  {
231  DEBUG("Final iteration complete\n");
232  }
233  }
234  else
235  {
236  /* More steps remain to complete this iteration. */
237  registerCallback(m_pattern_ptr->sequence[offset].length);
238  }
239  }
240  return 0;
241 }
242 
243 /**
244  * @brief This API requests to process the pattern iteration steps.
245  */
247 {
248  DEBUG("Enter\n");
249  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
250  m_source_id = 0;
251  step();
252  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
253  return 0;
254 }
255 
256 /**
257  * @brief This API register timer callback function in order to complete the blinking pattern iteration count.
258  *
259  * @param[in] milliseconds time interval between calls to the callback function.
260  *
261  * @return Returns status of the operation.
262  */
263 int indicator::registerCallback(unsigned int milliseconds)
264 {
265  if(0 == milliseconds)
266  {
267  ERROR("Zero-wait timer!\n");
268  return -1;
269  }
270  m_source_id = g_timeout_add(milliseconds, masterBlinkCallbackFunction, (gpointer)this);
271  if(0 == m_source_id)
272  {
273  ERROR("Could not register callback!\n");
274  }
275  return 0;
276 }
277 
278 /**
279  * @brief This API cancel the current blinking indicator if any, to change the state .
280  *
281  * @param[in] state indicator state.
282  *
283  * @return Returns status of the operation.
284  */
285 int indicator::setState(indicatorState_t state)
286 {
287  INFO("state 0x%x\n", state);
288  if((STATE_STEADY_ON != state) && (STATE_STEADY_OFF != state))
289  {
290  ERROR("Unsupported state!\n");
291  return -1;
292  }
293 
294  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
295  /*Cancel any blinking*/
296  if(STATE_BLINKING == m_state)
297  {
298  if(0 != m_source_id)
299  {
300  REPORT_IF_UNEQUAL(true, g_source_remove(m_source_id));
301  m_source_id = 0;
302  INFO("Cancelled previously started blink operation\n");
303  }
304  }
305  m_state = state;
306  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
307 
308  if(STATE_STEADY_ON == state)
309  {
310  enableIndicator(true);
311  }
312  else
313  {
314  enableIndicator(false);
315  }
316  return 0;
317 }
318 
319 /**
320  * @brief This API sets the indicator state.
321  *
322  * @param[in] enable indicator state.
323  *
324  * @return Returns status of the operation.
325  */
327 {
328  using namespace device;
329  try
330  {
331  m_indicator->setState(enable);
332  }
333  catch(...)
334  {
335  ERROR("Could not change indicator state!\n");
336  }
337  return 0;
338 }
339 
340 /**
341  * @brief This API saves all the current indicator related properties.
342  *
343  * When iterations >= 0 and the number of iterations has successfully completed, the LED will be left to the color/brightness as specified
344  * by the LAST element in the array
345  */
347 {
348  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
349  m_saved_properties.state = m_state;
350  if(STATE_BLINKING == m_state)
351  {
352  m_saved_properties.sequence_read_offset = m_sequence_read_offset;
353  m_saved_properties.pattern_ptr = m_pattern_ptr;
354  m_saved_properties.pattern_repetitions= m_pattern_repetitions;
355  }
356  try
357  {
358  m_saved_properties.intensity = m_indicator->getBrightness();
359  m_saved_properties.color = m_indicator->getColor();
360  }
361  catch(...)
362  {
363  ERROR("Could not read brightness or color values!\n");
364  m_saved_properties.intensity = 20; //safe default
365  m_saved_properties.intensity= INVALID_COLOR;
366  }
367  m_saved_properties.isValid = true;
368  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
369  INFO("Saved state.\n");
370 }
371 
372 /**
373  * @brief API to restore the indicator properties from saved indicator properties.
374  *
375  * When iterations >= 0 and the number of iterations has successfully completed, the LED will be left to the color/brightness as specified
376  * by the LAST element in the array
377  */
379 {
380  REPORT_IF_UNEQUAL(0, pthread_mutex_lock(&m_mutex));
381  if(m_saved_properties.isValid)
382  {
383  /*Stop whatever we're doing right now.*/
384  setState(STATE_STEADY_OFF);
385 
386  if(INVALID_COLOR != m_saved_properties.color)
387  {
388  setColor(m_saved_properties.color);
389  }
390 
391  m_state = m_saved_properties.state;
392  if(STATE_STEADY_ON == m_state)
393  {
394  enableIndicator(true);
395  INFO("Successfully restored to STEADY ON state.\n");
396  }
397  else if(STATE_BLINKING == m_state)
398  {
399  m_pattern_ptr = m_saved_properties.pattern_ptr;
400  m_sequence_read_offset = m_saved_properties.sequence_read_offset;
401  m_pattern_repetitions = m_saved_properties.pattern_repetitions;
402 
403  /*If the blink pattern is not set to repeat indefinitely and has completed its run,
404  * find out what the last state is supposed to be and set it.*/
405  if(0 == m_pattern_repetitions)
406  {
407  enableIndicator(m_pattern_ptr->sequence[m_pattern_ptr->num_sequences - 1].isOn);
408  INFO("Successfully restored to final holding state of blink pattern.\n");
409  }
410  else
411  {
412  INFO("Successfully restored blink pattern.\n");
413  step();
414  }
415  }
416  m_saved_properties.isValid = false; //This setting has been applied. Mark as stale.
417  }
418  else
419  {
420  ERROR("Won't restore stale settings.\n");
421  }
422  REPORT_IF_UNEQUAL(0, pthread_mutex_unlock(&m_mutex));
423 }
424 
425 /**
426  * @brief Register Flare callback function to set indicator brightness as flare.
427  *
428  * @param[in] percentage_increase flare percentage to be increased.
429  * @param[in] length_ms time interval between calls to the callback function.
430  */
431 void indicator::executeFlare(const unsigned int percentage_increase, const unsigned int length_ms)
432 {
433  using namespace device;
434  unsigned int preflare_brightness = 20;
435  try
436  {
437  preflare_brightness = m_indicator->getBrightness();
438  }
439  catch(...)
440  {
441  ERROR("Could not read brightness!\n");
442  }
443 
444 
445  if(0 == g_timeout_add(length_ms, masterFlareCallbackFunction, (gpointer)this))
446  {
447  ERROR("Could not register callback!\n");
448  }
449  else
450  {
451  unsigned int flare_level = preflare_brightness * (100 + percentage_increase) / 100;
452  if(100 < flare_level)
453  {
454  flare_level = 100;
455  }
456 
457  if(100 == preflare_brightness) {
458  flare_level = (preflare_brightness - percentage_increase);
459  }
460 
461  setBrightness(flare_level);
462  }
463 }
464 
465 /**
466  * @brief API to perform indicator brightness with flare value.
467  */
469 {
470  using namespace device;
471  unsigned int preflare_brightness = 20; //safe default
472  try
473  {
474  preflare_brightness = m_indicator->getBrightness();
475  }
476  catch(...)
477  {
478  ERROR("Could not read brightness!\n");
479  }
480  setBrightness(preflare_brightness);
481 }
482 
483 /** @} */ //END OF GROUP LED_APIS
indicator::registerCallback
int registerCallback(unsigned int milliseconds)
This API register timer callback function in order to complete the blinking pattern iteration count.
Definition: indicator.cpp:263
indicator::setColor
void setColor(const unsigned int color)
This API sets the indicator color.
Definition: indicator.cpp:109
blinkPattern_t::sequence
blinkOp_t * sequence
Definition: ledmgr_types.hpp:63
indicator::timerCallback
int timerCallback(void)
This API requests to process the pattern iteration steps.
Definition: indicator.cpp:246
device::FrontPanelConfig::getInstance
static FrontPanelConfig & getInstance()
This API gets the instance of the FrontPanelConfig. When called for the first time,...
Definition: frontPanelConfig.cpp:82
indicator::executeFlare
void executeFlare(const unsigned int percentage_increase, const unsigned int length_ms)
Register Flare callback function to set indicator brightness as flare.
Definition: indicator.cpp:431
indicator::setBlink
int setBlink(const blinkPattern_t *pattern, int repetitions=-1)
This API enables the indicator to blink with the specified blinking pattern.
Definition: indicator.cpp:148
indicator::setState
int setState(indicatorState_t state)
This API cancel the current blinking indicator if any, to change the state .
Definition: indicator.cpp:285
indicator::enableIndicator
int enableIndicator(bool enable)
This API sets the indicator state.
Definition: indicator.cpp:326
indicator::flareCallback
void flareCallback(void)
API to perform indicator brightness with flare value.
Definition: indicator.cpp:468
indicator
Definition: indicator.hpp:26
blinkOp_t::length
unsigned int length
Definition: ledmgr_types.hpp:55
device::FrontPanelIndicator::getState
bool getState()
This API gets the State of the specified LED indicators.
Definition: frontPanelIndicator.cpp:325
frontPanelConfig.hpp
Structures and classes to manage front panel are defined here.
device::FrontPanelConfig::getIndicator
FrontPanelIndicator & getIndicator(int id)
This function gets an instance of the FrontPanelndicator with the specified id, only if the id passed...
Definition: frontPanelConfig.cpp:147
device::FrontPanelIndicator::getColor
uint32_t getColor()
This API gets the color of the front panel indicator/LED.
Definition: frontPanelIndicator.cpp:455
indicator::step
int step()
This API is to register timer callback function depends on iteration pattern(indefinite iteration and...
Definition: indicator.cpp:188
masterFlareCallbackFunction
static gboolean masterFlareCallbackFunction(gpointer data)
Callback function to preform indicator brightness with flare value.
Definition: indicator.cpp:51
masterBlinkCallbackFunction
static gboolean masterBlinkCallbackFunction(gpointer data)
Callback function to perform indicator brightness with type "Blink".
Definition: indicator.cpp:36
indicator::saveState
void saveState()
This API saves all the current indicator related properties.
Definition: indicator.cpp:346
indicator::restoreState
void restoreState()
API to restore the indicator properties from saved indicator properties.
Definition: indicator.cpp:378
device::FrontPanelIndicator::getBrightness
int getBrightness()
This API gets the brightness of the specified LED indicators.
Definition: frontPanelIndicator.cpp:374
indicator::setBrightness
void setBrightness(unsigned int intensity)
This API sets the brightness of the specified LED.
Definition: indicator.cpp:127
indicator::getName
const std::string & getName() const
API to return the indicator name.
Definition: indicator.cpp:98