RDK Documentation (Open Sourced RDK Components)
dcautils.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 
22 /**
23  * @defgroup dca
24  * @{
25  **/
26 
27 
28 
29 
30 /**
31  * @defgroup dca
32  * @{
33  * @defgroup src
34  * @{
35  **/
36 
37 
38 #include "dcautils.h"
39 #include "safec_lib.h"
40 
41 
42 
43 #define EC_BUF_LEN 20
44 
45 /**
46  * @addtogroup DCA_APIS
47  * @{
48  */
49 
50 
51 /**
52  * @brief This API is to find the load average of system and add it to the SearchResult JSON.
53  *
54  * @return Returns status of operation.
55  * @retval Return 1 on success.
56  */
58 {
59  FILE *fp;
60  char str[LEN+1];
61 
62  if (NULL == (fp = fopen("/proc/loadavg", "r"))) {
63  LOG("Error in opening /proc/loadavg file");
64  return 0;
65  }
66  if (fread(str, 1, LEN, fp) != LEN) {
67  LOG("Error in reading loadavg");
68  fclose(fp);
69  return 0;
70  }
71  fclose(fp);
72  str[LEN] = '\0';
73 
74  addToSearchResult("Load_Average", str);
75  return 1;
76 }
77 
78 /**
79  * @brief This function returns file size.
80  *
81  * @param[in] fp File name
82  *
83  * @return Returns size of file.
84  */
85 static int fsize(FILE *fp) {
86  int prev = ftell(fp);
87  fseek(fp, 0L, SEEK_END);
88  int sz = ftell(fp);
89  if(prev >= 0)
90  {
91  if(fseek(fp, prev, SEEK_SET) != 0){
92  LOG("Cannot set the file position indicator for the stream pointed to by stream\n");
93  }
94  }
95  return sz;
96 }
97 
98 /**
99  * @brief This function is to clear/free the global paths.
100  */
101 void clearConfVal(void)
102 {
103  if (PERSISTENT_PATH)
104  free(PERSISTENT_PATH);
105 
106  if (LOG_PATH)
107  free(LOG_PATH);
108 
109  if (DEVICE_TYPE)
110  free(DEVICE_TYPE);
111 }
112 
113 /**
114  * @brief To update current dca execution count
115  */
117 {
118  FILE *ec_fp = NULL;
119  char buf[EC_BUF_LEN] = {0};
120  char *rval = NULL;
121 
122  ec_fp = fopen(EXEC_COUNTER_FILENAME, "r");
123  if (NULL == ec_fp) {
124  CUR_EXEC_COUNT = 0;
125  return;
126  }
127 
128  rval = fgets(buf, EC_BUF_LEN, ec_fp);
129  fclose(ec_fp);
130  if (NULL == rval) {
131  CUR_EXEC_COUNT = 0;
132  return;
133  }
134 
135  CUR_EXEC_COUNT = atoi(buf);
136  CUR_EXEC_COUNT++;
137  if (CUR_EXEC_COUNT < 0)
138  CUR_EXEC_COUNT = 0;
139 
140  return;
141 }
142 
143 void saveExecCounter()
144 {
145  FILE *ec_fp = NULL;
146  ec_fp = fopen(EXEC_COUNTER_FILENAME, "w");
147  if (NULL == ec_fp) {
148  return;
149  }
150 
151  fprintf(ec_fp, "%d" , CUR_EXEC_COUNT);
152  fclose(ec_fp);
153  return;
154 }
155 
156 /**
157  * @brief This API is to verify whether to skip this telemetry marker.
158  *
159  * @param[in] skipInterval Polling frequency
160  *
161  * @return Retuns 0 or 1 depening upon the polling frequency.
162  */
163 int isSkipParam(int skipInterval)
164 {
165  int rval = 1;
166  if (skipInterval == 0 || CUR_EXEC_COUNT == 0) {
167  rval = 0;
168  } else {
169  skipInterval++;
170  if (CUR_EXEC_COUNT < skipInterval) {
171  rval = 1;
172  } else {
173  if ((CUR_EXEC_COUNT % skipInterval) == 0) {
174  rval = 0;
175  }
176  }
177  }
178  return rval;
179 }
180 
181 /**
182  * @brief Function to return rotated log file.
183  *
184  * @param[in] buf Buffer
185  * @param[in] buflen Maximum buffer length
186  * @param[in] name Current Log file
187  *
188  * @return Returns Seek Log file.
189  */
190 char *getsRotatedLog(char *buf, int buflen, char *name)
191 {
192  static FILE *LOG_FP = NULL;
193  static int is_rotated_log = 0;
194  char *rval = NULL;
195  errno_t rc = -1;
196  char *curLog = NULL;
197  char * rotatedLog = NULL;
198  size_t curLog_len = 0;
199  size_t rotatedLog_len = 0;
200  char *fileExtn = ".1";
201 
202  if ((NULL == PERSISTENT_PATH) || (NULL == LOG_PATH) || (NULL == name)) {
203  LOG("Path variables are empty");
204  return NULL;
205  }
206 
207  curLog_len = strlen(LOG_PATH) + strlen(name) + 1;
208  rotatedLog_len = strlen(LOG_PATH) + strlen(name) + strlen(fileExtn) + 1;
209  curLog = malloc(curLog_len);
210  rotatedLog = malloc(rotatedLog_len);
211  if((curLog == NULL) || (rotatedLog == NULL))
212  return NULL;
213 
214  if (NULL == LOG_FP)
215  {
216  long seek_value = 0;
217  if (NULL != curLog)
218  {
219  rc = sprintf_s(curLog,curLog_len, "%s%s", LOG_PATH,name);
220  if(rc < EOK)
221  {
222  ERR_CHK(rc);
223  goto EXIT;
224  }
225 
226  if (0 != readLogSeek(name, &seek_value))
227  {
228  if(CUR_EXEC_COUNT == 0){
229  rc = sprintf_s(rotatedLog,rotatedLog_len, "%s%s%s", LOG_PATH,name,fileExtn);
230  if(rc < EOK)
231  {
232  ERR_CHK(rc);
233  goto EXIT;
234  }
235  LOG_FP = fopen(rotatedLog, "rb");
236  if(NULL == LOG_FP){
237  LOG("Error in opening %s\n",rotatedLog);
238  LOG_FP = fopen(curLog, "rb");
239  if (NULL == LOG_FP)
240  goto EXIT;
241  }
242  else {
243  is_rotated_log = 1;
244  }
245  }
246  else {
247  LOG_FP = fopen(curLog, "rb");
248 
249  if (NULL == LOG_FP)
250  goto EXIT;
251 
252  }
253  }
254  else
255  {
256  long fileSize = 0;
257 
258  LOG_FP = fopen(curLog, "rb");
259 
260  if (NULL == LOG_FP)
261  {
262  LAST_SEEK_VALUE = 0;
263  goto EXIT;
264  }
265 
266  fileSize = fsize(LOG_FP);
267 
268  if (seek_value <= fileSize)
269  {
270  if(fseek(LOG_FP, seek_value, 0) != 0){
271  LOG("Cannot set the file position indicator for the stream pointed to by stream\n");
272  }
273  }
274  else
275  {
276  int entry_flag = -1;
277  int ind = -1;
278 
279  if(NULL != DEVICE_TYPE)
280  {
281  rc = strcmp_s("broadband", strlen("broadband"), DEVICE_TYPE , &ind);
282  ERR_CHK(rc);
283  if((!ind) && (rc == EOK))
284  {
285  entry_flag = 1;
286  }
287  }
288 
289  if (1 == entry_flag)
290  {
291  LOG("Telemetry file pointer corrupted");
292  if(fseek(LOG_FP, 0, 0) != 0){
293  LOG("Cannot set the file position indicator for the stream pointed to by stream\n");
294  }
295  }
296  else
297  {
298  if (NULL != rotatedLog) {
299  rc = sprintf_s(rotatedLog,rotatedLog_len, "%s%s%s", LOG_PATH,name,fileExtn);
300  if(rc < EOK)
301  {
302  ERR_CHK(rc);
303  fclose(LOG_FP);
304  LOG_FP = NULL;
305  goto EXIT;
306  }
307 
308  fclose(LOG_FP);
309  LOG_FP = NULL;
310 
311  LOG_FP = fopen(rotatedLog, "rb");
312 
313  if (NULL == LOG_FP)
314  {
315  LOG("Error in opening file %s", rotatedLog);
316  LAST_SEEK_VALUE = 0;
317  goto EXIT;
318  }
319 
320 
321  if(fseek(LOG_FP, seek_value, 0) != 0){
322  LOG("Cannot set the file position indicator for the stream pointed to by stream\n");
323  }
324  is_rotated_log = 1;
325  }
326 
327  }
328  }
329  }
330  }
331 
332  }
333 
334  if (NULL != LOG_FP)
335  {
336  rval = fgets(buf, buflen, LOG_FP);
337  if (NULL == rval)
338  {
339  long seek_value = ftell(LOG_FP);
340  LAST_SEEK_VALUE = seek_value;
341 
342  fclose(LOG_FP);
343  LOG_FP = NULL;
344 
345  if (is_rotated_log == 1)
346  {
347  is_rotated_log = 0;
348  if (NULL != curLog)
349  {
350  rc = sprintf_s(curLog,curLog_len, "%s%s", LOG_PATH,name);
351  if(rc < EOK)
352  {
353  ERR_CHK(rc);
354  goto EXIT;
355  }
356 
357  LOG_FP = fopen(curLog, "rb");
358 
359  if (NULL == LOG_FP)
360  {
361  LOG("Error in opening file %s", curLog);
362  LAST_SEEK_VALUE = 0;
363  goto EXIT;
364  }
365 
366  }
367  rval = fgets(buf, buflen, LOG_FP);
368  if (NULL == rval)
369  {
370  seek_value = ftell(LOG_FP);
371  LAST_SEEK_VALUE = seek_value;
372 
373  fclose(LOG_FP);
374  LOG_FP = NULL;
375  }
376 
377  }
378  }
379  }
380 
381  free(curLog);
382  free(rotatedLog);
383  return rval;
384 
385 EXIT:
386  free(curLog);
387  free(rotatedLog);
388  return NULL;
389 }
390 
391 /**
392  * @brief Function to update the global paths like PERSISTENT_PATH,LOG_PATH from include.properties file.
393  *
394  * @param[in] logpath Log file path
395  * @param[in] perspath Persistent path
396  */
397 void updateIncludeConfVal(char *logpath, char *perspath)
398 {
399  errno_t rc = -1;
400  int p_path_len = -1, log_path_len = -1;
401  FILE *file = fopen( INCLUDE_PROPERTIES, "r");
402  if(NULL != file )
403  {
404  char props[255] = {""};
405  p_path_len = strlen("PERSISTENT_PATH=");
406  log_path_len = strlen("LOG_PATH=");
407  while(fscanf(file,"%255s", props) != EOF )
408  {
409  char *property = NULL;
410  if ((property = strstr( props, "PERSISTENT_PATH="))) {
411  property = property + p_path_len;
412  PERSISTENT_PATH = malloc(strlen(property) + 1);
413  if (NULL != PERSISTENT_PATH) {
414  rc = strcpy_s(PERSISTENT_PATH,strlen(property) + 1, property);
415  if(rc != EOK)
416  {
417  ERR_CHK(rc);
418  free(PERSISTENT_PATH);
419  PERSISTENT_PATH = NULL;
420  fclose(file);
421  return;
422  }
423  }
424  } else if ((property = strstr( props, "LOG_PATH="))) {
425  if ( 0 == strncmp(props, "LOG_PATH=", log_path_len) ) {
426  property = property + log_path_len;
427  LOG_PATH = malloc(strlen(property) + 1);
428  if (NULL != LOG_PATH) {
429  rc = strcpy_s(LOG_PATH,strlen(property) + 1, property);
430  if(rc != EOK)
431  {
432  ERR_CHK(rc);
433  free(LOG_PATH);
434  LOG_PATH = NULL;
435  fclose(file);
436  return;
437  }
438 
439  }
440  }
441  }
442  }
443  fclose(file);
444  }
445  if ((NULL != logpath) && (logpath[0] != '\0'))
446  {
447  char *tmp = NULL;
448  tmp = realloc(LOG_PATH, strlen(logpath) + 1 );
449  if (NULL != tmp) {
450  LOG_PATH = tmp;
451  rc = strcpy_s(LOG_PATH,strlen(logpath) + 1, logpath);
452  if(rc != EOK)
453  {
454  ERR_CHK(rc);
455  free(LOG_PATH);
456  LOG_PATH = NULL;
457  return;
458  }
459  } else {
460  free(LOG_PATH);
461  LOG_PATH = NULL;
462  }
463  }
464  if ((NULL != perspath) && (perspath[0] != '\0'))
465  {
466  char *tmp = NULL;
467  tmp = realloc(PERSISTENT_PATH,strlen(perspath) + 1 );
468  if (NULL != tmp) {
469  PERSISTENT_PATH = tmp;
470  rc = strcpy_s(PERSISTENT_PATH,strlen(perspath) + 1, perspath);
471  if(rc != EOK)
472  {
473  ERR_CHK(rc);
474  free(PERSISTENT_PATH);
475  PERSISTENT_PATH = NULL;
476  return;
477  }
478  } else {
479  free(PERSISTENT_PATH);
480  PERSISTENT_PATH = NULL;
481  }
482  }
483 }
484 
485 /**
486  * @brief Function to update the configuration values from device.properties file.
487  *
488  * @param[in] logpath Log file path
489  * @param[in] perspath Persistent path
490  */
491 void updateConfVal(char *logpath, char *perspath)
492 {
493  FILE *file = NULL;
494  errno_t rc = -1;
495  int ind = -1;
496  int device_type_len = strlen("DEVICE_TYPE=");
497  int length = 0 ;
498 
499  file = fopen( DEVICE_PROPERTIES, "r");
500  if(NULL != file )
501  {
502  char props[255] = {""};
503  while(fscanf(file,"%255s", props) != EOF )
504  {
505  char *property = NULL;
506  length = 0;
507  if((property = strstr( props, "DEVICE_TYPE=")))
508  {
509  property = property + device_type_len;
510  length = strlen(property) + 1;
511  DEVICE_TYPE = malloc(length);
512  if (NULL != DEVICE_TYPE) {
513  rc = strcpy_s(DEVICE_TYPE,length, property);
514  if(rc != EOK)
515  {
516  ERR_CHK(rc);
517  free(DEVICE_TYPE);
518  DEVICE_TYPE = NULL;
519  fclose(file);
520  return;
521  }
522  }
523  break;
524  }
525  }
526  fclose(file);
527  }
528 
529  updateIncludeConfVal(logpath, perspath);
530 
531  if (NULL != DEVICE_TYPE && NULL != PERSISTENT_PATH && NULL != LOG_PATH) {
532  rc = strcmp_s("broadband", strlen("broadband"), DEVICE_TYPE , &ind);
533  ERR_CHK(rc);
534  if((!ind) && (rc == EOK)) {
535  char *tmp_seek_file = "/.telemetry/tmp/rtl_";
536  char *tmp_log_file = "/";
537  char *tmp = NULL;
538 
539  if (NULL == perspath || perspath[0] == '\0') {
540  length = strlen(PERSISTENT_PATH) + strlen(tmp_seek_file) + 1 ;
541  tmp = realloc(PERSISTENT_PATH,length );
542  if (NULL != tmp) {
543  PERSISTENT_PATH = tmp;
544  rc = strcat_s(PERSISTENT_PATH,length, tmp_seek_file);
545  if(rc != EOK)
546  {
547  ERR_CHK(rc);
548  free(PERSISTENT_PATH);
549  PERSISTENT_PATH = NULL;
550  return;
551  }
552  } else {
553  free(PERSISTENT_PATH);
554  PERSISTENT_PATH = NULL;
555  }
556  }
557 
558  if (NULL == logpath || logpath[0] == '\0') {
559  length = strlen(LOG_PATH) + strlen(tmp_log_file) + 1 ;
560  tmp = realloc(LOG_PATH, length );
561  if (NULL != tmp) {
562  LOG_PATH = tmp;
563  rc = strcat_s(LOG_PATH,length, tmp_log_file);
564  if(rc != EOK)
565  {
566  ERR_CHK(rc);
567  free(LOG_PATH);
568  LOG_PATH = NULL;
569  return;
570  }
571  } else {
572  free(LOG_PATH);
573  LOG_PATH = NULL;
574  }
575  }
576  } else {
577  /* FIXME */
578  char *tmp_seek_file = DEFAULT_SEEK_PREFIX;
579  char *tmp_log_file = DEFAULT_LOG_PATH;
580  char *tmp = NULL;
581 
582  //char *tmp_seek_file = "./tmp/rtl_";
583  //char *tmp_log_file = "./logs/";
584  if (NULL == perspath || perspath[0] == '\0') {
585  length = strlen(tmp_seek_file) + 1;
586  tmp = realloc(PERSISTENT_PATH, length );
587  if (NULL != tmp) {
588  PERSISTENT_PATH = tmp;
589  rc = strcpy_s(PERSISTENT_PATH,length, tmp_seek_file);
590  if(rc != EOK)
591  {
592  ERR_CHK(rc);
593  free(PERSISTENT_PATH);
594  PERSISTENT_PATH = NULL;
595  return;
596  }
597  } else {
598  free(PERSISTENT_PATH);
599  PERSISTENT_PATH = NULL;
600  }
601  }
602 
603  if (NULL == logpath || logpath[0] == '\0') {
604  length = strlen(tmp_log_file) + 1 ;
605  tmp = realloc(LOG_PATH, length );
606  if (NULL != tmp) {
607  LOG_PATH = tmp;
608  rc = strcpy_s(LOG_PATH,length, tmp_log_file);
609  if(rc != EOK)
610  {
611  ERR_CHK(rc);
612  free(LOG_PATH);
613  LOG_PATH = NULL;
614  return;
615  }
616  } else {
617  free(LOG_PATH);
618  LOG_PATH = NULL;
619  }
620  }
621  }
622  }
623 
624 }
625 
626 /**
627  * @brief Function to read the rotated Log file.
628  *
629  * @param[in] name Log file name.
630  * @param[in] seek_value Position to seek.
631  *
632  * @return Returns the status of the operation.
633  * @retval Returns -1 on failure, appropriate errorcode otherwise.
634  */
635 int readLogSeek(char *name, long *seek_value)
636 {
637  int rc = -1;
638  errno_t ret = -1;
639  int length = 0 ;
640  if (NULL != name && NULL != PERSISTENT_PATH) {
641  char *seekfile = NULL;
642  length = strlen(PERSISTENT_PATH) + strlen(name) + 1;
643  seekfile = malloc(length);
644  if (NULL != seekfile) {
645  FILE *fp = NULL;
646  ret = sprintf_s(seekfile,length, "%s%s", PERSISTENT_PATH,name);
647  if(ret < EOK)
648  {
649  ERR_CHK(ret);
650  free(seekfile);
651  return -1;
652  }
653 
654  if (NULL != (fp = fopen(seekfile, "r"))) {
655  /*Coverity Fix CID:18152 CHECKED_RETURN */
656  if( fscanf(fp, "%ld", seek_value) != 1) {
657  LOG("Error in fscanf()\n");
658  }
659 
660  fclose(fp);
661  rc = 0;
662  }
663  free(seekfile);
664  }
665  }
666  return rc;
667 }
668 
669 /**
670  * @brief Function to write the rotated Log file.
671  *
672  * @param[in] name Log file name.
673  * @param[in] seek_value Position to seek.
674  *
675  * @return Returns the status of the operation.
676  * @retval Returns -1 on failure, appropriate errorcode otherwise.
677  */
678 void writeLogSeek(char *name, long seek_value)
679 {
680  errno_t rc = -1;
681  int length = 0;
682  if (NULL != name && NULL != PERSISTENT_PATH) {
683  char *seekfile = NULL;
684  length = strlen(PERSISTENT_PATH) + strlen(name) + 1;
685  seekfile = malloc(length);
686  if (NULL != seekfile) {
687  FILE *fp = NULL;
688  rc = sprintf_s(seekfile,length, "%s%s", PERSISTENT_PATH,name);
689  if(rc< EOK)
690  {
691  ERR_CHK(rc);
692  free(seekfile);
693  return;
694  }
695  if (NULL != (fp = fopen(seekfile, "w"))) {
696  fprintf(fp, "%ld", seek_value);
697  fclose(fp);
698  }
699  free(seekfile);
700  }
701  }
702 }
703 
704 /** @} */ //END OF GROUP DCA_APIS
705 
706 /** @} */
707 
708 
709 /** @} */
710 /** @} */
getLoadAvg
int getLoadAvg()
This API is to find the load average of system and add it to the SearchResult JSON.
Definition: dcautils.c:57
updateConfVal
void updateConfVal(char *logpath, char *perspath)
Function to update the configuration values from device.properties file.
Definition: dcautils.c:491
clearConfVal
void clearConfVal(void)
This function is to clear/free the global paths.
Definition: dcautils.c:101
writeLogSeek
void writeLogSeek(char *name, long seek_value)
Function to write the rotated Log file.
Definition: dcautils.c:678
fsize
static int fsize(FILE *fp)
This function returns file size.
Definition: dcautils.c:85
addToSearchResult
void addToSearchResult(char *key, char *value)
This API is to append the key/value pair to the SearchResult JSON array .
Definition: dcajson.c:71
updateExecCounter
void updateExecCounter()
To update current dca execution count.
Definition: dcautils.c:116
getsRotatedLog
char * getsRotatedLog(char *buf, int buflen, char *name)
Function to return rotated log file.
Definition: dcautils.c:190
isSkipParam
int isSkipParam(int skipInterval)
This API is to verify whether to skip this telemetry marker.
Definition: dcautils.c:163
readLogSeek
int readLogSeek(char *name, long *seek_value)
Function to read the rotated Log file.
Definition: dcautils.c:635
updateIncludeConfVal
void updateIncludeConfVal(char *logpath, char *perspath)
Function to update the global paths like PERSISTENT_PATH,LOG_PATH from include.properties file.
Definition: dcautils.c:397