RDK Documentation (Open Sourced RDK Components)
hostIf_utils.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 
21 
22 /**
23 * @defgroup tr69hostif
24 * @{
25 * @defgroup hostif
26 * @{
27 **/
28 
29 
30 #include "string.h"
31 #include "stdio.h"
32 #include <stddef.h>
33 #include <stdlib.h>
34 #include <sstream>
35 #include "hostIf_utils.h"
36 #include "safec_lib.h"
37 #include "cJSON.h"
38 
39 #if defined (RDK_DEVICE_CISCO_XI4) || defined (RDK_DEVICE_EMU)
40 #define INTERFACE_ETH "eth0"
41 #else
42 #define INTERFACE_ETH "eth1"
43 #endif
44 
45 static bool gAcsConnStatus = false;
46 static bool gGatewayConnStatus = false;
47 #ifndef NEW_HTTP_SERVER_DISABLE
48 static bool legacyRFC = false;
49 #endif
50 
51 const char* ntp_time_received_file="/tmp/timeReceivedNTP";
52 const char *webpa_start_tm_file ="/tmp/webpa/start_time";
53 
54 EntryExitLogger::EntryExitLogger (const char* func, const char* file) :
55  func (func), file (file)
56 {
57  RDK_LOG (RDK_LOG_TRACE1, LOG_TR69HOSTIF, "Entry: %s [%s]\n", func, file);
58 }
59 
60 EntryExitLogger::~EntryExitLogger ()
61 {
62  RDK_LOG (RDK_LOG_TRACE1, LOG_TR69HOSTIF, "Exit: %s [%s]\n", func, file);
63 }
64 
65 using namespace std;
66 
67 const char * getStringFromEnum( EnumStringMapper stbMapperArray[], int stbMapperArraySize, int enumCode )
68 {
69  register int i = 0;
70  for ( i = 0; i != stbMapperArraySize; i++ )
71  {
72  if ( stbMapperArray[i].enumCode == enumCode )
73  {
74  return stbMapperArray[i].enumString;
75  }
76  }
77 
78  return NULL;
79 }
80 
81 int getEnumFromString( EnumStringMapper stbMapperArray[], int stbMapperArraySize, const char * inputStr )
82 {
83  register int i = 0;
84  for ( i = 0; i != stbMapperArraySize; i++ )
85  {
86  if (!strncasecmp(stbMapperArray[i].enumString, inputStr, strlen(inputStr)))
87  {
88  return stbMapperArray[i].enumCode;
89  }
90  }
91 
92  return -1;
93 }
94 
95 #define MAX_NUM_LEN 10
96 bool matchComponent(const char* pParam, const char *pKey, const char **pSetting, int &instanceNo)
97 {
98  bool ret = false;
99  int str_len = strlen(pKey);
100  ret = (strncasecmp(pParam,pKey,str_len)==0?true:false);
101 
102  if(ret)
103  {
104  const char *tmp_ptr;
105  int tmp_len;
106  if((pParam[str_len] == '.') &&
107  (tmp_ptr = strchr(pParam+str_len+1,'.')) &&
108  (tmp_len = tmp_ptr - (pParam + str_len + 1)) < MAX_NUM_LEN)
109  {
110  char tmp_buff[MAX_NUM_LEN];
111  memset(tmp_buff,0,MAX_NUM_LEN);
112  strncpy(tmp_buff,pParam+str_len+1,tmp_len);
113  instanceNo = atoi(tmp_buff);
114  *pSetting = (tmp_ptr + 1);
115  }
116  else
117  ret = false;
118  }
119 
120  return ret;
121 
122 }
123 
124 std::string int_to_string(int d)
125 {
126  char tmp_buff[10];
127  memset(tmp_buff,0,10);
128  sprintf(tmp_buff,"%d",d);
129  return std::string(tmp_buff);
130 }
131 
132 std::string uint_to_string(uint d)
133 {
134  std::stringstream ss;
135  ss << d;
136  return ss.str();
137 }
138 
139 std::string ulong_to_string(unsigned long d)
140 {
141  std::stringstream ss;
142  ss << d;
143  return ss.str();
144 }
145 
146 int get_int(const char* ptr)
147 {
148  int *ret = (int *)ptr;
149  return *ret;
150 }
151 
152 void put_int(char *ptr, int val)
153 {
154  int *tmp = (int *)ptr;
155  *tmp = val;
156 }
157 
158 uint get_uint(char *ptr)
159 {
160  uint *ret = (uint *)ptr;
161  return *ret;
162 }
163 
164 void put_uint(char *ptr, uint val)
165 {
166  uint *tmp = (uint *)ptr;
167  *tmp = val;
168 }
169 
170 
171 
172 int get_ulong(const char* ptr)
173 {
174  unsigned long *ret = (unsigned long *)ptr;
175  return *ret;
176 }
177 
178 void put_ulong(char *ptr, unsigned long val)
179 {
180  unsigned long *tmp = (unsigned long *)ptr;
181  *tmp = val;
182 }
183 
184 
185 bool get_boolean(const char *ptr)
186 {
187  bool *ret = (bool *)ptr;
188  return *ret;
189 }
190 
191 void put_boolean(char *ptr, bool val)
192 {
193  bool *tmp = (bool *)ptr;
194  *tmp = val;
195 }
196 
197 std::string bool_to_string(bool value)
198 {
199  if (value == true) {
200  return "true";
201  } else if (value == false) {
202  return "false";
203  }
204  return "";
205 }
206 
207 int string_to_int(const char *value)
208 {
209  char *end;
210  long ret = strtol(value, &end, 10);
211  return (int)ret;
212 }
213 
214 uint string_to_uint(const char *value)
215 {
216  char *end;
217  unsigned long ret = strtoul(value, &end, 10);
218  return (uint)ret;
219 }
220 
221 unsigned long string_to_ulong(const char *value)
222 {
223  char *end;
224  unsigned long ret = strtoul(value, &end, 10);
225  return ret;
226 }
227 
228 bool string_to_bool(const char *value)
229 {
230  bool ret = (strcmp(value, "true") == 0) ? true : false;
231  return ret;
232 }
233 
234 std::string getStringValue(HOSTIF_MsgData_t *stMsgData)
235 {
236  switch (stMsgData->paramtype) {
237  case hostIf_StringType:
238  return string(stMsgData->paramValue);
239  case hostIf_IntegerType:
240  return int_to_string(get_int(stMsgData->paramValue));
241  case hostIf_UnsignedIntType:
242  return uint_to_string(get_uint(stMsgData->paramValue));
243  case hostIf_BooleanType:
244  return bool_to_string(get_boolean(stMsgData->paramValue));
245  case hostIf_UnsignedLongType:
246  return ulong_to_string(get_ulong(stMsgData->paramValue));
247  case hostIf_DateTimeType:
248  // we don't handle this one yet
249  default:
250  return "";
251  }
252 }
253 
254 void putValue(HOSTIF_MsgData_t *stMsgData, const string &value)
255 {
256  errno_t rc = -1;
257  // std::cout << "value ot be inserted is : " << value << std::endl;
258  memset(stMsgData->paramValue, 0, TR69HOSTIFMGR_MAX_PARAM_LEN);
259 
260  switch (stMsgData->paramtype) {
261  case hostIf_StringType:
262  {
263  rc=strcpy_s(stMsgData->paramValue,sizeof(stMsgData->paramValue), value.c_str());
264  if(rc!=EOK)
265  {
266  ERR_CHK(rc);
267  }
268  stMsgData->paramLen = strlen(value.c_str());
269  break;
270  }
271  case hostIf_IntegerType:
272  put_int(stMsgData->paramValue, string_to_int(value.c_str()));
273  break;
274  case hostIf_UnsignedIntType:
275  put_uint(stMsgData->paramValue, string_to_uint(value.c_str()));
276  break;
277  case hostIf_BooleanType:
278  put_boolean(stMsgData->paramValue, string_to_bool(value.c_str()));
279  break;
280  case hostIf_UnsignedLongType:
281  put_ulong(stMsgData->paramValue, string_to_ulong(value.c_str()));
282  break;
283  case hostIf_DateTimeType:
284  // we don't handle this one yet
285  default:
286  break;
287  }
288 }
289 
290 void setResetState( eSTBResetState rebootFlag)
291 {
292  gResetState = rebootFlag;
293 }
294 
295 eSTBResetState getResetState( void )
296 {
297  return gResetState;
298 }
299 
300 void triggerResetScript()
301 {
302  int ret = -1;
303  char scriptbuff[100] = {'\0'};
304 
305  switch (gResetState) {
306  case ColdReset:
307  /* Excute Cold Factory Reset script */
308  sprintf(scriptbuff,"%s %s/%s", "sh", SCR_PATH, "coldfactory-reset.sh");
309  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Executing : %s \n",__FUNCTION__, scriptbuff);
310 
311  /*System command */
312  ret = system(scriptbuff);
313  if (WEXITSTATUS(ret) != 0 )
314  {
315  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s] Failed to execute : %s. \n",__FUNCTION__, scriptbuff);
316  }
317  else {
318  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Successfully executed %s Reset. \n",__FUNCTION__, scriptbuff);
319  system(REBOOT_SCR);
320  }
321  break;
322 
323  case FactoryReset:
324  /* Excute Factory Reset script */
325  sprintf(scriptbuff,"%s %s/%s", "sh", SCR_PATH, "factory-reset.sh");
326 
327  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Executing : %s \n",__FUNCTION__, scriptbuff);
328 
329  /*System command */
330  ret = system(scriptbuff);
331  if (WEXITSTATUS(ret) != 0 )
332  {
333  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s] Failed to execute : %s. \n",__FUNCTION__, scriptbuff);
334  }
335  else {
336  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Successfully executed %s Reset. \n",__FUNCTION__, scriptbuff);
337  system(REBOOT_SCR);
338  }
339  break;
340  case WarehouseReset:
341  /* Excute Warehouse Reset script */
342  sprintf(scriptbuff,"%s %s/%s", "sh", SCR_PATH, "warehouse-reset.sh");
343  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Executing : %s \n",__FUNCTION__, scriptbuff);
344 
345  /*System command */
346  ret = system(scriptbuff);
347  if (WEXITSTATUS(ret) != 0 )
348  {
349  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s] Failed to execute: %s. \n",__FUNCTION__, scriptbuff);
350  }
351  else {
352  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Successfully executed %s Reset. \n",__FUNCTION__, scriptbuff);
353  }
354  break;
355  case CustomerReset:
356  /* Excute Customer Reset script */
357  sprintf(scriptbuff,"%s %s/%s", "sh", SCR_PATH, "customer-reset.sh");
358  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Executing : %s \n",__FUNCTION__, scriptbuff);
359 
360  /*System command */
361  ret = system(scriptbuff);
362  if (WEXITSTATUS(ret) != 0 )
363  {
364  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s] Failed to execute: %s. \n",__FUNCTION__, scriptbuff);
365  }
366  else {
367  RDK_LOG(RDK_LOG_INFO,LOG_TR69HOSTIF,"[%s] Successfully executed %s Reset. \n",__FUNCTION__, scriptbuff);
368  system(REBOOT_SCR);
369  }
370  break;
371  default:
372  RDK_LOG(RDK_LOG_ERROR,LOG_TR69HOSTIF,"[%s] Invalid input for reset \n",__FUNCTION__);
373  break;
374  }
375 
376 }
377 
378 
379 void set_ACSStatus( bool enabled)
380 {
381  gAcsConnStatus = enabled;
382 }
383 
384 bool get_ACSStatus()
385 {
386  return gAcsConnStatus;
387 }
388 
389 void set_GatewayConnStatus( bool enabled)
390 {
391  gGatewayConnStatus = enabled;
392 }
393 
394 bool get_GatewayConnStatus()
395 {
396  return gGatewayConnStatus;
397 }
398 
399 /**
400  * Returns:
401  * the specified environment variable's value if it is not NULL.
402  * the specified default value otherwise.
403  */
404 char* getenvOrDefault (const char* name, char* defaultValue)
405 {
406  char* value = getenv (name);
407  return value ? value : defaultValue;
408 }
409 
410 int read_command_output (char* cmd, char* resultBuff, int length)
411 {
412  FILE* fp = popen (cmd, "r");
413  if (fp == NULL)
414  {
415  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s]: cannot run command [%s]\n", __FUNCTION__, cmd);
416  return NOK;
417  }
418  if (fgets (resultBuff, length, fp) == NULL)
419  {
420  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s]: cannot read output from command [%s]\n", __FUNCTION__, cmd);
421  pclose (fp);
422  return NOK;
423  }
424  pclose (fp);
425 
426  RDK_LOG (RDK_LOG_DEBUG, LOG_TR69HOSTIF, "[%s]: command [%s] returned [%s]\n", __FUNCTION__, cmd, resultBuff);
427 
428  return OK;
429 }
430 
431 /**
432  * @brief This function reads the complete output(upto 1k bytes) as string and return to caller.
433  * It returns output with new line character \n if the console output has new line.
434  */
435 int GetStdoutFromCommand(char *cmd, string &consoleString)
436 {
437  FILE * stream;
438  char buffer[BUFF_LENGTH_1024];
439 
440  memset(buffer, 0, sizeof(buffer));
441  consoleString.clear();
442  stream = popen(cmd, "r");
443  if (stream == NULL) {
444  return -1;
445  }
446  else
447  {
448  while (!feof(stream))
449  {
450  if (fgets(buffer, BUFF_LENGTH_1024, stream) != NULL)
451  {
452  consoleString.append(buffer);
453  }
454  }
455  pclose(stream);
456  }
457  return 0;
458 }
459 
460 #ifndef NEW_HTTP_SERVER_DISABLE
461 /**
462  * @brief Get Current time
463  *
464  * @param[in] Time spec timer
465  */
466 void getCurrentTime(struct timespec *timer)
467 {
468  clock_gettime(CLOCK_REALTIME, timer);
469 }
470 
471 
472 long timeValDiff(struct timespec *starttime, struct timespec *finishtime)
473 {
474  long msec;
475  msec=(finishtime->tv_sec-starttime->tv_sec)*1000;
476  msec+=(finishtime->tv_nsec-starttime->tv_nsec)/1000000;
477  return msec;
478 }
479 
480 void setLegacyRFCEnabled(bool value)
481 {
482  legacyRFC = value;
483 }
484 
485 bool legacyRFCEnabled()
486 {
487  return legacyRFC;
488 }
489 #endif
490 
491 HostIf_Source_Type_t getBSUpdateEnum(const char *bsUpdate)
492 {
493  if (!bsUpdate)
494  return HOSTIF_NONE;
495 
496  if (strcasecmp(bsUpdate, "allUpdate") == 0)
497  return HOSTIF_SRC_ALL;
498  else if (strcasecmp(bsUpdate, "rfcUpdate") == 0)
499  return HOSTIF_SRC_RFC;
500  else if (strcasecmp(bsUpdate, "default") == 0)
501  return HOSTIF_SRC_DEFAULT;
502  return HOSTIF_NONE;
503 }
504 
505 bool isWebpaReady()
506 {
507  return ((access("/tmp/webpa/start_time", F_OK) == 0)?true:false);
508 }
509 
510 bool isNtpTimeFilePresent()
511 {
512  return ((access(ntp_time_received_file, F_OK) == 0)?true:false);
513 }
514 
515 unsigned long get_system_manageble_ntp_time()
516 {
517  unsigned long ret = 0;
518  FILE* fp = fopen(ntp_time_received_file, "r");
519 
520  if (fp == NULL) {
521  return ret;
522  }
523 
524  char* line = NULL;
525  size_t len = 0;
526 
527  if((getline(&line, &len, fp)) != -1) {
528  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Date : \"%s\".\n", line);
529  }
530 
531  fclose(fp);
532 
533  struct tm tm = {0};
534  time_t epoch = 0;
535  char* s_time = NULL;
536 
537  s_time = strptime(line, "%a %b %d %H:%M:%S %Z %Y", &tm);
538 
539  if (NULL != s_time ) {
540  epoch = mktime(&tm);
541  ret = (unsigned long)epoch;
542  }
543  else {
544  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] Failed to parse NTP Date Format from \'%f\' file.\n ", __FUNCTION__, ntp_time_received_file);
545  }
546  if (line) free(line);
547  return ret;
548 }
549 
550 unsigned long get_device_manageble_time()
551 {
552  unsigned long epoch_time = 0;
553  FILE *fptr = NULL;
554  int counter = 0;
555 
556  do {
557  if(epoch_time || counter++ >=5 )
558  break;
559  if ((fptr = fopen(webpa_start_tm_file, "r")) != NULL) {
560  fscanf(fptr,"%ld", &epoch_time);
561  RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF,"Device Manageble Time =%ld\n", epoch_time);
562  fclose(fptr);
563  }
564  if(epoch_time == 0)
565  sleep(1);
566  }
567  while(epoch_time == 0);
568 
569  return epoch_time;
570 }
571 
572 std::string get_security_token() {
573  std::string sToken = "";
574  char pSecurityOutput[256] = {0};
575  bool status;
576  FILE *pSecurity = popen("/usr/bin/WPEFrameworkSecurityUtility", "r");
577  if(pSecurity) {
578  if (fgets(pSecurityOutput, 256, pSecurity) != NULL) {
579  cJSON* root = cJSON_Parse(pSecurityOutput);
580  if (root) {
581  cJSON *res = cJSON_GetObjectItem(root, "success");
582  if(cJSON_IsTrue(res) == 1) {
583  cJSON* token = cJSON_GetObjectItem(root, "token");
584  if (token != NULL && token->type == cJSON_String && token->valuestring != NULL) {
585  RDK_LOG (RDK_LOG_INFO, LOG_TR69HOSTIF, "%s: Security Token retrieved successfully\n", __FUNCTION__);
586  sToken = token->valuestring;
587  }
588  }
589  else {
590  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF,"%s: Security Token retrieval failed!\n", __FUNCTION__);
591  }
592  cJSON_Delete(root);
593  }
594  else {
595  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF, "[%s] json parse error\n", __FUNCTION__);
596  if (NULL != pSecurity)
597  pclose(pSecurity);
598  }
599  }
600  }
601  else {
602  RDK_LOG (RDK_LOG_ERROR, LOG_TR69HOSTIF,"%s: Failed to open security utility\n", __FUNCTION__);
603  }
604  if (NULL != pSecurity)
605  pclose(pSecurity);
606 
607  return sToken;
608 }
609 
610 /** @} */
611 /** @} */
getCurrentTime
void getCurrentTime(struct timespec *timer)
Get Current time.
Definition: hostIf_utils.cpp:466
getenvOrDefault
char * getenvOrDefault(const char *name, char *defaultValue)
Definition: hostIf_utils.cpp:404
HostIf_Source_Type_t
enum _HostIf_Source_Type_t HostIf_Source_Type_t
_HostIf_MsgData_t
Definition: hostIf_tr69ReqHandler.h:170
put_boolean
void put_boolean(char *ptr, bool val)
This function converts the input data to Boolean type.
Definition: hostIf_utils.cpp:191
_HostIf_MsgData_t::paramtype
HostIf_ParamType_t paramtype
Definition: hostIf_tr69ReqHandler.h:177
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
get_security_token
std::string get_security_token()
Definition: hostIf_utils.cpp:572
GetStdoutFromCommand
int GetStdoutFromCommand(char *cmd, string &consoleString)
This function reads the complete output(upto 1k bytes) as string and return to caller....
Definition: hostIf_utils.cpp:435
_HostIf_MsgData_t::paramValue
char paramValue[(4 *1024)]
Definition: hostIf_tr69ReqHandler.h:172
EnumStringMapper
Definition: hostIf_utils.h:73
put_int
void put_int(char *ptr, int val)
This function converts the input data to integer type.
Definition: hostIf_utils.cpp:152
_HostIf_MsgData_t::paramLen
short paramLen
Definition: hostIf_tr69ReqHandler.h:175