RDK Documentation (Open Sourced RDK Components)
reset.c
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 
20 /**
21 * @defgroup iarmmgrs
22 * @{
23 * @defgroup power
24 * @{
25 **/
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/time.h>
33 #include <string.h>
34 #include <fcntl.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <secure_wrapper.h>
38 #include <thread>
39 
40 #include "comcastIrKeyCodes.h"
41 #include "libIBus.h"
42 #include "pwrMgr.h"
43 #include "plat_power.h"
44 #include "libIBusDaemon.h"
45 #include "resetModes.h"
46 #include "frontPanelIndicator.hpp"
47 #include "exception.hpp"
48 #include "manager.hpp"
49 #include "iarmUtil.h"
50 #include "pwrlogger.h"
51 #include "frontPanelConfig.hpp"
52 #include "pwrMgrInternal.h"
53 
54 static pthread_mutex_t tMutexLock;
55 static pthread_cond_t tMutexCond;
56 static long gKeyPressedTime = 0;
57 static long gKeyReleasedTime = 0;
58 static long gCurrentTime = 0;
59 static int gTimeOutValue = 0;
60 static bool inResetMode = false;
61 static bool gResetMonitoredOnIBus = false;
62 static unsigned int gLastResetEvent = 0;
63 static bool gInitialized = false;
64 
65 static bool isRIFocus = false;
66 static bool isXREFocus = false;
67 static bool grabedFocus = false;
68 static int modeIndexStatus = 0;
69 
70 
71 /*Global variable which shows the wait state. Waiting for LED blink. Should not enter any key */
72 static bool gWaitState = false;
73 /*Global variable to inform the timer that the wait state got interrupted by key press*/
74 static bool gResetTimer = true;
75 /*A single key entry has to be checked for all reset modes. This global variable stores the
76 information whether the key is pressed only once but used for different reset modes or a new key*/
77 static bool gIsSameKey = false;
78 static bool gKeyAllowed[] = {true, true, true, true};
79 
80 /* Reset key sequence is taken cared by a statemachine.
81 The Key sequence can vary between different boxes.*/
82 
83 /*Structure to represent the values defining the state
84 of the state machine*/
85 typedef struct keyType
86 {
87  int Key; // Key Value for the specific state
88  int keyMode; // Key Type (Up/Down) for the specific state
89  int waitDuration; // Time to wait for after a particular state
90  int validTime; // Duration with in which the next set of keys need to be entered
91 }keyType_t;
92 
93 /*Structure to pass the time values to the timer thread*/
94 typedef struct timerStruct
95 {
96  int waitFor; // Wait till leds blink before entering next key
97  int validFor; // Enter the next keys in the sequence within this valid time after the leds blink.
99 
100 /*A mapping to the Key Values available in comcastIrKeyCodes.h*/
101 typedef enum keyValue
102 {
103  KEY_NULL=0,
104  KEY_POWER=KED_POWER,
105  KEY_OK=KED_OK,
106  KEY_RIGHT=KED_ARROWRIGHT,
107  KEY_LEFT=KED_ARROWLEFT,
108  KEY_MENU=KED_MENU,
109  KEY_UP=KED_ARROWUP,
110  KEY_DOWN=KED_ARROWDOWN
111 }keyValue_t;
112 
113 /* Key Variants mapping.
114  * In different states remote can send different key codes for the same keys.
115  * this structure for variants definition to to translate variants to defined in reset sequence keys */
116 typedef struct keyVariant
117 {
118  int Key; // Key Value for the specific state
119  int Variant; // Other key code can be generated
120 }keyVariant_t;
121 
122 /*State of the reset statemachine*/
123 typedef enum state
124 {
125  INIT = 0,
126  PROCESS = 1,
127  ENDED = 2
128 }state_t;
129 
130 /*Structure which stores the current state of the statemachine */
131 typedef struct stateMachine
132 {
133  state_t state; /*Currently not used*/
134  int expectedKeyIndex; /*Points to the expected key set for the current state*/
135  int (*resetFuction) (void); /*Function pointer to point to the reset function for the specific reset mode*/
137 
138 /*We have 4 statemachines each for a specific reset mode.
139 All statemachines are initialized to index 0 and ENDED state*/
140 static stateMachine_t coldFactory = {ENDED, 0, processColdFactoryReset};
141 static stateMachine_t factory = {ENDED, 0, processFactoryReset};
142 static stateMachine_t wareHouse = {ENDED, 0, processWareHouseReset};
143 static stateMachine_t customer = {ENDED, 0, processCustomerReset};
144 static stateMachine_t personality = {ENDED, 0, processPersonalityReset};
145 
146 /*An array of the statemachines currently supported. The array is introduced to enable
147 traversing through the specific statemachine from a single function using different
148 array index - resetmode*/
149 stateMachine_t * stateMachineList[] = {&coldFactory, &factory, &wareHouse, &customer, &personality};
150 
151 /*Enumeration to map a resetmode to a number */
152 typedef enum resetType
153 {
154  COLD_FACTORY = 0,
155  FACTORY = 1,
156  WARE_HOUSE = 2,
157  CUSTOMER = 3,
158  PERSONALITY = 4
159 }resetType_t;
160 
161 static const char *resetString [5] = {"CLDINIT", "FR RST", "WH RST", "CUST", "PERS"};
162 
163 /*Structure to store the expected sequence for a specific reset type*/
164 typedef struct KeyMap
165 {
166  resetType_t reset;
167  keyType_t *pData;
168 }KeyMap_t;
169 
170 /*Time values in milliseconds*/
171 #define INITIAL_TIME_OUT_VALUE 10000
172 #define MAX_RESET_MODE_COUNT 5
173 
174 #define KEY_COMBINATION_TIMEOUT 2000
175 #define POWER_KEY_HOLD_TIME_FOR_REBOOT 10000
176 #define POWER_KEY_HOLD_TIME_FOR_RESET 2000
177 #define POWER_KEY_HOLD_TIME_FOR_FACTORY_RESET 30000
178 
179 
180 /* Refer https://www.teamccp.com/confluence/display/CE/Resets.
181  Use Same Reset Sequence for all devices.
182 */
183 static keyType_t coldFactorySeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
184  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_MENU, KET_KEYUP, 0, 2000}, \
185  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_POWER, KET_KEYUP, 0, 0}, \
186  {KEY_NULL, 0, 0, 0}};
187 
188 static keyType_t factorySeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
189  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_MENU, KET_KEYUP, 0, 2000}, \
190  {KEY_LEFT, KET_KEYUP, 0, 2000}, {KEY_POWER, KET_KEYUP, 0, 0}, \
191  {KEY_NULL, 0, 0, 0}};
192 
193 static keyType_t wareHouseSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
194  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_DOWN, KET_KEYUP, 0, 2000}, \
195  {KEY_POWER, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}};
196 
197 /*customer reset sequence unknown*/
198 static keyType_t customerSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
199  {KED_UNDEFINEDKEY, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}};
200 
201 keyType_t personalityResetSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
202  {KEY_LEFT, KET_KEYUP, 0, 2000}, {KEY_DOWN, KET_KEYUP, 0, 2000}, \
203  {KEY_POWER, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}};
204 
205 /* handling variants */
206 static const keyVariant_t keyVariants[] = {{ KED_POWER, KED_RF_POWER}, {KED_OK, KED_SELECT}};
207 
208 /*Reset Rules Array - which points to the Key sequences for each reset modes */
209 static KeyMap_t Reset_Rules[MAX_RESET_MODE_COUNT] = {{COLD_FACTORY, &coldFactorySeq[0]},{FACTORY, &factorySeq[0]},{WARE_HOUSE, &wareHouseSeq[0]},{CUSTOMER, &customerSeq[0]}, \
210  {PERSONALITY, &personalityResetSeq[0]}};
211 
212 
213 static IARM_Bus_PWRMgr_PowerState_t curPwrState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
214 
215 static void storeFocus()
216 {
217  isXREFocus = true;
218 }
219 
220 static void getSystemTime(long *syst)
221 {
222  struct timespec Stime;
223  clock_gettime(CLOCK_MONOTONIC, &Stime);
224  *syst = ((Stime.tv_sec * 1000) + (Stime.tv_nsec / 1000000)); //gets in milliseconds
225 
226 }
227 
228 static void releaseFocus()
229 {
230  __TIMESTAMP();LOG("Reset: IARM-Release MEDIA Focus for RI Process\n");
231  IARM_BusDaemon_ReleaseOwnership(IARM_BUS_RESOURCE_FOCUS);
232  grabedFocus = false;
233  isXREFocus = false;
234  isRIFocus = false;
235 
236 }
237 
238 static void grabFocus()
239 {
240 
241  __TIMESTAMP();LOG("Reset: IARM-Request MEDIA Focus for Reset Process\n");
242  IARM_BusDaemon_RequestOwnership(IARM_BUS_RESOURCE_FOCUS);
243  return;
244 
245 }
246 static void ResetResetState(void)
247 {
248  int i;
249  for( i = 0; i < MAX_RESET_MODE_COUNT; i++ )
250  {
251  stateMachineList[i]->expectedKeyIndex = 0;
252  }
253 
254  inResetMode = false;
255  gKeyPressedTime = 0;
256  gKeyReleasedTime = 0;
257  gCurrentTime = 0;
258  gTimeOutValue = 0;
259  if (grabedFocus)
260  {
261  releaseFocus();
262  }
263 
264  /*There could be other entities (like ledmgr) monitoring progress of reset sequence.
265  * Let them know that the sequence failed.*/
266  if(gResetMonitoredOnIBus)
267  {
268  IARM_Bus_PWRMgr_EventData_t eventData;
269  eventData.data.reset_sequence_progress = -1;
271  (void *)&eventData, sizeof(eventData));
272  gResetMonitoredOnIBus = false;
273  gLastResetEvent = 0;
274  }
275 }
276 
277 void setResetPowerState(IARM_Bus_PWRMgr_PowerState_t newPwrState)
278 {
279  /* LOG("Reset: Saving current state %d\r\n", newPwrState);*/
280  curPwrState = newPwrState;
281 }
282 
283 void blinkLEDs(void)
284 {
285  /*Blink functionality is not supported in boxes..
286  Simulate blink by setting the LED stae to ON/OFF */
287 
288  __TIMESTAMP();LOG("Reset: Blinking LEDs\n");
289  fflush(stdout);
290 
291  try{
292 
294 
295  for (uint i = 0; i < fpIndicators.size(); i++)
296  {
297  //__TIMESTAMP();LOG("BLINK %s LED : ",fpIndicators.at(i).getName().c_str());
298  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(false);
299  }
300 
301  sleep(1);
302 
303  for (uint i = 0; i < fpIndicators.size(); i++)
304  {
305  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(true);
306  }
307 
308  sleep(1);
309 
310  for (uint i = 0; i < fpIndicators.size(); i++)
311  {
312  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(false);
313  }
314 
315  }
316  catch(device::Exception &e)
317  {
318  __TIMESTAMP();LOG("An exception caught during FP LED Blink Operation: %s",e.getMessage().c_str());
319  }
320  return;
321 }
322 
323 int checkResetModeSequence(int keyType, int keyCode, resetType_t resetMode)
324 {
325  keyType_t *pCurrentState;
326  keyType_t *pNextState;
327  int ret = 0;
328  static timerStruct_t timerVariable;
329 
330  //__TIMESTAMP(); LOG("Reset: Enter checkResetModeSequence");
331 
332  /*Get the current state's expectation for the reset mode */
333  pCurrentState = Reset_Rules[resetMode].pData + stateMachineList[resetMode]->expectedKeyIndex;
334 
335  if ( (true == gWaitState) && (true != gIsSameKey))
336  {
337  /* Received a key during wait state - so reset the timer */
338  gResetTimer = true;
339  /* Signal the thread to unblock */
340  pthread_mutex_lock(&tMutexLock);
341  pthread_cond_signal(&tMutexCond);
342  pthread_mutex_unlock(&tMutexLock);
343 
344  ResetResetState();
345  return 0;
346  }
347 
348  //__TIMESTAMP(); LOG("Reset: checkResetModeSequence %d - %d",pCurrentState->keyMode,pCurrentState->Key);
349  // __TIMESTAMP(); LOG("Reset: checkResetModeSequence passed %d - %d",keyType,keyCode);
350  /* Check Key Code for the specific state machine */
351  if( (pCurrentState->keyMode == keyType) && (pCurrentState->Key == keyCode)/* && (true == gKeyAllowed[resetMode]) */)
352  {
353  if(0 < stateMachineList[resetMode]->expectedKeyIndex)
354  {
355  /*Power and OK keys detected. From here on, all keypresses generate appropriate IARM events*/
356  if(gLastResetEvent != stateMachineList[resetMode]->expectedKeyIndex)
357  {
358  gResetMonitoredOnIBus = true;
359  IARM_Bus_PWRMgr_EventData_t eventData;
360  eventData.data.reset_sequence_progress = stateMachineList[resetMode]->expectedKeyIndex;
362  (void *)&eventData, sizeof(eventData));
363  __TIMESTAMP();LOG("\n Reset: sending IARM event %d \n", stateMachineList[resetMode]->expectedKeyIndex);
364  gLastResetEvent = stateMachineList[resetMode]->expectedKeyIndex;
365  }
366  }
367  /* Set the next expected KeyCode and KeyType for the state machine*/
368  stateMachineList[resetMode]->expectedKeyIndex++;
369  //__TIMESTAMP();LOG("Reset: Set the next expected KeyCode and KeyType %02x",keyCode);
370 
371  /*If the next state is KEY_NULL, we have traversed through the correct key sequence. Can call the
372  appropriate reset function*/
373  pNextState = pCurrentState + 1;
374  if ( KEY_NULL == (pNextState)->Key)
375  {
376  gResetTimer = true;
377  stateMachineList[resetMode]->expectedKeyIndex = 0;
378  __TIMESTAMP();LOG("\n Reset: Action took place for: %d \n",resetMode);
379 
380  fflush(stdout);
381  try {
383  device::FrontPanelConfig::getInstance().getTextDisplay("Text").setText(resetString[resetMode]);
385  }
386  catch(device::Exception &e)
387  {
388  printf("An exception caught while setting fp text : %s",e.getMessage().c_str());
389  }
390 
391  ret = stateMachineList[resetMode]->resetFuction();
392  ResetResetState();
393  }
394 
395  if(0 != pCurrentState->validTime)
396  {
397  /*We need to wait for 2 more seconds to get the
398  next key. If the user fail to provide the key within the expected
399  time period, all the reset statemachines are set to beginning*/
400  gCurrentTime=0;
401  /*Capture the current time to check for that timeout*/
402  getSystemTime(&gCurrentTime);
403  gTimeOutValue = pCurrentState->validTime;
404  __TIMESTAMP();LOG("Reset: gTimeOutValue: %d- %d ",gTimeOutValue,gCurrentTime);
405  }
406 
407 
408  }
409  else
410  {
411  /*Reset statemachine to the initial state*/
412  stateMachineList[resetMode]->expectedKeyIndex = 0;
413  //__TIMESTAMP();LOG("\n Reset: Reset statemachine to the initial state for Reset Mode %d: \n",resetMode);
414 
415  }
416  return 0;
417 }
418 
419 int checkResetSequence(int keyType, int keyCode)
420 {
421  int ret = 0;
422  int i = 0;
423  long tCurTime = 0;
424 
425  //__TIMESTAMP();LOG("Reset: Processing Key %02x",keyCode);
426 
427  /* Check Key Code variant for the specific state machine */
428  for (const keyVariant_t* v = keyVariants; v < keyVariants + sizeof(keyVariants)/sizeof(keyVariant_t); ++v)
429  {
430  if (keyCode == v->Variant)
431  {
432  keyCode = v->Key;
433  //__TIMESTAMP();LOG("Reset: Key %02x variant was redefined as %02x for further processing " ,v->Variant, v->Key);
434  break;
435  }
436  }
437  //__TIMESTAMP();LOG("checkResetSequence : keyCode = %d keyType = %d \n",keyCode,keyType);
438  if (0 != gCurrentTime)
439  {
440  gKeyPressedTime=0;
441  getSystemTime(&gKeyPressedTime);
442  //__TIMESTAMP(); LOG("\n Reset: gKeyPressedTime - 1 %ld - %ld \n", gKeyPressedTime,gCurrentTime);
443  if((gKeyPressedTime - gCurrentTime) > gTimeOutValue)
444  {
445  __TIMESTAMP(); LOG("\n Reset: Sorry you crossed the time out value %d \n", gTimeOutValue);
446  fflush(stdout);
447  ResetResetState();
448  }
449  }
450 
451  switch (keyType)
452  {
453  case KET_KEYDOWN:
454  {
455 
456  //__TIMESTAMP();LOG("Reset : KEY PRESSED keyCode = %d -%d\n",keyCode,KET_KEYDOWN );
457  fflush(stdout);
458  if (!inResetMode && ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER) || (keyCode == KED_FACTORY)))
459  {
460  gKeyPressedTime=0;
461  getSystemTime(&gKeyPressedTime);
462  }
463 
464  }
465  break;
466  case KET_KEYUP:
467  {
468  //__TIMESTAMP();LOG("Reset : KEY RELEASED keyCode = %d -%d\n",keyCode,KET_KEYUP);
469  fflush(stdout);
470  if (!inResetMode && ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER) || (keyCode == KED_FACTORY)))
471  {
472  gKeyReleasedTime=0;
473  getSystemTime(&gKeyReleasedTime);
474  if(gKeyPressedTime == 0)
475  {
476  ResetResetState();//if start time is zero make end also zero. Found a issue with (Downkey event not comes and starttime =0 and endtime >0 TODO
477  }
478  if ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER))
479  {
480 #ifdef ENABLE_FACTORY_RESET_VIA_FP_POWER_BUTTON
481  if((gKeyReleasedTime - gKeyPressedTime) >= POWER_KEY_HOLD_TIME_FOR_FACTORY_RESET)
482  {
483  __TIMESTAMP();LOG("\n Reset: User Factory reset through long-pressing power key\n");
484  fflush(stdout);
485  processUserFactoryReset();
486  ret = 1;
487  return ret;
488  }
489 #else
490  if ((gKeyReleasedTime - gKeyPressedTime) > POWER_KEY_HOLD_TIME_FOR_REBOOT)
491  {
492  __TIMESTAMP();LOG("\n Reset: Inside reset mode 1\n");
493  fflush(stdout);
494  PwrMgr_Reset(curPwrState, true);
495 
496  ret = 1; //mark the return value as triggered for reset.
497  return ret;
498  }
499 #endif
500  else if ((gKeyReleasedTime - gKeyPressedTime) >= POWER_KEY_HOLD_TIME_FOR_RESET)
501  {
502  __TIMESTAMP();LOG("\n Reset: Inside reset mode 2\n");
503  fflush(stdout);
504  ResetResetState();
505  inResetMode = true;
506 
507  gCurrentTime=0;
508  /*Capture the current time to check for that timeout*/
509  getSystemTime(&gCurrentTime);
510  gTimeOutValue = INITIAL_TIME_OUT_VALUE;
511  if (!grabedFocus)
512  {
513  /*storeFocus()*/;
514  grabFocus();
515  grabedFocus = true;
516  }
517  for( i = 0; i < MAX_RESET_MODE_COUNT; i++ )
518  {
519  stateMachineList[i]->expectedKeyIndex++;
520  }
521  __TIMESTAMP();LOG("\n Reset: FP Power key is pressed for 2 secs");
522  fflush(stdout);
523  ret = 1; //mark the return value as triggered for reset.
524  return ret;
525  }
526  else
527  {
528  ResetResetState();
529  }
530  }
531  else
532  {
533  ResetResetState();
534  }
535 
536 
537  }
538  else
539  {
540  if(inResetMode)
541  {
542  __TIMESTAMP();LOG("\n Reset: Already in reset mode \n");
543  fflush(stdout);
544  resetType_t resetMode = COLD_FACTORY;
545  checkResetModeSequence(keyType, keyCode, resetMode);
546  gIsSameKey = true;
547  resetMode = FACTORY;
548  checkResetModeSequence(keyType, keyCode, resetMode);
549 #ifndef _DISABLE_RESET_SEQUENCE
550  resetMode = WARE_HOUSE;
551  checkResetModeSequence(keyType, keyCode, resetMode);
552 #else
553  static bool indicatedDisable = false;
554  if (!indicatedDisable) {
555  indicatedDisable = true;
556  LOG("Reset sequence is disabled for Warehouse reset");
557  }
558 #endif
559  resetMode = CUSTOMER;
560  checkResetModeSequence(keyType, keyCode, resetMode);
561  resetMode = PERSONALITY;
562  checkResetModeSequence(keyType, keyCode, resetMode);
563  gIsSameKey = false;
564  }
565  }
566  }
567  default:
568  /*Ignore Repeat Key type*/
569  break;
570  }
571  if( inResetMode )
572  {
573  if(( 0 == stateMachineList[0]->expectedKeyIndex) && (0 == stateMachineList[1]->expectedKeyIndex) && (0 == stateMachineList[2]->expectedKeyIndex) &&
574  (0 == stateMachineList[3]->expectedKeyIndex) && (0 == stateMachineList[4]->expectedKeyIndex))
575  {
576  __TIMESTAMP();LOG("\n Reset: All statemachines in initial state. So reset the state machines\n");
577  ResetResetState();
578  }
579  }
580  return 0;
581 }
582 
583 IARM_Result_t initReset()
584 {
585  if(!gInitialized)
586  {
587  gInitialized = true;
588  pthread_mutex_init (&tMutexLock, NULL);
589  pthread_cond_init (&tMutexCond, NULL);
590  }
591  return IARM_RESULT_SUCCESS;
592 }
593 /*Uninitialize the reset app from power manager Stop.
594 Currently this interface is not being used*/
595 IARM_Result_t unInitReset()
596 {
597  if(gInitialized)
598  {
599  gInitialized = false;
600  pthread_mutex_unlock(&tMutexLock);
601  pthread_mutex_destroy(&tMutexLock);
602  pthread_cond_destroy(&tMutexCond);
603  }
604  return IARM_RESULT_SUCCESS;
605 }
606 
607 void PwrMgr_Reset(IARM_Bus_PWRMgr_PowerState_t newState, bool isFPKeyPress)
608 {
609  LOG("\n PWR_Reset: Rebooting box now .....\r\n");
610  if (newState == IARM_BUS_PWRMGR_POWERSTATE_ON) system("sh /togglePower");
611 
612  if(!isFPKeyPress)
613  {
614  performReboot("PowerMgr_Powerreset", nullptr, "Rebooting the box due to ECM connectivity Loss...");
615  }
616  else
617  {
618  performReboot("PowerMgr_Powerreset", nullptr, "Rebooting the box due to Frontpanel power key pressed for 10 sec...");
619  }
620 }
621 
622 inline static void check_payload(const char ** input, const char * default_arg)
623 {
624  if((NULL == *input) || (0 == (*input)[0]))
625  {
626  *input = default_arg;
627  }
628  return;
629 }
630 
631 void performReboot(const char * requestor, const char * reboot_reason_custom, const char * reboot_reason_other)
632 {
633  LOG("performReboot: Rebooting box now. Requestor: %s. Reboot reason: %s\n", requestor, reboot_reason_custom);
634  const char * default_arg = "unknown";
635 
636  check_payload(&requestor, default_arg);
637  check_payload(&reboot_reason_custom, default_arg);
638  check_payload(&reboot_reason_other, default_arg);
639 
641  //Note: assumes caller has checked arg reboot_reason_custom and is safe to use.
642  strncpy(eventData.reboot_reason_custom, reboot_reason_custom, sizeof(eventData.reboot_reason_custom));
643  strncpy(eventData.reboot_reason_other, reboot_reason_other, sizeof(eventData.reboot_reason_other));
644  strncpy(eventData.requestor, requestor, sizeof(eventData.requestor));
645  eventData.reboot_reason_custom[sizeof(eventData.reboot_reason_custom) - 1] = '\0';
646  eventData.reboot_reason_other[sizeof(eventData.reboot_reason_other) - 1] = '\0';
647  eventData.requestor[sizeof(eventData.requestor) - 1] = '\0';
648  IARM_Bus_BroadcastEvent( IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_REBOOTING, (void *)&eventData, sizeof(eventData));
649 
650  /*
651  * performReboot() can be called from the context of an RPC, and the sleep() call below can trigger RPC timeouts. So the time-consuming operations
652  * must be handled asynchronously to let this function return promptly. Make a copy of the necessary members so that they can be accessed
653  * safely from the new thread.
654  * Note: not using strndup() here as lengths of the incoming string are already sanitized.
655  */
656  char * requestor_cpy = strdup(requestor);
657  char * reboot_reason_custom_cpy = strdup(reboot_reason_custom);
658  char * reboot_reason_other_cpy = strdup(reboot_reason_other);
659 
660  std::thread async_reboot_thread([requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy] () {
661  v_secure_system("echo 0 > /opt/.rebootFlag");
662  sleep(5);
663  if(0 == access("/rebootNow.sh", F_OK))
664  {
665  v_secure_system("/rebootNow.sh -s '%s' -r '%s' -o '%s'", requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy);
666  }
667  else
668  {
669  v_secure_system("/lib/rdk/rebootNow.sh -s '%s' -r '%s' -o '%s'", requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy);
670  }
671  free(requestor_cpy);
672  free(reboot_reason_custom_cpy);
673  free(reboot_reason_other_cpy);
674  });
675  async_reboot_thread.detach();
676 }
677 
678 /** @} */
679 /** @} */
IARM_BUS_PWRMGR_NAME
#define IARM_BUS_PWRMGR_NAME
Definition: pwrMgr.h:54
_IARM_Bus_PWRMgr_RebootParam_t
Structure to pass reboot reason argument with the reboot call.
Definition: pwrMgr.h:302
timerStruct
Definition: reset.c:94
device::FrontPanelConfig::getTextDisplay
FrontPanelTextDisplay & getTextDisplay(int id)
This function gets the FrontPanelTextDisplay instance corresponding to the specified id,...
Definition: frontPanelConfig.cpp:224
device::FrontPanelConfig::getInstance
static FrontPanelConfig & getInstance()
This API gets the instance of the FrontPanelConfig. When called for the first time,...
Definition: frontPanelConfig.cpp:82
device::List
This class is implemented using templates and it is used to maintain a container with the list of sup...
Definition: list.hpp:51
pwrMgrInternal.h
device::FrontPanelTextDisplay::Scroll
Definition: frontPanelTextDisplay.hpp:74
manager.hpp
It contains class referenced by manager.cpp file.
_PWRMgr_EventData_t
Structure which holds the event data.
Definition: pwrMgr.h:117
IARM_BUS_PWRMGR_EVENT_REBOOTING
@ IARM_BUS_PWRMGR_EVENT_REBOOTING
Definition: pwrMgr.h:63
frontPanelIndicator.hpp
Structures and classes for front panel indicator are defined here.
device::List::size
size_t size()
This function gets the size of the container.
Definition: list.hpp:118
device::FrontPanelTextDisplay::setScroll
void setScroll(const Scroll &scroll)
This API sets the scroll parameters for text LED display like hold duration, vertical iterations and ...
Definition: frontPanelTextDisplay.cpp:299
IARM_Bus_BroadcastEvent
IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len)
This API is used to publish an Asynchronous event to all IARM client registered for this perticular e...
libIBus.h
RDK IARM-Bus API Declarations.
frontPanelConfig.hpp
Structures and classes to manage front panel are defined here.
device::FrontPanelTextDisplay::setText
void setText(const std::string &text)
This API sets the text LED display, by switching the text display to text mode.
Definition: frontPanelTextDisplay.cpp:187
IARM_BUS_PWRMGR_EVENT_RESET_SEQUENCE
@ IARM_BUS_PWRMGR_EVENT_RESET_SEQUENCE
Definition: pwrMgr.h:62
keyVariant
Definition: reset.c:116
device::DSConstant::getName
virtual const std::string & getName() const
This function is used to the get the data member name.
Definition: dsConstant.hpp:141
KeyMap
Definition: reset.c:164
stateMachine
Definition: reset.c:131
device::Exception
This class handles exceptions occurring in DS module.
Definition: exception.hpp:52
pwrMgr.h
IARM-Bus Power Manager Public API.
device::FrontPanelIndicator::getInstance
static FrontPanelIndicator & getInstance(int id)
This function gets the FrontPanelIndicator instance corresponding to the id parameter,...
Definition: frontPanelIndicator.cpp:208
keyType
Definition: reset.c:85
device::Exception::getMessage
virtual const std::string & getMessage() const
This function is used to get the message string of the exception.
Definition: exception.hpp:93
device::FrontPanelConfig::getIndicators
List< FrontPanelIndicator > getIndicators()
This API gets a list of indicators on the front panel.
Definition: frontPanelConfig.cpp:291
device::FrontPanelIndicator::setState
void setState(const bool &enable)
This API is used to enable or disable the front panel indicator.
Definition: frontPanelIndicator.cpp:350