RDK Documentation (Open Sourced RDK Components)
therm_mgr.c
1 
2 /*
3  * If not stated otherwise in this file or this component's Licenses.txt file the
4  * following copyright and licenses apply:
5  *
6  * Copyright 2016 RDK Management
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19 */
20 
21 
22 
23 /**
24 * @defgroup iarmmgrs
25 * @{
26 * @defgroup power
27 * @{
28 **/
29 #ifdef __cplusplus
30 extern "C"
31 {
32 #endif
33 
34 #ifdef ENABLE_THERMAL_PROTECTION
35 #include <sys/stat.h>
36 #include <sys/time.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <glib.h>
40 #include <unistd.h>
41 #include "pwrMgr.h"
42 #include "mfr_temperature.h"
43 #include "plat_power.h"
44 #include "pwrlogger.h"
45 #include "libIBus.h"
46 #include "rfcapi.h"
47 
48 #define STANDBY_REASON_FILE "/opt/standbyReason.txt"
49 #define THERMAL_PROTECTION_GROUP "Thermal_Config"
50 #define THERMAL_SHUTDOWN_REASON "THERMAL_SHUTDOWN"
51 
52 #define RFC_ENABLE_ThermalProtection
53 #define RFC_DATA_ThermalProtection_POLL_INTERVAL
54 
55 #define RFC_DATA_ThermalProtection_REBOOT_CRITICAL_THRESHOLD
56 #define RFC_DATA_ThermalProtection_REBOOT_CONCERN_THRESHOLD
57 #define RFC_DATA_ThermalProtection_REBOOT_GRACE_INTERVAL
58 #define RFC_DATA_ThermalProtection_REBOOT_SAFE_THRESHOLD
59 
60 #define RFC_DATA_ThermalProtection_DEEPSLEEP_CRITICAL_THRESHOLD
61 #define RFC_DATA_ThermalProtection_DEEPSLEEP_CONCERN_THRESHOLD
62 #define RFC_DATA_ThermalProtection_DEEPSLEEP_GRACE_INTERVAL
63 #define RFC_DATA_ThermalProtection_DEEPSLEEP_SAFE_THRESHOLD
64 
65 #define RFC_DATA_ThermalProtection_DECLOCK_CRITICAL_THRESHOLD
66 #define RFC_DATA_ThermalProtection_DECLOCK_CONCERN_THRESHOLD
67 #define RFC_DATA_ThermalProtection_DECLOCK_GRACE_INTERVAL
68 #define RFC_DATA_ThermalProtection_DECLOCK_SAFE_THRESHOLD
69 
70 
71 /* Temperature (in celcus) at which box will ALWAYS be rebooted */
72 static int thermal_reboot_critical_threshold = 120;
73 /* Temperature (in celcus) at which box will be rebooted after grace_interval has passed
74  Timer is started 2 minutes late to give deepsleep logic a chance to work */
75 static int thermal_reboot_concern_threshold = 112;
76 /* Temperature (in celcus) at which box is considered safe and will stop reboot consideration */
77 static int thermal_reboot_safe_threshold = 110;
78 /* The amount of time (in seconds) that must pass after the temperature has reached 'thermal_reboot_concern_threshold'
79  and has not fallen below 'thermal_reboot_safe_threshold' before the box will reboot
80 
81  ***NOTE: All temperature based reboot logic will be disabled if 'thermal_reboot_grace_interval' is set to 0 *** */
82 static int thermal_reboot_grace_interval = 600;
83 
84 
85 /* Temperature (in celcus) at which box will ALWAYS go to deep sleep */
86 static int thermal_deepsleep_critical_threshold = 115;
87 /* Temperature (in celcus) at which box will go to deep sleep after grace_interval has passed */
88 static int thermal_deepsleep_concern_threshold = 110;
89 /* Temperature (in celcus) at which box is considered safe and will stop deep sleep consideration */
90 static int thermal_deepsleep_safe_threshold = 100;
91 /* The amount of time (in seconds) that must pass after the temperature has reached 'thermal_deepsleep_concern_threshold'
92  and has not fallen below 'thermal_deepsleep_safe_threshold' before the box will go to deepsleep
93 
94  ***NOTE: All temperature based deep sleep logic will be disabled if 'thermal_deepsleep_grace_interval' is set to 0 *** */
95 static int thermal_deepsleep_grace_interval = 600;
96 
97 
98 /* Temperature (in celcus) at which box will ALWAYS be switched to the LOWEST clock mode */
99 static int thermal_declock_critical_threshold = 110;
100 /* Temperature (in celcus) at which box will ALWAYS be switched to the middle clock mode */
101 static int thermal_declock_concern_threshold = 100;
102 /* Temperature (in celcus) at which box will be switched back to highest clock mode after 'thermal_declock_grace_interval' has passed */
103 static int thermal_declock_safe_threshold = 90;
104 /* The amount of time (in seconds) that must pass after to switch from a lower clock mode to a higher clock mode
105 
106  ***NOTE: All temperature based declock logic will be disabled if 'thermal_declock_grace_interval' is set to 0 *** */
107 static int thermal_declock_grace_interval = 60;
108 
109 
110 // the interval at which temperature will be polled from lower layers
111 static int thermal_poll_interval = 30; //in seconds
112 // the interval after which reboot will happen if the temperature goes above reboot threshold
113 
114 //Did we already read config params once ?
115 static bool read_config_param = FALSE;
116 
117 // Is feature enabled ?
118 static bool isFeatureEnabled = TRUE;
119 //Current temperature level
120 static volatile IARM_Bus_PWRMgr_ThermalState_t cur_Thermal_Level = IARM_BUS_PWRMGR_TEMPERATURE_NORMAL;
121 ///Current temperature reading in celcius
122 static volatile int cur_Thermal_Value =0;
123 //Current CPU clocking mode.
124 static uint32_t cur_Cpu_Speed = 0;
125 
126 // These are the clock rates that will actually be used when declocking. 0 is uninitialized and we'll attempt to auto discover
127 static uint32_t PLAT_CPU_SPEED_NORMAL = 0;
128 static uint32_t PLAT_CPU_SPEED_SCALED = 0;
129 static uint32_t PLAT_CPU_SPEED_MINIMAL = 0;
130 
131 // Thread id of polling thread
132 static pthread_t thermalThreadId = NULL;
133 
134 // RFC parameter storage
135 #define MAX_THERMAL_RFC 16
136 static char valueBuf[MAX_THERMAL_RFC];
137 
138 //Functions used
139 /**
140 * Entry function for thread that monitor temperature change
141 */
142 static void *_PollThermalLevels(void *);
143 /**
144 * Read configuration values, strat the thread
145 */
146 void initializeThermalProtection();
147 /**
148 * IARM call to return current thermal state
149 */
150 static IARM_Result_t _GetThermalState(void *arg);
151 /**
152 * IARM call to set temperature thresholds
153 */
154 static IARM_Result_t _SetTemperatureThresholds(void *arg);
155 /**
156 * IARM call to get temperature thresholds
157 */
158 static IARM_Result_t _GetTemperatureThresholds(void *arg);
159 /**
160 * IARM call to set the grace interval
161 */
162 static IARM_Result_t _SetOvertempGraceInterval(void *arg);
163 /**
164 * IARM call to get the grace interval
165 */
166 static IARM_Result_t _GetOvertempGraceInterval(void *arg);
167 /**
168 * This function reads configuration details from relevant configuration files.
169 */
170 static bool read_ConfigProps();
171 /**
172 * Check whether RFC based control is present, if yes create a glib style config file
173 */
174 static bool updateRFCStatus();
175 /**
176 * @brief Is Thermal protection feature enabled
177 *
178 * @return TRUE f enabled, FALSE otherise
179 */
180 
181 static bool isThermalProtectionEnabled()
182 {
183  if (!read_config_param)
184  {
185  if (updateRFCStatus())
186  {
187  read_ConfigProps();
188  }
189 
190  read_config_param= TRUE;
191  }
192 
193  return isFeatureEnabled;
194 }
195 
196 void initializeThermalProtection()
197 {
198  if (isThermalProtectionEnabled())
199  {
200  IARM_Bus_RegisterCall(IARM_BUS_PWRMGR_API_GetThermalState, _GetThermalState);
201  IARM_Bus_RegisterCall(IARM_BUS_PWRMGR_API_SetTemperatureThresholds, _SetTemperatureThresholds);
202  IARM_Bus_RegisterCall(IARM_BUS_PWRMGR_API_GetTemperatureThresholds, _GetTemperatureThresholds);
203  IARM_Bus_RegisterCall(IARM_BUS_PWRMGR_API_SetOvertempGraceInterval, _SetOvertempGraceInterval);
204  IARM_Bus_RegisterCall(IARM_BUS_PWRMGR_API_GetOvertempGraceInterval, _GetOvertempGraceInterval);
205 
206  LOG("[%s] Thermal Monitor [REBOOT] Enabled: %s\n", __FUNCTION__, (thermal_reboot_grace_interval > 0) ? "TRUE" : "FALSE");
207  if (thermal_reboot_grace_interval > 0) {
208  LOG("[%s] Thermal Monitor [REBOOT] Thresholds -- Critical:%d Concern:%d Safe:%d Grace Interval:%d\n", __FUNCTION__,
209  thermal_reboot_critical_threshold, thermal_reboot_concern_threshold, thermal_reboot_safe_threshold, thermal_reboot_grace_interval);
210  }
211 
212  LOG("[%s] Thermal Monitor [DEEP SLEEP] Enabled: %s\n", __FUNCTION__, (thermal_deepsleep_grace_interval > 0) ? "TRUE" : "FALSE");
213  if (thermal_deepsleep_grace_interval > 0) {
214  LOG("[%s] Thermal Monitor [DEEP SLEEP] Thresholds -- Critical:%d Concern:%d Safe:%d Grace Interval:%d\n", __FUNCTION__,
215  thermal_deepsleep_critical_threshold, thermal_deepsleep_concern_threshold, thermal_deepsleep_safe_threshold, thermal_deepsleep_grace_interval);
216  }
217 
218 #ifndef DISABLE_DECLOCKING_LOGIC
219  LOG("[%s] Thermal Monitor [DECLOCK] Enabled: %s\n", __FUNCTION__, (thermal_declock_grace_interval > 0) ? "TRUE" : "FALSE");
220  if (thermal_declock_grace_interval > 0) {
221  LOG("[%s] Thermal Monitor [DECLOCK] Thresholds -- Critical:%d Concern:%d Safe:%d Grace Interval:%d\n", __FUNCTION__,
222  thermal_declock_critical_threshold, thermal_declock_concern_threshold, thermal_declock_safe_threshold, thermal_declock_grace_interval);
223  PLAT_API_GetClockSpeed(&cur_Cpu_Speed);
224  LOG("[%s] Thermal Monitor [DECLOCK] Default Frequency %d\n", __FUNCTION__, cur_Cpu_Speed);
225  /* Discover clock rate for this system. Only discover if the rate is 0 */
226  PLAT_API_DetemineClockSpeeds(
227  (PLAT_CPU_SPEED_NORMAL == 0 ) ? &PLAT_CPU_SPEED_NORMAL : NULL,
228  (PLAT_CPU_SPEED_SCALED == 0 ) ? &PLAT_CPU_SPEED_SCALED : NULL,
229  (PLAT_CPU_SPEED_MINIMAL == 0 ) ? &PLAT_CPU_SPEED_MINIMAL : NULL);
230  LOG("[%s] Thermal Monitor [DECLOCK] Frequencies -- Normal:%d Scaled:%d Minimal:%d\n", __FUNCTION__, PLAT_CPU_SPEED_NORMAL, PLAT_CPU_SPEED_SCALED, PLAT_CPU_SPEED_MINIMAL);
231  if (PLAT_CPU_SPEED_NORMAL == 0 || PLAT_CPU_SPEED_SCALED == 0 || PLAT_CPU_SPEED_MINIMAL == 0) {
232  LOG("[%s] Thermal Monitor [DECLOCK] **ERROR** At least one clock speed is 0. Disabling declocking!\n", __FUNCTION__);
233  thermal_declock_grace_interval = 0;
234  }
235  }
236 #endif
237 
238  if(!PLAT_API_SetTempThresholds(thermal_declock_concern_threshold, thermal_declock_critical_threshold))
239  {
240  LOG("*****Critical*** Fails to set temperature thresholds.. \n");
241  }
242 
243  if (pthread_create(&thermalThreadId, NULL, _PollThermalLevels, NULL))
244  {
245  LOG("*****Critical*** Fails to Create temperature monitor thread \n");
246  }
247  }
248  else
249  {
250  LOG("[%s] Thermal protection is disabled from RFC \n",__FUNCTION__);
251  }
252 }
253 
254 static void logThermalShutdownReason()
255 {
256  //command is echo THERMAL_SHUTDOWN_REASON > STANDBY_REASON_FILE
257  int cmdSize = strlen(THERMAL_SHUTDOWN_REASON) + strlen(STANDBY_REASON_FILE) + 10;
258  char logCommand[cmdSize]= {'0'};
259  snprintf(logCommand,cmdSize,"echo %s > %s",THERMAL_SHUTDOWN_REASON, STANDBY_REASON_FILE);
260  system(logCommand);
261 }
262 
263 static void rebootIfNeeded()
264 {
265  struct timeval tv;
266  long difftime = 0;
267  static struct timeval monitorTime;
268  static bool rebootZone = false;
269 
270  if (thermal_reboot_grace_interval == 0) {
271  /* This check is disable */
272  return;
273  }
274 
275  if (cur_Thermal_Value >= thermal_reboot_critical_threshold)
276  {
277  LOG("[%s] Rebooting is being forced!\n", __FUNCTION__);
278  system("/rebootNow.sh -s Power_Thermmgr -o 'Rebooting the box due to stb temperature greater than thermal_reboot_critical_threshold...'");
279  }
280  else if (!rebootZone && cur_Thermal_Value >= thermal_reboot_concern_threshold)
281  {
282  LOG("[%s] Temperature threshold crossed (%d) ENTERING reboot zone\n", __FUNCTION__, cur_Thermal_Value );
283  gettimeofday(&monitorTime, NULL);
284  rebootZone = true;
285  }
286  else if (rebootZone && cur_Thermal_Value < thermal_reboot_safe_threshold) {
287  LOG("[%s] Temperature threshold crossed (%d) EXITING reboot zone\n", __FUNCTION__, cur_Thermal_Value );
288  rebootZone = false;
289  }
290 
291  if (rebootZone) {
292  /* We are in the deep sleep zone. After 'thermal_reboot_grace_interval' passes we will go to deep sleep */
293  gettimeofday(&tv, NULL);
294  difftime = tv.tv_sec - monitorTime.tv_sec;
295 
296  if (difftime >= thermal_reboot_grace_interval)
297  {
298  LOG("[%s] - Rebooting since the temperature is still above critical level after %d seconds !! : \n",
299  __FUNCTION__,thermal_reboot_grace_interval);
300  system("/rebootNow.sh -s Power_Thermmgr -o 'Rebooting the box as the stb temperature is still above critical level after 20 seconds...'");
301  }
302  else {
303  LOG("[%s] Still in the reboot zone! Will go for reboot in %u seconds unless the temperature falls below %u!\n", __FUNCTION__, thermal_reboot_grace_interval-difftime, thermal_reboot_safe_threshold );
304  }
305  }
306 }
307 
308 
309 static void deepSleepIfNeeded()
310 {
311  struct timeval tv;
312  long difftime = 0;
313  static struct timeval monitorTime;
314  static bool deepSleepZone = false;
315 
316  if (thermal_deepsleep_grace_interval == 0) {
317  /* This check is disable */
318  return;
319  }
320 
321  if (cur_Thermal_Value >= thermal_deepsleep_critical_threshold)
322  {
323  logThermalShutdownReason();
324  LOG("[%s] Going to deepsleep since the temperature is above %d\n", __FUNCTION__, thermal_deepsleep_critical_threshold);
325  system("/lib/rdk/alertSystem.sh pwrMgrMain \"Going to deepsleep due to temperature runaway\"");
326  system("/SetPowerState DEEPSLEEP");
327  }
328  else if (!deepSleepZone && cur_Thermal_Value >= thermal_deepsleep_concern_threshold)
329  {
330  LOG("[%s] Temperature threshold crossed (%d) ENTERING deepsleep zone\n", __FUNCTION__, cur_Thermal_Value );
331  gettimeofday(&monitorTime, NULL);
332  deepSleepZone = true;
333  }
334  else if (deepSleepZone && cur_Thermal_Value < thermal_deepsleep_safe_threshold) {
335  LOG("[%s] Temperature threshold crossed (%d) EXITING deepsleep zone\n", __FUNCTION__, cur_Thermal_Value );
336  deepSleepZone = false;
337  }
338 
339  if (deepSleepZone) {
340  /* We are in the deep sleep zone. After 'thermal_deepsleep_grace_interval' passes we will go to deep sleep */
341  gettimeofday(&tv, NULL);
342  difftime = tv.tv_sec - monitorTime.tv_sec;
343 
344  if (difftime >= thermal_deepsleep_grace_interval)
345  {
346  logThermalShutdownReason();
347  LOG("[%s] Going to deepsleep since the temperature reached %d and stayed above %d for %d seconds\n",
348  __FUNCTION__, thermal_deepsleep_concern_threshold, thermal_deepsleep_safe_threshold, thermal_deepsleep_grace_interval);
349  system("/lib/rdk/alertSystem.sh pwrMgrMain \"Going to deepsleep due to over temperature\"");
350  system("/SetPowerState DEEPSLEEP");
351  }
352  else {
353  LOG("[%s] Still in the deep sleep zone! Entering deep sleep in %u seconds unless the temperature falls below %u!\n", __FUNCTION__, thermal_deepsleep_grace_interval-difftime, thermal_deepsleep_safe_threshold );
354  }
355  }
356 }
357 
358 
359 static void declockIfNeeded()
360 {
361 #ifndef DISABLE_DECLOCKING_LOGIC
362  struct timeval tv;
363  long difftime = 0;
364  static struct timeval monitorTime;
365 
366  if (thermal_declock_grace_interval == 0) {
367  /* This check is disable */
368  return;
369  }
370 
371  if (cur_Thermal_Value >= thermal_declock_critical_threshold)
372  {
373  if (cur_Cpu_Speed != PLAT_CPU_SPEED_MINIMAL) {
374  LOG("[%s] - Temperature threshold crossed (%d) !!!! Switching to minimal mode !!\n",
375  __FUNCTION__, cur_Thermal_Value);
376  PLAT_API_SetClockSpeed(PLAT_CPU_SPEED_MINIMAL);
377  cur_Cpu_Speed = PLAT_CPU_SPEED_MINIMAL;
378  }
379  /* Always reset the monitor time */
380  gettimeofday(&monitorTime, NULL);
381  }
382  else if (cur_Thermal_Value >= thermal_declock_concern_threshold)
383  {
384  if (cur_Cpu_Speed == PLAT_CPU_SPEED_NORMAL) {
385  /* Switching from normal to scaled */
386  LOG("[%s] - CPU Scaling threshold crossed (%d) !!!! Switching to scaled mode (%d) from normal mode(%d) !!\n",
387  __FUNCTION__,cur_Thermal_Value,PLAT_CPU_SPEED_SCALED,PLAT_CPU_SPEED_NORMAL );
388  PLAT_API_SetClockSpeed(PLAT_CPU_SPEED_SCALED);
389  cur_Cpu_Speed = PLAT_CPU_SPEED_SCALED;
390  }
391  gettimeofday(&monitorTime, NULL);
392  }
393  else if (cur_Thermal_Value > thermal_declock_safe_threshold)
394  //Between thermal_declock_concern_threshold and thermal_declock_safe_threshold
395  {
396  if (cur_Cpu_Speed == PLAT_CPU_SPEED_MINIMAL) {
397  /* We are already declocked. If we stay in this state for 'thermal_declock_grace_interval' we will change to */
398  gettimeofday(&tv, NULL);
399  difftime = tv.tv_sec - monitorTime.tv_sec;
400 
401  if (difftime >= thermal_declock_grace_interval)
402  {
403  LOG("[%s] - CPU Scaling threshold crossed (%d) !!!! Switching to scaled mode (%d) from minimal mode(%d) !!\n",
404  __FUNCTION__,cur_Thermal_Value,PLAT_CPU_SPEED_SCALED,PLAT_CPU_SPEED_MINIMAL );
405  PLAT_API_SetClockSpeed(PLAT_CPU_SPEED_SCALED);
406  cur_Cpu_Speed = PLAT_CPU_SPEED_SCALED;
407  gettimeofday(&monitorTime, NULL);
408  }
409  }
410  else {
411  /*Still in the correct mode. Always reset the monitor time */
412  gettimeofday(&monitorTime, NULL);
413  }
414  }
415  else //cur_Thermal_Value <= thermal_declock_safe_threshold
416  {
417  if (cur_Cpu_Speed != PLAT_CPU_SPEED_NORMAL) {
418  /* We are in the declock zone. After 'thermal_declock_grace_interval' passes we will go back to normal mode */
419  gettimeofday(&tv, NULL);
420  difftime = tv.tv_sec - monitorTime.tv_sec;
421 
422  if (difftime >= thermal_declock_grace_interval)
423  {
424  LOG("[%s] - CPU rescaling threshold crossed (%d) !!!! Switching to normal mode !!\n",
425  __FUNCTION__,cur_Thermal_Value );
426  PLAT_API_SetClockSpeed(PLAT_CPU_SPEED_NORMAL);
427  cur_Cpu_Speed = PLAT_CPU_SPEED_NORMAL;
428  }
429  }
430 
431  }
432 #endif
433 
434 }
435 
436 //Thread entry function to monitor thermal levels of the device.
437 static void *_PollThermalLevels(void *)
438 {
440  float current_Temp = 0;
441  float current_WifiTemp = 0;
442 
443  unsigned int pollCount = 0;
444  int thermalLogInterval = 300/thermal_poll_interval;
445 
446  //PACEXI5-2127 //print current temperature levels every 15 mins
447  int fifteenMinInterval = 900/thermal_poll_interval; //15 *60 seconds/interval
448 
449 
450  LOG("Entering [%s] - [%s] - Start monitoring temeperature every %d seconds log interval: %d\n",
451  __FUNCTION__, IARM_BUS_PWRMGR_NAME, thermal_poll_interval, thermalLogInterval);
452 
453  while(TRUE)
454  {
455  int result = PLAT_API_GetTemperature(&state, &current_Temp, &current_WifiTemp);//cur_Thermal_Level
456  if(result)
457  {
458  if(cur_Thermal_Level != state)//State changed, need to broadcast
459  {
460  LOG("[%s] - Temeperature level changed %d -> %d : \n", __FUNCTION__,cur_Thermal_Level,state );
461  //Broadcast this event
462  IARM_Bus_PWRMgr_EventData_t _eventData;
463  _eventData.data.therm.curLevel = cur_Thermal_Level;
464  _eventData.data.therm.newLevel = state;
465  _eventData.data.therm.curTemperature = current_Temp;
466 
468  IARM_BUS_PWRMGR_EVENT_THERMAL_MODECHANGED,(void *)&_eventData, sizeof(_eventData));
469 
470  cur_Thermal_Level = state;
471  }
472  //PACEXI5-2127 - BEGIN
473  if(0 == (pollCount % fifteenMinInterval))
474  {
475  LOG("[%s] - CURRENT_CPU_SCALE_MODE:%s \n", __FUNCTION__,
476  (cur_Cpu_Speed == PLAT_CPU_SPEED_NORMAL)?"Normal":
477  ((cur_Cpu_Speed == PLAT_CPU_SPEED_SCALED)?"Scaled":"Minimal"));
478  }
479  //PACEXI5-2127 - END
480  if (0 == pollCount % thermalLogInterval)
481  {
482  LOG("[%s] - Current Temperature %d\n", __FUNCTION__, (int)current_Temp );
483  }
484  cur_Thermal_Value = (int)current_Temp;
485 
486  /* Check if we should enter deepsleep based on the current temperature */
487  deepSleepIfNeeded();
488 
489  /* Check if we should reboot based on the current temperature */
490  rebootIfNeeded();
491 
492  /* Check if we should declock based on the current temperature */
493  declockIfNeeded();
494  }
495  else
496  {
497  LOG("Warning [%s] - Failed to retrieve temperature from OEM\n", __FUNCTION__);
498  }
499  sleep(thermal_poll_interval);
500  pollCount++;
501  }
502 }
503 
504 static IARM_Result_t _GetThermalState(void *arg)
505 {
506  IARM_Result_t retCode = IARM_RESULT_SUCCESS;
507 
508  LOG("[PwrMgr] thermal state is queried: \n");
509  if(NULL != arg)
510  {
511  IARM_Bus_PWRMgr_GetThermalState_Param_t *param = (IARM_Bus_PWRMgr_GetThermalState_Param_t *)arg;
512  param->curLevel = cur_Thermal_Level;
513  param->curTemperature = cur_Thermal_Value;
514  LOG("[PwrMgr] thermal state is queried: returning %d \n", cur_Thermal_Value);
515  }
516  else
517  {
518  retCode = IARM_RESULT_INVALID_PARAM;
519  }
520  return retCode;
521 }
522 
523 static IARM_Result_t _GetTemperatureThresholds(void *arg)
524 {
525  IARM_Result_t retCode = IARM_RESULT_IPCCORE_FAIL;
526  int result = 0;
527 
528  if(NULL != arg)
529  {
530  IARM_Bus_PWRMgr_GetTempThresholds_Param_t * param = (IARM_Bus_PWRMgr_GetTempThresholds_Param_t *) arg;
531  float high, critical;
532  result = PLAT_API_GetTempThresholds(&high,&critical);
533  if ( result )
534  {
535  retCode = IARM_RESULT_SUCCESS;
536  param->tempHigh = high;
537  param->tempCritical = critical;
538  LOG("[PwrMgr] Current thermal threshold : %f , %f \n", param->tempHigh,param->tempCritical);
539  }
540  }
541  else
542  {
543  retCode = IARM_RESULT_INVALID_PARAM;
544  }
545  return retCode;
546 }
547 
548 static IARM_Result_t _SetTemperatureThresholds(void *arg)
549 {
550  IARM_Result_t retCode = IARM_RESULT_SUCCESS;
551  int result = 0;
552  if(NULL != arg)
553  {
554  IARM_Bus_PWRMgr_SetTempThresholds_Param_t * param = (IARM_Bus_PWRMgr_SetTempThresholds_Param_t *) arg;
555  LOG("[PwrMgr] Setting thermal threshold : %f , %f \n", param->tempHigh,param->tempCritical); //CID:127982 ,127475,103705 - Print_args
556  result = PLAT_API_SetTempThresholds(param->tempHigh,param->tempCritical);
557  retCode = result?IARM_RESULT_SUCCESS:IARM_RESULT_IPCCORE_FAIL;
558  }
559  else
560  {
561  retCode = IARM_RESULT_INVALID_PARAM;
562  }
563  return retCode;
564 
565 }
566 
567 static IARM_Result_t _GetOvertempGraceInterval(void *arg)
568 {
569  IARM_Result_t retCode = IARM_RESULT_SUCCESS;
570 
571  if(NULL != arg)
572  {
573  IARM_Bus_PWRMgr_GetOvertempGraceInterval_Param_t * param = (IARM_Bus_PWRMgr_GetOvertempGraceInterval_Param_t *) arg;
574  {
575  param->graceInterval = thermal_reboot_grace_interval;
576  retCode = IARM_RESULT_SUCCESS;
577  LOG("[PwrMgr] Current over temparature grace interval : %d\n", param->graceInterval);
578  }
579  }
580  else
581  {
582  retCode = IARM_RESULT_INVALID_PARAM;
583  }
584  return retCode;
585 }
586 
587 static IARM_Result_t _SetOvertempGraceInterval(void *arg)
588 {
589  IARM_Result_t retCode = IARM_RESULT_SUCCESS;
590  if(NULL != arg)
591  {
592  IARM_Bus_PWRMgr_SetOvertempGraceInterval_Param_t * param = (IARM_Bus_PWRMgr_SetOvertempGraceInterval_Param_t *) arg;
593  if(param->graceInterval >= 0 )
594  {
595  LOG("[PwrMgr] Setting over temparature grace interval : %d\n", param->graceInterval);
596  thermal_reboot_grace_interval = param->graceInterval;
597  thermal_deepsleep_grace_interval = param->graceInterval;
598  retCode = IARM_RESULT_SUCCESS;
599  }
600  else
601  {
602  retCode = IARM_RESULT_INVALID_PARAM;
603  }
604  }
605  else
606  {
607  retCode = IARM_RESULT_INVALID_PARAM;
608  }
609  return retCode;
610 }
611 
612 static bool updateRFCStatus()
613 {
614  bool result = false;
615  RFC_ParamData_t param;
616 
617  isFeatureEnabled = TRUE;
618 
619  WDMP_STATUS status = getRFCParameter(THERMAL_PROTECTION_GROUP, "RFC_ENABLE_ThermalProtection", &param);
620 
621  if (status == WDMP_SUCCESS)
622  {
623  LOG("[%s:%d] Key: RFC_ENABLE_ThermalProtection,Value %s \n", __FUNCTION__, __LINE__, param.value);
624  if (0 == strncasecmp(param.value, "false",5))
625  {
626  isFeatureEnabled = FALSE;
627  }
628  else
629  {
630  result = true;
631  }
632  }
633  else
634  {
635  LOG("[%s:%d] Key: RFC_ENABLE_ThermalProtection is not configured, Status %d \n", __FUNCTION__, __LINE__, status);
636  }
637 
638  return result;
639 }
640 
641 static char * read_ConfigProperty(const char* key)
642 {
643  char *value = NULL;
644  int dataLen;
645  RFC_ParamData_t param;
646 
647 
648  WDMP_STATUS status = getRFCParameter(THERMAL_PROTECTION_GROUP, key, &param);
649 
650  valueBuf[0] = '\0';
651 
652  if (status == WDMP_SUCCESS)
653  {
654  dataLen = strlen(param.value);
655  if (dataLen > MAX_THERMAL_RFC-1)
656  {
657  dataLen = MAX_THERMAL_RFC-1;
658  }
659 
660  if ( (param.value[0] == '"') && (param.value[dataLen-1] == '"'))
661  {
662  // remove quotes arround data
663  strncpy (valueBuf, &param.value[1], dataLen-2);
664  valueBuf[dataLen-2] = '\0';
665  }
666  else
667  {
668  strncpy (valueBuf, param.value, MAX_THERMAL_RFC-1);
669  valueBuf[MAX_THERMAL_RFC-1] = '\0';
670  }
671 
672  LOG("name = %s, type = %d, value = %s, status = %d\n", param.name, param.type, param.value, status);
673  }
674  else
675  {
676  LOG("[%s:%d] Key: property %s is not configured, Status %d \n", __FUNCTION__, __LINE__, key, status);
677  }
678 
679 
680  if (valueBuf[0])
681  {
682  value = valueBuf;
683  }
684  else
685  {
686  LOG("[%s:%d] Unable to find key %s in group %s \n", __FUNCTION__, __LINE__, key, THERMAL_PROTECTION_GROUP);
687  }
688 
689  return value;
690 }
691 
692 static bool read_ConfigProps()
693 {
694  char *value = NULL;
695 
696  //Now override with RFC values if any
697  value = read_ConfigProperty("RFC_DATA_ThermalProtection_REBOOT_CRITICAL_THRESHOLD");
698  if (NULL != value)
699  {
700  thermal_reboot_critical_threshold = atoi(value);
701  }
702 
703  value = read_ConfigProperty("RFC_DATA_ThermalProtection_REBOOT_CONCERN_THRESHOLD");
704  if (NULL != value)
705  {
706  thermal_reboot_concern_threshold = atoi(value);
707  }
708 
709  value = read_ConfigProperty("RFC_DATA_ThermalProtection_REBOOT_SAFE_THRESHOLD");
710  if (NULL != value)
711  {
712  thermal_reboot_safe_threshold = atoi(value);
713  }
714 
715  value = read_ConfigProperty("RFC_DATA_ThermalProtection_REBOOT_GRACE_INTERVAL");
716  if (NULL != value)
717  {
718  thermal_reboot_grace_interval = atoi(value);
719  }
720 
721 
722  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DECLOCK_CRITICAL_THRESHOLD");
723  if (NULL != value)
724  {
725  thermal_declock_critical_threshold = atoi(value);
726  }
727 
728  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DECLOCK_CONCERN_THRESHOLD");
729  if (NULL != value)
730  {
731  thermal_declock_concern_threshold = atoi(value);
732  }
733 
734  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DECLOCK_SAFE_THRESHOLD");
735  if (NULL != value)
736  {
737  thermal_declock_safe_threshold = atoi(value);
738  }
739 
740  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DECLOCK_GRACE_INTERVAL");
741  if (NULL != value)
742  {
743  thermal_declock_grace_interval = atoi(value);
744  }
745 
746  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DEEPSLEEP_CRITICAL_THRESHOLD");
747  if (NULL != value)
748  {
749  thermal_deepsleep_critical_threshold =atoi(value);
750  }
751 
752  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DEEPSLEEP_CONCERN_THRESHOLD");
753  if (NULL != value)
754  {
755  thermal_deepsleep_concern_threshold = atoi(value);
756  }
757 
758  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DEEPSLEEP_SAFE_THRESHOLD");
759  if (NULL != value)
760  {
761  thermal_deepsleep_safe_threshold = atoi(value);
762  }
763 
764  value = read_ConfigProperty("RFC_DATA_ThermalProtection_DEEPSLEEP_GRACE_INTERVAL");
765  if (NULL != value)
766  {
767  thermal_deepsleep_grace_interval = atoi(value);
768  }
769 
770 
771  value = read_ConfigProperty("RFC_DATA_ThermalProtection_POLL_INTERVAL");
772  if (NULL != value)
773  {
774  thermal_poll_interval = atoi(value);
775  }
776 
777  value = read_ConfigProperty("RFC_DATA_ThermalProtection_PLAT_CPU_SPEED_NORMAL");
778  if (NULL != value)
779  {
780  PLAT_CPU_SPEED_NORMAL =atoi(value);
781  }
782 
783  value = read_ConfigProperty("RFC_DATA_ThermalProtection_PLAT_CPU_SPEED_SCALED");
784  if (NULL != value)
785  {
786  PLAT_CPU_SPEED_SCALED =atoi(value);
787  }
788 
789  value = read_ConfigProperty("RFC_DATA_ThermalProtection_PLAT_CPU_SPEED_MINIMAL");
790  if (NULL != value)
791  {
792  PLAT_CPU_SPEED_MINIMAL =atoi(value);
793  }
794 
795  return true;
796 }
797 
798 #endif//ENABLE_THERMAL_PROTECTION
799 
800 #ifdef __cplusplus
801 }
802 #endif
803 
804 /** @} */
805 /** @} */
IARM_BUS_PWRMGR_NAME
#define IARM_BUS_PWRMGR_NAME
Definition: pwrMgr.h:54
_PWRMgr_EventData_t
Structure which holds the event data.
Definition: pwrMgr.h:117
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.
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.
IARM_Bus_PWRMgr_ThermalState_t
enum _IARM_Bus_PWRMgr_ThermalState_t IARM_Bus_PWRMgr_ThermalState_t
Enumerator which represents the possible temeperature states.
pwrMgr.h
IARM-Bus Power Manager Public API.
IARM_BUS_PWRMGR_EVENT_THERMAL_MODECHANGED
@ IARM_BUS_PWRMGR_EVENT_THERMAL_MODECHANGED
Definition: pwrMgr.h:64
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199