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 
189 static keyType_t factorySeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
190  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_MENU, KET_KEYUP, 0, 2000}, \
191  {KEY_LEFT, KET_KEYUP, 0, 2000}, {KEY_POWER, KET_KEYUP, 0, 0}, \
192  {KEY_NULL, 0, 0, 0}
193 };
194 
195 static keyType_t wareHouseSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
196  {KEY_RIGHT, KET_KEYUP, 0, 2000}, {KEY_DOWN, KET_KEYUP, 0, 2000}, \
197  {KEY_POWER, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}
198 };
199 
200 /*customer reset sequence unknown*/
201 static keyType_t customerSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
202  {KED_UNDEFINEDKEY, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}
203 };
204 
205 keyType_t personalityResetSeq[] = {{KEY_POWER, KET_KEYUP, 0, 0}, {KEY_OK, KET_KEYUP, 0, 2000}, \
206  {KEY_LEFT, KET_KEYUP, 0, 2000}, {KEY_DOWN, KET_KEYUP, 0, 2000}, \
207  {KEY_POWER, KET_KEYUP, 0, 0}, {KEY_NULL, 0, 0, 0}
208 };
209 
210 /* handling variants */
211 static const keyVariant_t keyVariants[] = {{ KED_POWER, KED_RF_POWER}, {KED_OK, KED_SELECT}};
212 
213 /*Reset Rules Array - which points to the Key sequences for each reset modes */
214 static KeyMap_t Reset_Rules[MAX_RESET_MODE_COUNT] = {{COLD_FACTORY, &coldFactorySeq[0]},{FACTORY, &factorySeq[0]},{WARE_HOUSE, &wareHouseSeq[0]},{CUSTOMER, &customerSeq[0]}, \
215  {PERSONALITY, &personalityResetSeq[0]}
216 };
217 
218 
219 static IARM_Bus_PWRMgr_PowerState_t curPwrState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
220 
221 static void storeFocus()
222 {
223  isXREFocus = true;
224 }
225 
226 static void getSystemTime(long *syst)
227 {
228  struct timespec Stime;
229  clock_gettime(CLOCK_MONOTONIC, &Stime);
230  *syst = ((Stime.tv_sec * 1000) + (Stime.tv_nsec / 1000000)); //gets in milliseconds
231 
232 }
233 
234 static void releaseFocus()
235 {
236  __TIMESTAMP();
237  LOG("Reset: IARM-Release MEDIA Focus for RI Process\n");
238  IARM_BusDaemon_ReleaseOwnership(IARM_BUS_RESOURCE_FOCUS);
239  grabedFocus = false;
240  isXREFocus = false;
241  isRIFocus = false;
242 
243 }
244 
245 static void grabFocus()
246 {
247 
248  __TIMESTAMP();
249  LOG("Reset: IARM-Request MEDIA Focus for Reset Process\n");
250  IARM_BusDaemon_RequestOwnership(IARM_BUS_RESOURCE_FOCUS);
251  return;
252 
253 }
254 static void ResetResetState(void)
255 {
256  int i;
257  for( i = 0; i < MAX_RESET_MODE_COUNT; i++ )
258  {
259  stateMachineList[i]->expectedKeyIndex = 0;
260  }
261 
262  inResetMode = false;
263  gKeyPressedTime = 0;
264  gKeyReleasedTime = 0;
265  gCurrentTime = 0;
266  gTimeOutValue = 0;
267  if (grabedFocus)
268  {
269  releaseFocus();
270  }
271 
272  /*There could be other entities (like ledmgr) monitoring progress of reset sequence.
273  * Let them know that the sequence failed.*/
274  if(gResetMonitoredOnIBus)
275  {
276  IARM_Bus_PWRMgr_EventData_t eventData;
277  eventData.data.reset_sequence_progress = -1;
279  (void *)&eventData, sizeof(eventData));
280  gResetMonitoredOnIBus = false;
281  gLastResetEvent = 0;
282  }
283 }
284 
285 void setResetPowerState(IARM_Bus_PWRMgr_PowerState_t newPwrState)
286 {
287  /* LOG("Reset: Saving current state %d\r\n", newPwrState);*/
288  curPwrState = newPwrState;
289 }
290 
291 void blinkLEDs(void)
292 {
293  /*Blink functionality is not supported in boxes..
294  Simulate blink by setting the LED stae to ON/OFF */
295 
296  __TIMESTAMP();
297  LOG("Reset: Blinking LEDs\n");
298  fflush(stdout);
299 
300  try {
301 
303 
304  for (uint i = 0; i < fpIndicators.size(); i++)
305  {
306  //__TIMESTAMP();LOG("BLINK %s LED : ",fpIndicators.at(i).getName().c_str());
307  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(false);
308  }
309 
310  sleep(1);
311 
312  for (uint i = 0; i < fpIndicators.size(); i++)
313  {
314  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(true);
315  }
316 
317  sleep(1);
318 
319  for (uint i = 0; i < fpIndicators.size(); i++)
320  {
321  device::FrontPanelIndicator::getInstance(fpIndicators.at(i).getName()).setState(false);
322  }
323 
324  }
325  catch(device::Exception &e)
326  {
327  __TIMESTAMP();
328  LOG("An exception caught during FP LED Blink Operation: %s",e.getMessage().c_str());
329  }
330  return;
331 }
332 
333 int checkResetModeSequence(int keyType, int keyCode, resetType_t resetMode)
334 {
335  keyType_t *pCurrentState;
336  keyType_t *pNextState;
337  int ret = 0;
338  static timerStruct_t timerVariable;
339 
340  //__TIMESTAMP(); LOG("Reset: Enter checkResetModeSequence");
341 
342  /*Get the current state's expectation for the reset mode */
343  pCurrentState = Reset_Rules[resetMode].pData + stateMachineList[resetMode]->expectedKeyIndex;
344 
345  if ( (true == gWaitState) && (true != gIsSameKey))
346  {
347  /* Received a key during wait state - so reset the timer */
348  gResetTimer = true;
349  /* Signal the thread to unblock */
350  pthread_mutex_lock(&tMutexLock);
351  pthread_cond_signal(&tMutexCond);
352  pthread_mutex_unlock(&tMutexLock);
353 
354  ResetResetState();
355  return 0;
356  }
357 
358  //__TIMESTAMP(); LOG("Reset: checkResetModeSequence %d - %d",pCurrentState->keyMode,pCurrentState->Key);
359  // __TIMESTAMP(); LOG("Reset: checkResetModeSequence passed %d - %d",keyType,keyCode);
360  /* Check Key Code for the specific state machine */
361  if( (pCurrentState->keyMode == keyType) && (pCurrentState->Key == keyCode)/* && (true == gKeyAllowed[resetMode]) */)
362  {
363  if(0 < stateMachineList[resetMode]->expectedKeyIndex)
364  {
365  /*Power and OK keys detected. From here on, all keypresses generate appropriate IARM events*/
366  if(gLastResetEvent != stateMachineList[resetMode]->expectedKeyIndex)
367  {
368  gResetMonitoredOnIBus = true;
369  IARM_Bus_PWRMgr_EventData_t eventData;
370  eventData.data.reset_sequence_progress = stateMachineList[resetMode]->expectedKeyIndex;
372  (void *)&eventData, sizeof(eventData));
373  __TIMESTAMP();
374  LOG("\n Reset: sending IARM event %d \n", stateMachineList[resetMode]->expectedKeyIndex);
375  gLastResetEvent = stateMachineList[resetMode]->expectedKeyIndex;
376  }
377  }
378  /* Set the next expected KeyCode and KeyType for the state machine*/
379  stateMachineList[resetMode]->expectedKeyIndex++;
380  //__TIMESTAMP();LOG("Reset: Set the next expected KeyCode and KeyType %02x",keyCode);
381 
382  /*If the next state is KEY_NULL, we have traversed through the correct key sequence. Can call the
383  appropriate reset function*/
384  pNextState = pCurrentState + 1;
385  if ( KEY_NULL == (pNextState)->Key)
386  {
387  gResetTimer = true;
388  stateMachineList[resetMode]->expectedKeyIndex = 0;
389  __TIMESTAMP();
390  LOG("\n Reset: Action took place for: %d \n",resetMode);
391 
392  fflush(stdout);
393  try {
395  device::FrontPanelConfig::getInstance().getTextDisplay("Text").setText(resetString[resetMode]);
397  }
398  catch(device::Exception &e)
399  {
400  printf("An exception caught while setting fp text : %s",e.getMessage().c_str());
401  }
402 
403  ret = stateMachineList[resetMode]->resetFuction();
404  ResetResetState();
405  }
406 
407  if(0 != pCurrentState->validTime)
408  {
409  /*We need to wait for 2 more seconds to get the
410  next key. If the user fail to provide the key within the expected
411  time period, all the reset statemachines are set to beginning*/
412  gCurrentTime=0;
413  /*Capture the current time to check for that timeout*/
414  getSystemTime(&gCurrentTime);
415  gTimeOutValue = pCurrentState->validTime;
416  __TIMESTAMP();
417  LOG("Reset: gTimeOutValue: %d- %d ",gTimeOutValue,gCurrentTime);
418  }
419 
420 
421  }
422  else
423  {
424  /*Reset statemachine to the initial state*/
425  stateMachineList[resetMode]->expectedKeyIndex = 0;
426  //__TIMESTAMP();LOG("\n Reset: Reset statemachine to the initial state for Reset Mode %d: \n",resetMode);
427 
428  }
429  return 0;
430 }
431 
432 int checkResetSequence(int keyType, int keyCode)
433 {
434  int ret = 0;
435  int i = 0;
436  long tCurTime = 0;
437 
438  //__TIMESTAMP();LOG("Reset: Processing Key %02x",keyCode);
439 
440  /* Check Key Code variant for the specific state machine */
441  for (const keyVariant_t* v = keyVariants; v < keyVariants + sizeof(keyVariants)/sizeof(keyVariant_t); ++v)
442  {
443  if (keyCode == v->Variant)
444  {
445  keyCode = v->Key;
446  //__TIMESTAMP();LOG("Reset: Key %02x variant was redefined as %02x for further processing " ,v->Variant, v->Key);
447  break;
448  }
449  }
450  //__TIMESTAMP();LOG("checkResetSequence : keyCode = %d keyType = %d \n",keyCode,keyType);
451  if (0 != gCurrentTime)
452  {
453  gKeyPressedTime=0;
454  getSystemTime(&gKeyPressedTime);
455  //__TIMESTAMP(); LOG("\n Reset: gKeyPressedTime - 1 %ld - %ld \n", gKeyPressedTime,gCurrentTime);
456  if((gKeyPressedTime - gCurrentTime) > gTimeOutValue)
457  {
458  __TIMESTAMP();
459  LOG("\n Reset: Sorry you crossed the time out value %d \n", gTimeOutValue);
460  fflush(stdout);
461  ResetResetState();
462  }
463  }
464 
465  switch (keyType)
466  {
467  case KET_KEYDOWN:
468  {
469 
470  //__TIMESTAMP();LOG("Reset : KEY PRESSED keyCode = %d -%d\n",keyCode,KET_KEYDOWN );
471  fflush(stdout);
472  if (!inResetMode && ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER) || (keyCode == KED_FACTORY)))
473  {
474  gKeyPressedTime=0;
475  getSystemTime(&gKeyPressedTime);
476  }
477 
478  }
479  break;
480  case KET_KEYUP:
481  {
482  //__TIMESTAMP();LOG("Reset : KEY RELEASED keyCode = %d -%d\n",keyCode,KET_KEYUP);
483  fflush(stdout);
484  if (!inResetMode && ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER) || (keyCode == KED_FACTORY)))
485  {
486  gKeyReleasedTime=0;
487  getSystemTime(&gKeyReleasedTime);
488  if(gKeyPressedTime == 0)
489  {
490  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
491  }
492  if ((keyCode == KED_POWER) || (keyCode == KED_RF_POWER))
493  {
494 #ifdef ENABLE_FACTORY_RESET_VIA_FP_POWER_BUTTON
495  if((gKeyReleasedTime - gKeyPressedTime) >= POWER_KEY_HOLD_TIME_FOR_FACTORY_RESET)
496  {
497  __TIMESTAMP();
498  LOG("\n Reset: Factory reset through long-pressing power key\n");
499  fflush(stdout);
500  processFactoryReset();
501  ret = 1;
502  return ret;
503  }
504 #else
505  if ((gKeyReleasedTime - gKeyPressedTime) > POWER_KEY_HOLD_TIME_FOR_REBOOT)
506  {
507  __TIMESTAMP();
508  LOG("\n Reset: Inside reset mode 1\n");
509  fflush(stdout);
510  PwrMgr_Reset(curPwrState, true);
511 
512  ret = 1; //mark the return value as triggered for reset.
513  return ret;
514  }
515 #endif
516  else if ((gKeyReleasedTime - gKeyPressedTime) >= POWER_KEY_HOLD_TIME_FOR_RESET)
517  {
518  __TIMESTAMP();
519  LOG("\n Reset: Inside reset mode 2\n");
520  fflush(stdout);
521  ResetResetState();
522  inResetMode = true;
523 
524  gCurrentTime=0;
525  /*Capture the current time to check for that timeout*/
526  getSystemTime(&gCurrentTime);
527  gTimeOutValue = INITIAL_TIME_OUT_VALUE;
528  if (!grabedFocus)
529  {
530  /*storeFocus()*/;
531  grabFocus();
532  grabedFocus = true;
533  }
534  for( i = 0; i < MAX_RESET_MODE_COUNT; i++ )
535  {
536  stateMachineList[i]->expectedKeyIndex++;
537  }
538  __TIMESTAMP();
539  LOG("\n Reset: FP Power key is pressed for 2 secs");
540  fflush(stdout);
541  ret = 1; //mark the return value as triggered for reset.
542  return ret;
543  }
544  else
545  {
546  ResetResetState();
547  }
548  }
549  else
550  {
551  ResetResetState();
552  }
553 
554 
555  }
556  else
557  {
558  if(inResetMode)
559  {
560  __TIMESTAMP();
561  LOG("\n Reset: Already in reset mode \n");
562  fflush(stdout);
563  resetType_t resetMode = COLD_FACTORY;
564  checkResetModeSequence(keyType, keyCode, resetMode);
565  gIsSameKey = true;
566  resetMode = FACTORY;
567  checkResetModeSequence(keyType, keyCode, resetMode);
568 #ifndef _DISABLE_RESET_SEQUENCE
569  resetMode = WARE_HOUSE;
570  checkResetModeSequence(keyType, keyCode, resetMode);
571 #else
572  static bool indicatedDisable = false;
573  if (!indicatedDisable) {
574  indicatedDisable = true;
575  LOG("Reset sequence is disabled for Warehouse reset");
576  }
577 #endif
578  resetMode = CUSTOMER;
579  checkResetModeSequence(keyType, keyCode, resetMode);
580  resetMode = PERSONALITY;
581  checkResetModeSequence(keyType, keyCode, resetMode);
582  gIsSameKey = false;
583  }
584  }
585  }
586  default:
587  /*Ignore Repeat Key type*/
588  break;
589  }
590  if( inResetMode )
591  {
592  if(( 0 == stateMachineList[0]->expectedKeyIndex) && (0 == stateMachineList[1]->expectedKeyIndex) && (0 == stateMachineList[2]->expectedKeyIndex) &&
593  (0 == stateMachineList[3]->expectedKeyIndex) && (0 == stateMachineList[4]->expectedKeyIndex))
594  {
595  __TIMESTAMP();
596  LOG("\n Reset: All statemachines in initial state. So reset the state machines\n");
597  ResetResetState();
598  }
599  }
600  return 0;
601 }
602 
603 IARM_Result_t initReset()
604 {
605  if(!gInitialized)
606  {
607  gInitialized = true;
608  pthread_mutex_init (&tMutexLock, NULL);
609  pthread_cond_init (&tMutexCond, NULL);
610  }
611  return IARM_RESULT_SUCCESS;
612 }
613 /*Uninitialize the reset app from power manager Stop.
614 Currently this interface is not being used*/
615 IARM_Result_t unInitReset()
616 {
617  if(gInitialized)
618  {
619  gInitialized = false;
620  pthread_mutex_unlock(&tMutexLock);
621  pthread_mutex_destroy(&tMutexLock);
622  pthread_cond_destroy(&tMutexCond);
623  }
624  return IARM_RESULT_SUCCESS;
625 }
626 
627 void PwrMgr_Reset(IARM_Bus_PWRMgr_PowerState_t newState, bool isFPKeyPress)
628 {
629  LOG("\n PWR_Reset: Rebooting box now .....\r\n");
630  if (newState == IARM_BUS_PWRMGR_POWERSTATE_ON) system("sh /togglePower");
631 
632  if(!isFPKeyPress)
633  {
634  performReboot("PowerMgr_Powerreset", nullptr, "Rebooting the box due to ECM connectivity Loss...");
635  }
636  else
637  {
638  performReboot("PowerMgr_Powerreset", nullptr, "Rebooting the box due to Frontpanel power key pressed for 10 sec...");
639  }
640 }
641 
642 inline static void check_payload(const char ** input, const char * default_arg)
643 {
644  if((NULL == *input) || (0 == (*input)[0]))
645  {
646  *input = default_arg;
647  }
648  return;
649 }
650 
651 void performReboot(const char * requestor, const char * reboot_reason_custom, const char * reboot_reason_other)
652 {
653  LOG("performReboot: Rebooting box now. Requestor: %s. Reboot reason: %s\n", requestor, reboot_reason_custom);
654  const char * default_arg = "unknown";
655 
656  check_payload(&requestor, default_arg);
657  check_payload(&reboot_reason_custom, default_arg);
658  check_payload(&reboot_reason_other, default_arg);
659 
661  //Note: assumes caller has checked arg reboot_reason_custom and is safe to use.
662  strncpy(eventData.reboot_reason_custom, reboot_reason_custom, sizeof(eventData.reboot_reason_custom));
663  strncpy(eventData.reboot_reason_other, reboot_reason_other, sizeof(eventData.reboot_reason_other));
664  strncpy(eventData.requestor, requestor, sizeof(eventData.requestor));
665  eventData.reboot_reason_custom[sizeof(eventData.reboot_reason_custom) - 1] = '\0';
666  eventData.reboot_reason_other[sizeof(eventData.reboot_reason_other) - 1] = '\0';
667  eventData.requestor[sizeof(eventData.requestor) - 1] = '\0';
668  IARM_Bus_BroadcastEvent( IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_EVENT_REBOOTING, (void *)&eventData, sizeof(eventData));
669 
670  /*
671  * performReboot() can be called from the context of an RPC, and the sleep() call below can trigger RPC timeouts. So the time-consuming operations
672  * must be handled asynchronously to let this function return promptly. Make a copy of the necessary members so that they can be accessed
673  * safely from the new thread.
674  * Note: not using strndup() here as lengths of the incoming string are already sanitized.
675  */
676  char * requestor_cpy = strdup(requestor);
677  char * reboot_reason_custom_cpy = strdup(reboot_reason_custom);
678  char * reboot_reason_other_cpy = strdup(reboot_reason_other);
679 
680  std::thread async_reboot_thread([requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy] () {
681  v_secure_system("echo 0 > /opt/.rebootFlag");
682  sleep(5);
683  if(0 == access("/rebootNow.sh", F_OK))
684  {
685  v_secure_system("/rebootNow.sh -s '%s' -r '%s' -o '%s'", requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy);
686  }
687  else
688  {
689  v_secure_system("/lib/rdk/rebootNow.sh -s '%s' -r '%s' -o '%s'", requestor_cpy, reboot_reason_custom_cpy, reboot_reason_other_cpy);
690  }
691  free(requestor_cpy);
692  free(reboot_reason_custom_cpy);
693  free(reboot_reason_other_cpy);
694  });
695  async_reboot_thread.detach();
696 }
697 
698 /** @} */
699 /** @} */
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
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
pwrMgrInternal.h
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