RDK Documentation (Open Sourced RDK Components)
webconfig_lite.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  * @file webconfig_internal.c
22  *
23  * @description This file describes the webconfig Abstraction Layer
24  *
25  */
26 #include <iostream>
27 #include <cstring>
28 #include <string.h>
29 #include <math.h>
30 #include <time.h>
31 #include <stdio.h>
32 #include <pthread.h>
33 #include "webconfig_lite.h"
34 #include <curl/curl.h>
35 #include "cJSON.h"
36 #include <uuid/uuid.h>
37 #include <webconfig_utils.h>
38 #include <libpd.h>
39 #include <unistd.h>
40 #include "rfcapi.h"
41 #include "safec_lib.h"
42 
43 #ifdef __cplusplus
44 extern "C"
45 {
46 #endif
47 #include <wdmp_internal.h>
48 #ifdef __cplusplus
49 }
50 #endif
51 
52 /*----------------------------------------------------------------------------*/
53 /* Macros */
54 /*----------------------------------------------------------------------------*/
55 /* Macros */
56 #define CURL_TIMEOUT_SEC 25L
57 #define CA_CERT_PATH "/etc/ssl/certs"
58 #define MAX_BUF_SIZE 256
59 #define MAX_HEADER_LEN 4096
60 #define MAX_PARAMETERNAME_LENGTH 512
61 #define WEBPA_READ_HEADER "/etc/parodus/parodus_read_file.sh"
62 #define WEBPA_CREATE_HEADER "/etc/parodus/parodus_create_file.sh"
63 #define BACKOFF_SLEEP_DELAY_SEC 20
64 #define BACKOFF_SLEEP_DELAY_5_SEC 5
65 #define ETAG_HEADER "ETag:"
66 #define BLE_DETECTION_WEBCONFIG_ENDPOINT "https://cpe-config.xdp.comcast.net/api/v1/device/{mac}/config/ble"
67 #define BLE_DETECTION_WEBCONFIG_SUFIX "/ble"
68 #define LOG_TR69HOSTIF "LOG.RDK.TR69HOSTIF"
69 #define CURL_FILE "/tmp/adzvfchig-res.mch"
70 #define CONFIG_VERSION_FILE "/opt/persistent/webconfig_Version"
71 #define MAX_UUID_SIZE 64
72 
73 /*----------------------------------------------------------------------------*/
74 /* Data Structures */
75 /*----------------------------------------------------------------------------*/
76 struct token_data {
77  size_t size;
78  char* data;
79 };
80 
81 typedef struct _notify_params
82 {
83  char * url;
84  long status_code;
85  char * application_status;
86  int application_details;
87  char * request_timestamp;
88  char * version;
89  char * transaction_uuid;
91 
92 typedef struct _tr181Data
93 {
94  //size_t paramCnt;
95  std::string name;
96  std::string value;
97  int datatype;
98 } tr181Data;
99 /*----------------------------------------------------------------------------*/
100 /* File Scoped Variables */
101 /*----------------------------------------------------------------------------*/
102 static char serialNum[64]= {'\0'};
103 char webpa_auth_token[4096]= {'\0'};
104 static char g_ETAG[64]= {'\0'};
105 static char deviceMac[64] = {'\0'};
106 static char *webconfigEndPoint=NULL;
107 tr181Data tr181data;
108 /*----------------------------------------------------------------------------*/
109 /* Function Prototypes */
110 /*----------------------------------------------------------------------------*/
111 static int processJsonDocument(char *jsonData, int *retStatus, char **docVersion);
112 static int validateConfigFormat(cJSON *json, char **eTag);
113 static int requestWebConfigData(char **configData,long *code,char **transaction_id);
114 static void createCurlheader(struct curl_slist *list, struct curl_slist **header_list, char ** trans_uuid);
115 static int parseJsonData(char* jsonData, char **version);
116 static size_t write_callback_fn(void *buffer, size_t size, size_t nmemb, struct token_data *data);
117 static void getAuthToken();
118 static void createNewAuthToken(char *newToken, size_t len, char *hw_mac, char* hw_serial_number);
119 static int handleHttpResponse(long response_code, char *webConfigData, int retry_count,char* transaction_uuid);
120 static char* generate_trans_uuid();
121 static void macToLowerCase(char macValue[]);
122 static void processWebConfigNotification(notify_params_t *n_parm);
123 static void addWebConfigNotifyMsg(char *url, long status_code, char *application_status, int application_details, char *request_timestamp, char *version, char *transaction_uuid);
124 static void free_notify_params_struct(notify_params_t *param);
125 static char *replaceMacWord(const char *s, const char *macW, const char *deviceMACW);
126 static void processWebconfigSync();
127 static size_t header_callback(char *buffer, size_t size, size_t nitems);
128 static void stripSpaces(char *str, char **final_str);
129 
130 /*----------------------------------------------------------------------------*/
131 /* External Functions */
132 /*----------------------------------------------------------------------------*/
133 
134 void parse_set_request(cJSON *request)
135 {
136  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Inside parse set Request \n");
137  cJSON *reqParamObj = NULL,*paramArray = NULL;
138  size_t paramCount, i;
139 
140  paramArray = cJSON_GetObjectItem(request, "parameters");
141 
142  paramCount = cJSON_GetArraySize(paramArray);
143 
144 
145  for (i = 0; i < paramCount; i++)
146  {
147  reqParamObj = cJSON_GetArrayItem(paramArray, i);
148 
149  if(cJSON_GetObjectItem(reqParamObj, "name") != NULL)
150  {
151  tr181data.name = cJSON_GetObjectItem(reqParamObj, "name")->valuestring;
152  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The Name = %s\n",tr181data.name.c_str());
153  }
154  else
155  {
156  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The Name value is NULL \n");
157  }
158 
159  if (cJSON_GetObjectItem(reqParamObj, "value") != NULL )
160  {
161  if(cJSON_GetObjectItem(reqParamObj, "value")->valuestring != NULL)
162  {
163  tr181data.value = cJSON_GetObjectItem(reqParamObj, "value")->valuestring;
164  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The param value =%s \n",tr181data.value.c_str());
165  }
166  else
167  {
168  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Parameter value field is not a string \n");
169  }
170  }
171 
172  if (cJSON_GetObjectItem(reqParamObj, "dataType") != NULL)
173  {
174  tr181data.datatype = cJSON_GetObjectItem(reqParamObj, "dataType")->valueint;
175  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The data Type = %d \n", tr181data.datatype);
176  }
177  }
178 
179 }
180 
181 
182 void * initWebConfigTask(void *)
183 {
184  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: [%s] %d **** Entering webconfig task thread ****** \n", __FUNCTION__, __LINE__);
185 
186  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:**** calling processWebconfigSync ****** \n");
187 
188  processWebconfigSync();
189 
190  if(webconfigEndPoint != NULL)
191  {
192  WAL_FREE(webconfigEndPoint);
193  }
194  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:**** End of webconfig task thread ****** \n");
195  pthread_detach(pthread_self());
196 }
197 
198 static void processWebconfigSync()
199 {
200  int retry_count=0;
201  int configRet = -1;
202  char *webConfigData = NULL;
203  long res_code;
204  int rv=0,ret=ERR;
205  char *transaction_uuid =NULL;
206 
207  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:========= Start of processWebconfigSync ============= \n");
208  while(1)
209  {
210  if(retry_count > 25)
211  {
212  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:retry_count has reached max limit. Exiting.\n");
213  retry_count=0;
214  break;
215  }
216  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Checking for MAC address in Device file Cache \n");
217  ret = getKeyValue("estb_mac", deviceMac);
218  if(ret==SUCCESS)
219  {
220  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:***** calling requestWebConfigData ***** \n");
221  configRet = requestWebConfigData(&webConfigData, &res_code, &transaction_uuid);
222  if(configRet == SUCCESS)
223  {
224  rv = handleHttpResponse(res_code, webConfigData, retry_count, transaction_uuid);
225  }
226  else
227  {
228  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to get webConfigData from cloud\n");
229  }
230  if(webConfigData != NULL)
231  {
232  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:=========Delete webconfig data =============\n");
233  WAL_FREE(webConfigData);
234  }
235  if(transaction_uuid != NULL)
236  {
237  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:=========transaction_uuid =============\n");
238  WAL_FREE(transaction_uuid);
239  }
240  if(rv == SUCCESS)
241  {
242  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:No retries are required. Exiting..\n");
243  break;
244  }
245 
246  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:requestWebConfigData BACKOFF_SLEEP_DELAY_SEC is %d seconds\n", BACKOFF_SLEEP_DELAY_SEC);
247  }
248  else
249  {
250  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: MAC address not populated yet in Device file Cache BACKOFF_SLEEP_DELAY_SEC is %d seconds\n", BACKOFF_SLEEP_DELAY_SEC);
251  }
252  sleep(BACKOFF_SLEEP_DELAY_SEC);
253  retry_count++;
254  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Webconfig retry_count is %d\n", retry_count);
255  }
256 
257  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:========= End of processWebconfigSync =============\n");
258  return;
259 }
260 
261 static int handleHttpResponse(long response_code, char *webConfigData, int retry_count, char* transaction_uuid)
262 {
263  int first_digit=0;
264  int json_status=0;
265  int setRet = 0;
266  char configVersion[MAX_BUF_SIZE] = {'\0'};
267  char *newDocVersion = NULL;
268  time_t current_time;
269  char currentTime[32];
270  current_time = time(NULL);
271  snprintf(currentTime,sizeof(currentTime),"%d",(int)current_time);
272  //read the configversion from /opt/data
273 
274  FILE *ConfigFilePtr = NULL;
275  /*write the configVersion/docVersion to the file "/opt/persistent/webconfig_Version"*/
276  if(ConfigFilePtr = fopen(CONFIG_VERSION_FILE,"r"))
277  {
278 
279  fread(configVersion, MAX_BUF_SIZE, 1, ConfigFilePtr);
280  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"The config version file exists with value =%s \n",configVersion);
281  fclose(ConfigFilePtr);
282  }
283 
284  if(response_code == 304)
285  {
286  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfig is in sync with cloud. response_code:%d\n", response_code);
287  addWebConfigNotifyMsg(webconfigEndPoint, response_code, NULL, 0, currentTime , configVersion, transaction_uuid);
288  return SUCCESS;
289  }
290  else if(response_code == 200)
291  {
292  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfig is not in sync with cloud. response_code:%d\n", response_code);
293 
294  if(webConfigData !=NULL)
295  {
296  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfigData fetched successfully\n");
297  json_status = processJsonDocument(webConfigData, &setRet, &newDocVersion);
298  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:setRet after process Json is %d\n", setRet);
299  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:newDocVersion is %s\n", newDocVersion);
300  if(json_status == SUCCESS)
301  {
302  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:processJsonDocument success\n");
303  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The transcation UUID =%s \n",transaction_uuid);
304  addWebConfigNotifyMsg(webconfigEndPoint, response_code, "success", setRet, currentTime , newDocVersion, transaction_uuid);
305  }
306  else
307  {
308  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failure in processJsonDocument\n");
309  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Configuration settings version %s FAILED\n", newDocVersion );
310  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Sending Webconfig apply Failure Notification\n");
311  addWebConfigNotifyMsg(webconfigEndPoint, response_code, "failed", setRet, currentTime , newDocVersion, transaction_uuid);
312  }
313  if(newDocVersion != NULL)
314  {
315  WAL_FREE(newDocVersion);
316  }
317  return SUCCESS;
318  }
319  else
320  {
321  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfigData is empty, need to retry\n");
322  }
323  }
324  else if(response_code == 204)
325  {
326  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:No configuration available for this device. response_code:%d\n", response_code);
327  addWebConfigNotifyMsg(webconfigEndPoint, response_code, NULL, 0, currentTime , configVersion, transaction_uuid);
328  return SUCCESS;
329  }
330  else if(response_code == 403)
331  {
332  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Token is expired, fetch new token. response_code:%d\n", response_code);
333  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The device mac =%s \n",deviceMac);
334  createNewAuthToken(webpa_auth_token, sizeof(webpa_auth_token), deviceMac, serialNum );
335  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:createNewAuthToken done in 403 case\n");
336  //retun error based on retry count at the end of the function
337  }
338  else if(response_code == 404)
339  {
340  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Action not supported. response_code:%d\n", response_code);
341  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: Something went wrong on the device side re try again \n");
342  //addWebConfigNotifyMsg(webconfigEndPoint, response_code, NULL, 0, currentTime , configVersion, transaction_uuid);
343  return ERR;
344 
345  }
346  else if(response_code == 429)
347  {
348  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:No action required from client. response_code:%d\n", response_code);
349  return SUCCESS;
350  }
351  first_digit = (int)(response_code / pow(10, (int)log10(response_code)));
352  if((response_code !=403) && (first_digit == 4)) //4xx
353  {
354  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Action not supported. response_code:%d\n", response_code);
355  addWebConfigNotifyMsg(webconfigEndPoint, response_code, NULL, 0, currentTime , configVersion, transaction_uuid);
356  return SUCCESS;
357  }
358  else //5xx & all other errors
359  {
360  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Error code returned, need to retry. response_code:%d\n", response_code);
361  if(retry_count >= 25 )
362  {
363  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Sending Notification after %d retry attempts\n",retry_count);
364  addWebConfigNotifyMsg(webconfigEndPoint, response_code, NULL, 0, currentTime , configVersion, transaction_uuid);
365  return ERR;
366  }
367  }
368  return ERR;
369 }
370 
371 /*
372  * @brief Initialize curl object with required options. create configData using libcurl.
373  * @param[out] configData
374  * @param[in] len total configData size
375  * @param[in] r_count Number of curl retries on ipv4 and ipv6 mode during failure
376  * @return returns 0 if success, otherwise failed to fetch auth token and will be retried.
377  */
378 static int requestWebConfigData(char **configData, long *code, char **transaction_id)
379 {
380  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: **** inside requestWebConfigData***** \n");
381  CURL *curl;
382  CURLcode res;
383  CURLcode time_res;
384  struct curl_slist *list = NULL;
385  struct curl_slist *headers_list = NULL;
386  double total;
387  long response_code = 0;
388  char *ct = NULL;
389  char *transID = NULL;
390  int content_res=0;
391  struct token_data data;
392  data.size = 0;
393  char c[] = "{mac}";
394  errno_t rc = -1;
395  void * dataVal = NULL;
396  curl = curl_easy_init();
397  if(curl)
398  {
399  //this memory will be dynamically grown by write call back fn as required
400  data.data = (char *) malloc(sizeof(char) * 1);
401  if(NULL == data.data)
402  {
403  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to allocate memory.\n");
404  return ERR;
405  }
406  data.data[0] = '\0';
407  createCurlheader(list, &headers_list, &transID);
408  if(transID !=NULL)
409  {
410  *transaction_id = strdup(transID);
411  WAL_FREE(transID);
412  }
413 
414  char endPoint[128] = {'\0'};
415  //Replace {mac} string from default init url with actual deviceMAC
416  RFC_ParamData_t param = {0};
417  WDMP_STATUS status = getRFCParameter((char*)"webcfg", "Device.X_RDK_WebConfig.URL", &param);
418 
419  if (status == WDMP_SUCCESS) {
420  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webcfg: name = %s, type = %d, value = %s\n", param.name, param.type, param.value);
421  rc=strcpy_s(endPoint,sizeof(param.value) ,param.value);
422  if(rc==EOK)
423  {
424  rc=strcat_s(endPoint,strlen(BLE_DETECTION_WEBCFG_ENDPOINT),BLE_DETECTION_WEBCFG_ENDPOINT);
425  }
426  if(rc==EOK)
427  {
428  webconfigEndPoint = replaceMacWord(endPoint, c, deviceMac);
429  }
430  }
431 
432  if(status != WDMP_SUCCESS || rc!=EOK)
433  {
434  webconfigEndPoint = replaceMacWord(BLE_DETECTION_WEBCONFIG_ENDPOINT, c, deviceMac);
435  }
436 
437 
438  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfigURL is %s \n", webconfigEndPoint);
439  curl_easy_setopt(curl, CURLOPT_URL, webconfigEndPoint );
440  curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT_SEC);
441 
442  // set callback for writing received data
443  dataVal = &data;
444  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback_fn);
445  curl_easy_setopt(curl, CURLOPT_WRITEDATA, dataVal);
446 
447  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_list);
448 
449  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Set CURLOPT_HEADERFUNCTION option\n");
450  curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
451 
452  // setting curl resolve option as default mode.
453  //If any failure, retry with v4 first and then v6 mode.
454  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:curl Ip resolve option set as default mode\n");
455  curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
456  curl_easy_setopt(curl, CURLOPT_CAPATH, CA_CERT_PATH);
457  // disconnect if it is failed to validate server's cert
458  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
459  // Verify the certificate's name against host
460  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
461  // To use TLS version 1.2 or later
462  curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
463  // To follow HTTP 3xx redirections
464  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
465  // Perform the request, res will get the return code
466  res = curl_easy_perform(curl);
467  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
468  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webConfig curl response %d http_code %d\n", res, response_code);
469  *code = response_code;
470  time_res = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total);
471  if(time_res == 0)
472  {
473  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:curl response Time: %.1f seconds\n", total);
474  }
475  curl_slist_free_all(headers_list);
476  if(res != 0)
477  {
478  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
479  }
480  else
481  {
482  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:checking content type\n");
483  content_res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
484  if(!content_res && ct)
485  {
486  if(strcmp(ct, "application/json") !=0)
487  {
488  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Invalid Content-Type\n");
489  }
490  else if(response_code == 200)
491  {
492  *configData = strdup(data.data);
493  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:configData received from cloud is %s\n", *configData);
494  }
495  }
496  }
497  WAL_FREE(data.data);
498  curl_easy_cleanup(curl);
499  return SUCCESS;
500  }
501  else
502  {
503  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:curl init failure\n");
504  }
505  return ERR;
506 }
507 
508 /* @brief callback function for writing libcurl received data
509  * @param[in] buffer curl delivered data which need to be saved.
510  * @param[in] size size is always 1
511  * @param[in] nmemb size of delivered data
512  * @param[out] data curl response data saved.
513  */
514 static size_t write_callback_fn(void *buffer, size_t size, size_t nmemb, struct token_data *data)
515 {
516  size_t index = data->size;
517  size_t n = (size * nmemb);
518  char* tmp;
519  errno_t safec_rc = -1;
520 
521  data->size += (size * nmemb);
522 
523  tmp = (char *)realloc(data->data, data->size + 1); // +1 for '\0'
524 
525  if(tmp) {
526  data->data = tmp;
527  } else {
528  if(data->data) {
529  WAL_FREE(data->data);
530  }
531  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to allocate memory for data\n");
532  return 0;
533  }
534 
535  safec_rc=memcpy_s((data->data + index),sizeof(data->data)-index, buffer, n);
536  if(safec_rc!=EOK)
537  {
538  ERR_CHK(safec_rc);
539  }
540  data->data[data->size] = '\0';
541 
542  return size * nmemb;
543 }
544 
545 /* @brief callback function to extract response header data.
546 */
547 static size_t header_callback(char *buffer, size_t size, size_t nitems)
548 {
549  size_t etag_len = 0;
550  char* header_value = NULL;
551  char* final_header = NULL;
552  char header_str[64] = {'\0'};
553  //int i=0, j=0;
554 
555  etag_len = strlen(ETAG_HEADER);
556  if( nitems > etag_len )
557  {
558  if( strncasecmp(ETAG_HEADER, buffer, etag_len) == 0 )
559  {
560  header_value = strtok(buffer, ":");
561  while( header_value != NULL )
562  {
563  header_value = strtok(NULL, ":");
564  if(header_value !=NULL)
565  {
566  strncpy(header_str, header_value, sizeof(header_str)-1);
567  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:header_str is %s\n", header_str);
568  stripSpaces(header_str, &final_header);
569 
570  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:final_header is %s len %lu\n", final_header, strlen(final_header));
571  strncpy(g_ETAG, final_header, sizeof(g_ETAG)-1);
572  }
573  }
574  }
575  }
576  return nitems;
577 }
578 
579 //To strip all spaces , new line & carriage return characters from header output
580 static void stripSpaces(char *str, char **final_str)
581 {
582  int i=0, j=0;
583 
584  for(i=0; str[i]!='\0'; ++i)
585  {
586  if(str[i]!=' ')
587  {
588  if(str[i]!='\n')
589  {
590  if(str[i]!='\r')
591  {
592  str[j++]=str[i];
593  }
594  }
595  }
596  }
597  str[j]='\0';
598  *final_str = str;
599 }
600 
601 static int processJsonDocument(char *jsonData, int *retStatus, char **docVersion)
602 {
603  int parseStatus = 0;
604  char *version = NULL;
605  std:: string command;
606  int exitstatus;
607 
608  parseStatus = parseJsonData(jsonData, &version);
609  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:After parseJsonData version is %s\n", version);
610  if(version!=NULL)
611  {
612  *docVersion = strdup(version);
613  FILE *ConfigFilePtr = NULL;
614  /*write the configVersion/docVersion to the file "/opt/persistent/webconfig_Version"*/
615  if(ConfigFilePtr = fopen(CONFIG_VERSION_FILE,"w"))
616  {
617  fwrite(version, strlen(version), 1, ConfigFilePtr);
618  fclose(ConfigFilePtr);
619  }
620  else
621  {
622  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: FAILED opening </opt/persistent/webconfig_Version> configVersion file \n");
623  }
624  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:docVersion is %s\n", *docVersion);
625  WAL_FREE(version);
626  }
627  if(parseStatus ==1)
628  {
629  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: ****webconfig set Request **** \n");
630  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The param name =%s \n",tr181data.name.c_str());
631  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The param value =%s \n",tr181data.value.c_str());
632  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The param dataType =%d \n",tr181data.datatype);
633  DATA_TYPE data_type = (DATA_TYPE)tr181data.datatype;
634 
635  WDMP_STATUS rfcStatus = setRFCParameter((char*)"webconfig",tr181data.name.c_str() , tr181data.value.c_str(), data_type);
636 
637  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The setRFCParameter return = %s \n",rfcStatus);
638 
639  return (WDMP_SUCCESS == rfcStatus)? SUCCESS : ERR;
640  }
641  else
642  {
643  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:parseJsonData failed. parseStatus is %d\n", parseStatus);
644  return ERR;
645  }
646 }
647 
648 static int parseJsonData(char* jsonData, char **version)
649 {
650  cJSON *json = NULL;
651  int isValid =0;
652  int rv =-1;
653  char *configVersion= NULL;
654 
655  if((jsonData !=NULL) && (strlen(jsonData)>0))
656  {
657  json = cJSON_Parse(jsonData);
658 
659  if( json != NULL )
660  {
661  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:WebConfig Parse successi \n");
662  isValid = validateConfigFormat(json, &configVersion);
663  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:configVersion is %s\n", configVersion);
664  if(configVersion !=NULL)
665  {
666  *version = strdup(configVersion);
667  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:version copied from configVersion is %s\n", *version);
668  WAL_FREE(configVersion);
669  }
670  if(!isValid)
671  {
672  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:validateConfigFormat failed\n");
673  return rv;
674  }
675  parse_set_request(json);
676  cJSON_Delete(json);
677  rv = 1;
678  }
679  else
680  {
681  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:****Error parsing Json data **** \n");
682  }
683  }
684  else
685  {
686  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:jsonData is empty\n");
687  }
688  return rv;
689 }
690 
691 static int validateConfigFormat(cJSON *json, char **eTag)
692 {
693  cJSON *versionObj =NULL;
694  cJSON *paramArray = NULL;
695  int itemSize=0;
696  char *jsonversion=NULL;
697 
698  versionObj = cJSON_GetObjectItem( json, "version" );
699  if(versionObj !=NULL)
700  {
701  if(cJSON_GetObjectItem( json, "version" )->type == cJSON_String)
702  {
703  jsonversion = cJSON_GetObjectItem( json, "version" )->valuestring;
704  if(jsonversion !=NULL)
705  {
706  //version & eTag header validation
707  if(strlen(g_ETAG)>0)
708  {
709  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:jsonversion :%s len %lu\n", jsonversion, strlen(jsonversion));
710  if(strncmp(jsonversion, g_ETAG, strlen(g_ETAG)) == 0)
711  {
712  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Config Version and ETAG header are matching\n");
713  *eTag = strdup(jsonversion);
714  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:eTag is %s\n", *eTag);
715  //check parameters
716  paramArray = cJSON_GetObjectItem( json, "parameters" );
717  if( paramArray != NULL )
718  {
719  itemSize = cJSON_GetArraySize( json );
720  if(itemSize ==2)
721  {
722  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Config document format is valid\n");
723  return 1;
724  }
725  else
726  {
727  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:config contains fields other than version and parameters\n");
728  return 0;
729  }
730  }
731  else
732  {
733  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Invalid config json, parameters field is not present\n");
734  return 0;
735  }
736  }
737  else
738  {
739  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Invalid config json, version & ETAG are not same\n");
740  return 0;
741  }
742  }
743  else
744  {
745  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to fetch ETAG header from config response\n");
746  return 0;
747  }
748  }
749  }
750  }
751  else
752  {
753  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Invalid config json, version field is not present\n");
754  return 0;
755  }
756 
757  return 0;
758 }
759 
760 
761 /* @brief Function to create curl header options
762  * @param[in] list temp curl header list
763  * @param[in] device status value
764  * @param[out] header_list output curl header list
765  */
766 static void createCurlheader( struct curl_slist *list, struct curl_slist **header_list, char ** trans_uuid)
767 {
768  time_t current_time;
769  char currentTime[32];
770  char *transaction_uuid = NULL;
771  char current_version[MAX_BUF_SIZE] = {0};
772  FILE *ConfigFilePtr = NULL;
773  char auth_header[MAX_HEADER_LEN] = {0};
774  char version_header[MAX_BUF_SIZE] = {0};
775  char schema_header[MAX_BUF_SIZE] = {0};
776  char currentTime_header[MAX_BUF_SIZE] = {0};
777  char uuid_header[MAX_BUF_SIZE] = {0};
778 
779  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Start of createCurlheader\n");
780  //Fetch auth JWT token from cloud.
781  getAuthToken();
782 
783  // auth_header
784  snprintf(auth_header, MAX_HEADER_LEN, "Authorization:Bearer %s", (0 < strlen(webpa_auth_token) ? webpa_auth_token : NULL));
785  list = curl_slist_append(list, auth_header);
786 
787  //version_header
788  if(ConfigFilePtr = fopen(CONFIG_VERSION_FILE,"r"))
789  {
790  fread(current_version, MAX_BUF_SIZE, 1, ConfigFilePtr);
791  if(strlen(current_version)!=0)
792  {
793  snprintf(version_header, MAX_BUF_SIZE, "IF-NONE-MATCH:%s", current_version);
794  }
795  else
796  {
797  snprintf(version_header, MAX_BUF_SIZE, "IF-NONE-MATCH:%s", "NONE");
798  }
799  fclose(ConfigFilePtr);
800  }
801  else
802  {
803  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: FAILED opening </opt/persistent/webconfig_Version> configVersion file \n");
804  snprintf(version_header, MAX_BUF_SIZE, "IF-NONE-MATCH:%s", "NONE");
805  }
806  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:version_header formed %s\n", version_header);
807  list = curl_slist_append(list, version_header);
808 
809 
810  //schema_header
811  snprintf(schema_header, MAX_BUF_SIZE, "Schema-Version: %s", "v1.0");
812  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:schema_header formed %s\n", schema_header);
813  list = curl_slist_append(list, schema_header);
814 
815 
816  memset(currentTime, 0, sizeof(currentTime));
817  current_time = time(NULL);
818  snprintf(currentTime,sizeof(currentTime),"%d",(int)current_time);
819  //currentTime_header
820  snprintf(currentTime_header, MAX_BUF_SIZE, "X-System-Current-Time: %s", currentTime);
821  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:currentTime_header formed %s\n", currentTime_header);
822  list = curl_slist_append(list, currentTime_header);
823  if(transaction_uuid == NULL)
824  {
825  transaction_uuid = generate_trans_uuid();
826  }
827 
828  if(transaction_uuid !=NULL)
829  {
830  //uuid_header
831  snprintf(uuid_header, MAX_BUF_SIZE, "Transaction-ID: %s", transaction_uuid);
832  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:uuid_header formed %s\n", uuid_header);
833  list = curl_slist_append(list, uuid_header);
834  *trans_uuid = strdup(transaction_uuid);
835  WAL_FREE(transaction_uuid);
836  }
837  else
838  {
839  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to generate transaction_uuid\n");
840  }
841  *header_list = list;
842 }
843 
844 static char* generate_trans_uuid()
845 {
846  char *transID = NULL;
847  uuid_t transaction_Id;
848  char *trans_id = NULL;
849  trans_id = (char *)malloc(MAX_UUID_SIZE);
850  uuid_generate_random(transaction_Id);
851  uuid_unparse(transaction_Id, trans_id);
852 
853  if(trans_id !=NULL)
854  {
855  transID = trans_id;
856  }
857  return transID;
858 }
859 
860 static void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum)
861 {
862  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: ****Inside execute token script**** \n");
863  FILE* out = NULL, *file = NULL;
864  char command[MAX_BUF_SIZE] = {'\0'};
865  if(strlen(name)>0)
866  {
867  file = fopen(name, "r");
868  if(file)
869  {
870  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Runn the commannd \n");
871  snprintf(command,sizeof(command),"%s %s %s",name,serNum,mac);
872  out = popen(command, "r");
873  if(out)
874  {
875  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Read the token \n");
876  fgets(token, len, out);
877  RDK_LOG(RDK_LOG_DEBUG, LOG_TR69HOSTIF,"webconfig_lite:Token =%s \n",token);
878  pclose(out);
879  }
880  fclose(file);
881  }
882  else
883  {
884  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"File %s open error\n", name);
885  }
886  }
887 }
888 
889 /*
890  * call parodus create/acquisition script to create new auth token, if success then calls
891  * execute_token_script func with args as parodus read script.
892  */
893 
894 static void createNewAuthToken(char *newToken, size_t len, char *hw_mac, char* hw_serial_number)
895 {
896  int token_retry_count=0;
897 
898  while(1)
899  {
900  if(( access( CURL_FILE, F_OK ) != -1 ))
901  {
902  //Call create script
903  char output[12] = {'\0'};
904  execute_token_script(output,WEBPA_CREATE_HEADER,sizeof(output),hw_mac,hw_serial_number);
905  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:***** inside create New Auth Token ***** \n");
906  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:**** the outout string =%s and lenngth =%d *** \n",output,strlen(output));
907  if (strlen(output)>0 && strcmp(output,"SUCCESS")==0)
908  {
909  //Call read script
910  execute_token_script(newToken,WEBPA_READ_HEADER,len,hw_mac,hw_serial_number);
911  }
912  else
913  {
914  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to create new token\n");
915  }
916  /*no retries are required*/
917  break;
918  }
919  else
920  {
921  // file doesn't exist
922  if(token_retry_count >60)
923  {
924  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:token_retry_count has reached max limit. Exiting.\n");
925  //token_retry_count=0;
926  break;
927  }
928  sleep(BACKOFF_SLEEP_DELAY_5_SEC);
929  token_retry_count++;
930  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Webconfig token_retry_count is %d\n", token_retry_count);
931  }
932 
933  }
934 
935 }
936 
937 /*
938  * Fetches authorization token from the output of read script. If read script returns "ERROR"
939  * it will call createNewAuthToken to create and read new token
940  */
941 
942 static void getAuthToken()
943 {
944  //local var to update webpa_auth_token only in success case
945  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:****Inside of getAuthToken ***** \n");
946  char output[4069] = {'\0'};
947  memset (webpa_auth_token, 0, sizeof(webpa_auth_token));
948 
949  if( strlen(WEBPA_READ_HEADER) !=0 && strlen(WEBPA_CREATE_HEADER) !=0)
950  {
951  execute_token_script(output, WEBPA_READ_HEADER, sizeof(output), deviceMac, serialNum);
952  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The OutPut =%s \n",output);
953  if ((strlen(output) == 0))
954  {
955  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Unable to get auth token\n");
956  }
957  else if(strcmp(output,"ERROR")==0)
958  {
959  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Failed to read token from %s. Proceeding to create new token.\n",WEBPA_READ_HEADER);
960  //Call create/acquisition script
961  createNewAuthToken(webpa_auth_token, sizeof(webpa_auth_token), deviceMac, serialNum );
962  }
963  else
964  {
965  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:update webpa_auth_token in success case\n");
966  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:The Aut Token =%s \n",output);
967  //walStrncpy(webpa_auth_token, output, sizeof(webpa_auth_token));
968  strncpy(webpa_auth_token, output, (sizeof(webpa_auth_token)-1));
969  }
970 
971  }
972  else
973  {
974  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Both read and write file are NULL \n");
975  }
976 }
977 
978 
979 static void addWebConfigNotifyMsg(char *url, long status_code, char *application_status, int application_details, char *request_timestamp, char *version, char *transaction_uuid)
980 {
981  notify_params_t *args = NULL;
982  args = (notify_params_t *)malloc(sizeof(notify_params_t));
983 
984  if(args != NULL)
985  {
986  memset(args, 0, sizeof(notify_params_t));
987  if(url != NULL)
988  {
989  args->url = strdup(url);
990  }
991  args->status_code = status_code;
992  if(application_status != NULL)
993  {
994  args->application_status = strdup(application_status);
995  }
996  args->application_details = application_details;
997  if(request_timestamp != NULL)
998  {
999  args->request_timestamp = strdup(request_timestamp);
1000  }
1001  if(version != NULL)
1002  {
1003  args->version = strdup(version);
1004  }
1005  if(transaction_uuid != NULL)
1006  {
1007  args->transaction_uuid = strdup(transaction_uuid);
1008  }
1009  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:args->url:%s args->status_code:%d \
1010  args->application_status:%s args->application_details:%d args->request_timestamp:%s\
1011  args->version:%s args->transaction_uuid:%s\n", args->url, args->status_code,\
1012  args->application_status, args->application_details, args->request_timestamp,\
1013  args->version, args->transaction_uuid );
1014 
1015  processWebConfigNotification(args);
1016  }
1017 }
1018 
1019 //Notify thread function waiting for notify msgs
1020 static void processWebConfigNotification(notify_params_t *n_param)
1021 {
1022  char device_id[32] = { '\0' };
1023  cJSON *notifyPayload = NULL;
1024  char * stringifiedNotifyPayload = NULL;
1025  char dest[512] = {'\0'};
1026  char source[MAX_BUF_SIZE] = {0};
1027  cJSON * reports, *one_report;
1028 
1029  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: Entering processWebConfigNotification\n");
1030  if(n_param !=NULL)
1031  {
1032  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:Processing msg\n");
1033  snprintf(device_id, sizeof(device_id), "mac:%s", deviceMac);
1034  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:webconfig Device_id %s\n", device_id);
1035 
1036  notifyPayload = cJSON_CreateObject();
1037 
1038  if(notifyPayload != NULL)
1039  {
1040  cJSON_AddStringToObject(notifyPayload,"device_id", device_id);
1041 
1042  cJSON_AddItemToObject(notifyPayload, "reports", reports = cJSON_CreateArray());
1043  cJSON_AddItemToArray(reports, one_report = cJSON_CreateObject());
1044  cJSON_AddStringToObject(one_report, "url", (NULL != n_param->url) ? n_param->url : "unknown");
1045  cJSON_AddNumberToObject(one_report,"http_status_code", n_param->status_code);
1046  if(n_param->status_code == 200)
1047  {
1048  cJSON_AddStringToObject(one_report,"document_application_status", (NULL != n_param->application_status) ? n_param->application_status : "unknown");
1049  cJSON_AddNumberToObject(one_report,"document_application_details", n_param->application_details);
1050  }
1051  cJSON_AddNumberToObject(one_report, "request_timestamp", (NULL != n_param->request_timestamp) ? atoi(n_param->request_timestamp) : 0);
1052  cJSON_AddStringToObject(one_report,"version", (NULL != n_param->version && (strlen(n_param->version)!=0)) ? n_param->version : "NONE");
1053  cJSON_AddStringToObject(one_report,"transaction_uuid", (NULL != n_param->transaction_uuid && (strlen(n_param->transaction_uuid)!=0)) ? n_param->transaction_uuid : "unknown");
1054  stringifiedNotifyPayload = cJSON_PrintUnformatted(notifyPayload);
1055  cJSON_Delete(notifyPayload);
1056  }
1057 
1058  snprintf(dest,sizeof(dest),"event:config-version-report/%s",device_id);
1059  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:dest is %s\n", dest);
1060 
1061  if (stringifiedNotifyPayload != NULL && strlen(device_id) != 0)
1062  {
1063  strncpy(source, device_id, sizeof(device_id));
1064  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:source is %s\n", source);
1065  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite:stringifiedNotifyPayload is %s\n", stringifiedNotifyPayload);
1066  sendNotification(stringifiedNotifyPayload, source, dest);
1067  }
1068  if(n_param != NULL)
1069  {
1070  free_notify_params_struct(n_param);
1071  }
1072  }
1073  else
1074  {
1075  RDK_LOG(RDK_LOG_INFO, LOG_TR69HOSTIF,"webconfig_lite: n_param is NULL\n");
1076  }
1077 
1078 }
1079 
1080 static void free_notify_params_struct(notify_params_t *param)
1081 {
1082  if(param != NULL)
1083  {
1084  if(param->url != NULL)
1085  {
1086  WAL_FREE(param->url);
1087  }
1088  if(param->application_status != NULL)
1089  {
1090  WAL_FREE(param->application_status);
1091  }
1092  if(param->request_timestamp != NULL)
1093  {
1094  WAL_FREE(param->request_timestamp);
1095  }
1096  if(param->version != NULL)
1097  {
1098  WAL_FREE(param->version);
1099  }
1100  if(param->transaction_uuid != NULL)
1101  {
1102  WAL_FREE(param->transaction_uuid);
1103  }
1104  WAL_FREE(param);
1105  }
1106 }
1107 
1108 static char *replaceMacWord(const char *s, const char *macW, const char *deviceMACW)
1109 {
1110  char *result;
1111  int i, cnt = 0;
1112  int temp_var;
1113  int deviceMACWlen = strlen(deviceMACW);
1114  int macWlen = strlen(macW);
1115  // Counting the number of times mac word occur in the string
1116  for (i = 0; s[i] != '\0'; i++)
1117  {
1118  if (strstr(&s[i], macW) == &s[i])
1119  {
1120  cnt++;
1121  // Jumping to index after the mac word.
1122  i += macWlen - 1;
1123  }
1124  }
1125 
1126  result = (char *)malloc(i + cnt * (deviceMACWlen - macWlen) + 1);
1127  temp_var=(i + cnt * (deviceMACWlen - macWlen) + 1);
1128  i = 0;
1129  while (*s)
1130  {
1131  if (strstr(s, macW) == s)
1132  {
1133  errno_t rc = -1;
1134  rc=strcpy_s(&result[i],(temp_var - i), deviceMACW);
1135  if(rc!=EOK)
1136  {
1137  ERR_CHK(rc);
1138  }
1139  i += deviceMACWlen;
1140  s += macWlen;
1141  }
1142  else
1143  result[i++] = *s++;
1144  }
1145  result[i] = '\0';
1146  return result;
1147 }
libpd.h
_notify_params
Definition: hostIf_NotificationHandler.cpp:43
RDK_LOG
#define RDK_LOG
Definition: rdk_debug.h:258
header_callback
static size_t header_callback(const char *ptr, size_t size, size_t nmemb, void *user_data)
callback invoked on http header by curl
Definition: AampCurlStore.cpp:141
sendNotification
void sendNotification(char *payload, char *source, char *destination)
Definition: libpd.cpp:225
_tr181Data
Definition: webconfig_lite.cpp:92
webconfig_utils.h
token_data
Definition: webconfig_lite.cpp:76