RDK Documentation (Open Sourced RDK Components)
dsMgrPwrEventListener.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 2021 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 
22 /**
23 * @defgroup iarmmgrs
24 * @{
25 * @defgroup dsmgr
26 * @{
27 **/
28 
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <time.h>
37 #include <pthread.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 
41 #include "dsRpc.h"
42 #include "dsMgrPwrEventListener.h"
43 #include "frontPanelIndicator.hpp"
44 #include "videoOutputPort.hpp"
45 #include "host.hpp"
46 #include "exception.hpp"
47 #include "manager.hpp"
48 #include "dsMgrProductTraitsHandler.h"
49 #include "dsAudioSettings.h"
50 
51 #define PWRMGR_REBOOT_REASON_MAINTENANCE "MAINTENANCE_REBOOT"
52 #define MAX_NUM_VIDEO_PORTS 5
53 
54 typedef struct{
55  char port[DSMGR_MAX_VIDEO_PORT_NAME_LENGTH];
56  bool isEnabled;
58 
59 extern IARM_Result_t _dsGetAudioPort(void *arg);
60 extern IARM_Result_t _dsEnableAudioPort(void *arg);
61 extern IARM_Result_t _dsSetFPState(void *arg);
62 extern IARM_Result_t _dsGetEnablePersist(void *arg);
63 extern void _setEASAudioMode();
64 
65 static DSMgr_Standby_Video_State_t g_standby_video_port_setting[MAX_NUM_VIDEO_PORTS];
66 static dsMgrProductTraits::ux_controller * ux = nullptr;
67 static pthread_mutex_t dsLock = PTHREAD_MUTEX_INITIALIZER;
68 
69 static bool get_video_port_standby_setting(const char * port);
70 static void _PwrEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
71 static int _SetLEDStatus(IARM_Bus_PWRMgr_PowerState_t powerState);
72 int _SetAVPortsPowerState(IARM_Bus_PWRMgr_PowerState_t powerState);
73 static IARM_Result_t _SetStandbyVideoState(void *arg);
74 static IARM_Result_t _GetStandbyVideoState(void *arg);
75 static IARM_Result_t _SetAvPortState(void *arg);
76 static IARM_Result_t _SetLEDState(void *arg);
77 static IARM_Result_t _SetRebootConfig(void *arg);
78 
79 static IARM_Bus_PWRMgr_PowerState_t curState;
80 static IARM_Bus_PWRMgr_PowerState_t prevState;
81 
82 #define IARM_BUS_Lock(lock) pthread_mutex_lock(&dsLock)
83 #define IARM_BUS_Unlock(lock) pthread_mutex_unlock(&dsLock)
84 
85 
86 void initPwrEventListner()
87 {
88  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
90 
91 
92 #ifdef POWERMGR_PRODUCT_PROFILE_ID
93  if(true == dsMgrProductTraits::ux_controller::initialize_ux_controller(POWERMGR_PRODUCT_PROFILE_ID))
94  {
95  ux = dsMgrProductTraits::ux_controller::get_instance();
96  }
97 #endif
98  if(nullptr == ux)
99  {
100  INT_DEBUG("dsmgr product traits not supported.\n");
101  }
102 
103  try {
105  }
106  catch (...){
107  INT_DEBUG("Exception Caught during [device::Manager::Initialize]\r\n");
108  }
110  IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_SetStandbyVideoState, _SetStandbyVideoState);
111  IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_GetStandbyVideoState, _GetStandbyVideoState);
112  IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_SetAvPortState, _SetAvPortState);
113  IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_SetLEDStatus, _SetLEDState);
114  IARM_Bus_RegisterCall(IARM_BUS_DSMGR_API_SetRebootConfig, _SetRebootConfig);
115  /* Read the Device Power State on startup... */
116  IARM_Result_t ret = IARM_Bus_Call(IARM_BUS_PWRMGR_NAME, IARM_BUS_PWRMGR_API_GetPowerState, (void *)&param, sizeof(param));
117  if(ret != IARM_RESULT_SUCCESS)
118  {
119  INT_DEBUG("Failed to get power state from pwrmgr Settnig defalt powerstate %d \r\n", IARM_BUS_PWRMGR_POWERSTATE_OFF);
120  prevState = IARM_BUS_PWRMGR_POWERSTATE_OFF;
121  curState = IARM_BUS_PWRMGR_POWERSTATE_STANDBY;
122  }
123  else
124  {
125  INT_DEBUG("Deep Sleep Manager Init with Power State %d\r\n",param.curState);
126  curState = param.curState;
127  prevState = param.prevState;
128  }
129  if(nullptr != ux)
130  ux->applyPostRebootConfig(curState, prevState); // This will set up ports, lights and bootloader pattern internally.
131  else
132  {
133  //Sync Port with Power state TODO:
134  }
135  if(nullptr == ux) // Since ux_controller is not supported, ports need to be set up explicitly.
136  {
137  _SetLEDStatus(curState);
138  _SetAVPortsPowerState(curState);
139  }
140 }
141 
142 
143 static void _PwrEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
144 {
145  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
146  IARM_Bus_PWRMgr_PowerState_t newState;
147  IARM_Bus_PWRMgr_PowerState_t curState;
148 
149  /*Handle only Sys Manager Events */
150  if (strcmp(owner, IARM_BUS_PWRMGR_NAME) == 0)
151  {
152  /* Only handle state events */
153  switch (eventId) {
155  {
156 
158 
159  INT_DEBUG("[%s] Got MODCHANGED Event from %d to %d \r\n",__FUNCTION__, eventData->data.state.curState, eventData->data.state.newState);
160  newState = eventData->data.state.newState;
161  curState = eventData->data.state.curState;
162  if (nullptr != ux) //If ux_controller is supported, it will set up AV ports and LEDs in the below call.
163  ux->applyPowerStateChangeConfig(newState, curState);
164  else
165  {
166  _SetLEDStatus(newState);
167 
168  _SetAVPortsPowerState(newState);
169  }
170  }
171  break;
172  default:
173  break;
174  }
175  }
176 }
177 
178 
179 
180 
181 
182 static int _SetLEDStatus(IARM_Bus_PWRMgr_PowerState_t powerState)
183 {
184  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
185  try {
186 
187  dsFPDStateParam_t param;
188 
189  param.eIndicator = dsFPD_INDICATOR_POWER;
190 
191  if( powerState != IARM_BUS_PWRMGR_POWERSTATE_ON )
192  {
193 #ifdef FP_POWER_LED_ON_IN_LOW_POWER_MODE //For devices like TVs that are expected to have lights on when in one of the standby modes.
194  param.state = dsFPD_STATE_ON;
195  INT_DEBUG("[PWRMgr-_SetLEDStatus] Settings the Power LED State to ON\r\n");
196 #else
197  param.state = dsFPD_STATE_OFF;
198  INT_DEBUG("[PWRMgr-_SetLEDStatus] Settings the Power LED State to OFF \r\n");
199 #endif
200  }
201  else
202  {
203  param.state = dsFPD_STATE_ON;
204  INT_DEBUG("[PWRMgr-_SetLEDStatus] Settings the Power LED State to ON \r\n");
205  }
206 
207  _dsSetFPState(&param);
208  }
209  catch (...) {
210  INT_DEBUG("Exception Caught during [PWRMgr - _SetLEDStatus]\r\n");
211  return 0;
212  }
213  return 0;
214 }
215 
216 int _SetAVPortsPowerState(IARM_Bus_PWRMgr_PowerState_t powerState)
217 {
218  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
219 
220  try
221  {
222  if (powerState != IARM_BUS_PWRMGR_POWERSTATE_ON)
223  {
224  if (IARM_BUS_PWRMGR_POWERSTATE_OFF != powerState)
225  {
226  INT_INFO("[%s] POWERSTATE %d \r\n", __FUNCTION__, powerState);
227  // We're in one of the standby modes. Certain ports may have to be left on.
228  try
229  {
231  for (size_t i = 0; i < videoPorts.size(); i++)
232  {
233  bool doEnable = get_video_port_standby_setting(videoPorts.at(i).getName().c_str());
234  INT_DEBUG("[%s]Video port %s will be %s in standby mode.\n", __FUNCTION__, videoPorts.at(i).getName().c_str(), (doEnable ? "enabled" : "disabled"));
235  if (false == doEnable)
236  videoPorts.at(i).disable();
237  }
238  }
239  catch (...)
240  {
241  INT_DEBUG("[%s] Video port exception %d \r\n", __FUNCTION__, powerState);
242  }
243  INT_INFO("[%s] Video port standby done \r\n",__FUNCTION__);
244  }
245  else
246  {
247  try
248  {
249  // Disable all ports when going into POWERSTATE_OFF
251  for (size_t i = 0; i < videoPorts.size(); i++)
252  {
253  videoPorts.at(i).disable();
254  }
255  }
256  catch (...)
257  {
258  INT_DEBUG("[%s] Video port exception %d \r\n", __FUNCTION__, powerState);
259  }
260  INT_INFO("[%s] Video port disable done \r\n", __FUNCTION__ );
261  }
262  try
263  {
264  dsAudioGetHandleParam_t getHandle;
266  int numPorts, i = 0;
267 
268  numPorts = dsUTL_DIM(kSupportedPortTypes);
269  for (i = 0; i < numPorts; i++)
270  {
271  const dsAudioPortType_t *audioPort = &kSupportedPortTypes[i];
272  memset(&getHandle, 0, sizeof(getHandle));
273  getHandle.type = *audioPort;
274  getHandle.index = 0;
275  _dsGetAudioPort(&getHandle);
276 
277  memset(&setMode, 0, sizeof(setMode));
278  setMode.handle = getHandle.handle;
279  setMode.enabled = false;
280  _dsEnableAudioPort(&setMode);
281  }
282  }
283  catch (...)
284  {
285  INT_DEBUG("[%s] audio port exception \r\n", __FUNCTION__);
286  }
287  }
288  else
289  {
290 
291  try
292  {
294  for (size_t i = 0; i < videoPorts.size(); i++)
295  {
296  videoPorts.at(i).enable();
297  }
298 
299  dsAudioGetHandleParam_t getHandle;
301 
302  int numPorts, i = 0;
303 
304  numPorts = dsUTL_DIM(kSupportedPortTypes);
305  for (i = 0; i < numPorts; i++)
306  {
307  const dsAudioPortType_t *audioPort = &kSupportedPortTypes[i];
308  memset(&getHandle, 0, sizeof(getHandle));
309  getHandle.type = *audioPort;
310  getHandle.index = 0;
311  _dsGetAudioPort(&getHandle);
312 
313  memset(&setMode, 0, sizeof(setMode));
314  setMode.handle = getHandle.handle;
315  setMode.enabled = false;
316  _dsGetEnablePersist(&setMode);
317 
318  if (setMode.enabled == true)
319  {
320  /*Instead of enabling all the audio ports on power transition */
321  /*Get the values from persistent storage & update */
322  INT_INFO("[%s] Enabling audio ports %d \r\n", __FUNCTION__, powerState);
323  _dsEnableAudioPort(&setMode);
324  }
325  }
326  if (isEAS == IARM_BUS_SYS_MODE_EAS)
327  {
328  /* Force Stereo in EAS mode. */
329  INT_INFO("[%s] Force Stereo in EAS mode \r\n", __FUNCTION__);
330  _setEASAudioMode();
331  }
332  }
333  catch (...)
334  {
335  INT_DEBUG("[%s] Audio port exception \r\n",__FUNCTION__);
336  }
337 
338  }
339  }
340  catch (...)
341  {
342  INT_DEBUG("Exception Caught during [%s]\r\n", __FUNCTION__);
343  return 0;
344  }
345  return 0;
346 }
347 
348 static bool get_video_port_standby_setting(const char * port)
349 {
350  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
351  if(NULL == port)
352  {
353  INT_DEBUG("[%s]Error! Port name is NULL!\n", __FUNCTION__);
354  return false;
355  }
356  for(int i = 0; i < MAX_NUM_VIDEO_PORTS; i++)
357  {
358  if(0 == strncasecmp(port, g_standby_video_port_setting[i].port, DSMGR_MAX_VIDEO_PORT_NAME_LENGTH))
359  {
360  return g_standby_video_port_setting[i].isEnabled;
361  }
362  }
363  return false; //Default setting: video port is disabled in standby mode
364 }
365 
366 static IARM_Result_t _SetStandbyVideoState(void *arg)
367 {
368  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
370  if(NULL == param->port)
371  {
372  param->result = -1;
373  INT_DEBUG("[%s] empty port name. Cannot proceed.\n", __FUNCTION__);
374  return IARM_RESULT_SUCCESS;
375  }
376  else
377  param->result = 0;
378 
379  int i = 0;
380  for(i = 0; i < MAX_NUM_VIDEO_PORTS; i++)
381  {
382  if(0 == strncasecmp(param->port, g_standby_video_port_setting[i].port, DSMGR_MAX_VIDEO_PORT_NAME_LENGTH))
383  {
384  /*Found a match. Update it*/
385  g_standby_video_port_setting[i].isEnabled = ((0 == param->isEnabled) ? false : true);
386  break;
387  }
388  }
389  if(MAX_NUM_VIDEO_PORTS == i)
390  {
391  /*No matching entries are present. Add one.*/
392  for(i = 0; i < MAX_NUM_VIDEO_PORTS; i++)
393  {
394  if('\0' == g_standby_video_port_setting[i].port[0])
395  {
396  strncpy(g_standby_video_port_setting[i].port, param->port, (DSMGR_MAX_VIDEO_PORT_NAME_LENGTH - 1));
397  g_standby_video_port_setting[i].isEnabled = ((0 == param->isEnabled) ? false : true);
398  break;
399  }
400  }
401  }
402  if(MAX_NUM_VIDEO_PORTS == i)
403  {
404  INT_DEBUG("[%s] Error! Out of room to write new video port setting for standby mode.\n", __FUNCTION__);
405  }
406 
407  try
408  {
410  if((IARM_BUS_PWRMGR_POWERSTATE_ON != curState) && (IARM_BUS_PWRMGR_POWERSTATE_OFF != curState))
411  {
412  /*We're currently in one of the standby states. This new setting needs to be applied right away.*/
413  INT_DEBUG("[%s] Setting standby %s port status to %s.\n", __FUNCTION__, param->port, ((1 == param->isEnabled)? "enabled" : "disabled"));
414  if(1 == param->isEnabled)
415  vPort.enable();
416  else
417  vPort.disable();
418  }
419  else
420  {
421  INT_DEBUG("[%s] video port %s will be %s when going into standby mode.\n", __FUNCTION__, param->port, ((1 == param->isEnabled)? "enabled" : "disabled"));
422  }
423  }
424  catch (...)
425  {
426  INT_DEBUG("Exception Caught during [%s]. Possible bad video port.\n", __FUNCTION__);
427  param->result = -1;
428  }
429  return IARM_RESULT_SUCCESS;
430 }
431 
432 static IARM_Result_t _GetStandbyVideoState(void *arg)
433 {
434  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
436  if(NULL == param->port)
437  {
438  INT_DEBUG("[%s]Bad port name. Cannot get state.\n", __FUNCTION__);
439  return IARM_RESULT_SUCCESS;
440  }
441 
442  try
443  {
445 
446  }
447  catch (...)
448  {
449  INT_DEBUG("Exception Caught during [%s]. Possible bad video port.\n", __FUNCTION__);
450  param->result = -1;
451  return IARM_RESULT_SUCCESS;
452  }
453  param->isEnabled = ((true == get_video_port_standby_setting(param->port))? 1 : 0);
454  param->result = 0;
455  return IARM_RESULT_SUCCESS;
456 }
457 
458 static IARM_Result_t _SetAvPortState(void *arg)
459 {
460  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
462  if(NULL == param)
463  {
464  INT_DEBUG("Bad Parameter.\n");
465  return IARM_RESULT_SUCCESS;
466  }
467 
468  _SetAVPortsPowerState((IARM_Bus_PWRMgr_PowerState_t)param->avPortPowerState);
469  param->result = 0;
470  return IARM_RESULT_SUCCESS;
471 }
472 
473 static IARM_Result_t _SetLEDState(void *arg)
474 {
475  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
477  if(NULL == param)
478  {
479  INT_DEBUG("[%s] Bad Parameter.\n", __FUNCTION__);
480  return IARM_RESULT_SUCCESS;
481  }
482 
483  _SetLEDStatus((IARM_Bus_PWRMgr_PowerState_t)param->ledState);
484  param->result = 0;
485  return IARM_RESULT_SUCCESS;
486 }
487 
488 static IARM_Result_t _SetRebootConfig(void *arg)
489 {
490  INT_INFO("Entering [%s]\r\n", __FUNCTION__);
492  if(NULL == param)
493  {
494  INT_DEBUG("[%s]Bad Parameter.\n", __FUNCTION__);
495  return IARM_RESULT_SUCCESS;
496  }
497  param->reboot_reason_custom[sizeof(param->reboot_reason_custom) - 1] = '\0'; //Just to be on the safe side.
498  if(nullptr != ux)
499  {
500  if(0 == strncmp(PWRMGR_REBOOT_REASON_MAINTENANCE, param->reboot_reason_custom, sizeof(param->reboot_reason_custom)))
501  ux->applyPreMaintenanceRebootConfig((IARM_Bus_PWRMgr_PowerState_t)param->powerState);
502  else
503  ux->applyPreRebootConfig((IARM_Bus_PWRMgr_PowerState_t)param->powerState);
504  }
505 
506  param->result = 0;
507  return IARM_RESULT_SUCCESS;
508 }
IARM_BUS_PWRMGR_NAME
#define IARM_BUS_PWRMGR_NAME
Definition: pwrMgr.h:54
device::VideoOutputPort::getName
const std::string & getName() const
This API gets the name of the VideoOutputPort. The VideoOutputPort names can be HDMI,...
Definition: videoOutputPort.hpp:225
_dsMgrStandbyVideoStateParam_t
Definition: dsRpc.h:280
_IARM_Bus_PWRMgr_GetPowerState_Param_t
Structure which holds the current power state of the CPE.
Definition: pwrMgr.h:173
dsAudioPortType_t
enum _dsAudioPortType_t dsAudioPortType_t
device::Host::getVideoOutputPorts
List< VideoOutputPort > getVideoOutputPorts()
This API is used to get the list of the video output ports supported on the device....
Definition: host.cpp:285
dsMgrPwrEventListener.h
_dsMgrAVPortStateParam_t
Definition: dsRpc.h:292
IARM_Bus_Call
IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen)
This API is used to Invoke RPC method by its application name and method name.
Definition: iarm_bus.c:57
device::VideoOutputPort
Class extending enumerable to implement the videoooutputport interface.
Definition: videoOutputPort.hpp:59
manager.hpp
It contains class referenced by manager.cpp file.
_PWRMgr_EventData_t
Structure which holds the event data.
Definition: pwrMgr.h:117
_dsMgrLEDStatusParam_t
Definition: dsRpc.h:297
IARM_BUS_PWRMGR_API_GetPowerState
#define IARM_BUS_PWRMGR_API_GetPowerState
Definition: pwrMgr.h:168
frontPanelIndicator.hpp
Structures and classes for front panel indicator are defined here.
IARM_Bus_RegisterEventHandler
IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler)
This API register to listen to event and provide the callback function for event notification....
Definition: iarmMgrMocks.cpp:43
dsFPD_STATE_ON
@ dsFPD_STATE_ON
Definition: dsTypes.h:821
IARM_Bus_RegisterCall
IARM_Result_t IARM_Bus_RegisterCall(const char *methodName, IARM_BusCall_t handler)
This API is used to register an RPC method that can be invoked by other applications.
_dsVideoPortEnabledParam_t
Definition: dsRpc.h:509
device::List::size
size_t size()
This function gets the size of the container.
Definition: list.hpp:118
_dsAudioGetHandleParam_t
Definition: dsRpc.h:302
DSMgr_Standby_Video_State_t
Definition: dsMgrPwrEventListener.c:54
device::Manager::Initialize
static void Initialize()
This API is used to initialize the Device Setting module. Each API should be called by any client of ...
Definition: manager.cpp:97
dsMgrProductTraits::ux_controller
Definition: dsMgrProductTraitsHandler.h:72
_dsFPDStateParam
Definition: dsRpc.h:662
_dsMgrRebootConfigParam_t
Definition: dsRpc.h:286
IARM_BUS_PWRMGR_EVENT_MODECHANGED
@ IARM_BUS_PWRMGR_EVENT_MODECHANGED
Definition: pwrMgr.h:60
videoOutputPort.hpp
It contains class and structure refrenced by the videooutputport.cpp file.
device::Host::getVideoOutputPort
VideoOutputPort & getVideoOutputPort(const std::string &name)
This API is used to get the reference to the video output port by its name. The name of the port must...
Definition: host.cpp:350
device::Host::getInstance
static Host & getInstance(void)
This API is used to get a reference to the single instance of the Host object.
Definition: host.cpp:88
device::VideoOutputPort::enable
void enable()
This API is used to enable the video output port.
Definition: videoOutputPort.cpp:552
device::List< device::VideoOutputPort >
dsUTL_DIM
#define dsUTL_DIM(arr)
Device Settings general Array dimension calculation inline definition.
Definition: dsUtl.h:85
device::VideoOutputPort::disable
void disable()
This API is used to disable the Audio output port.
Definition: videoOutputPort.cpp:567
dsFPD_INDICATOR_POWER
#define dsFPD_INDICATOR_POWER
Definition: dsTypes.h:790
dsFPD_STATE_OFF
@ dsFPD_STATE_OFF
Definition: dsTypes.h:820