RDK Documentation (Open Sourced RDK Components)
xdiscovery.c
Go to the documentation of this file.
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  * @file xdiscovery.c
21  * @brief This source file contains functions that will run as task for maintaining the device list.
22  */
23 #ifndef _GNU_SOURCE
24  #define _GNU_SOURCE
25 #endif
26 #include <libgupnp/gupnp-control-point.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <libgssdp/gssdp.h>
30 #include <ifaddrs.h>
31 #include <arpa/inet.h>
32 #include <sys/ioctl.h>
33 #include <net/if.h>
34 #include <sys/ipc.h>
35 #include <sys/shm.h>
36 #include <sys/stat.h>
37 #include <errno.h>
38 #include <signal.h>
39 #include "xdiscovery.h"
40 #include "xdiscovery_private.h"
41 #include "secure_wrapper.h"
42 #include <glib/gprintf.h>
43 #include <string.h>
44 #include <glib/gstdio.h>
45 #ifdef INCLUDE_BREAKPAD
46 #include "breakpad_wrapper.h"
47 #endif
48 #ifndef BROADBAND
49 #ifdef ENABLE_RFC
50 #include "rfcapi.h"
51 #endif
52 #else
53 #include <platform_hal.h>
54 #endif
55 #if defined(CLIENT_XCAL_SERVER) && !defined(BROADBAND)
56 #include "mfrMgr.h"
57 #endif
58 int gatewayDetected=0;
59 gboolean partialDiscovery=FALSE;
60 #include "rdk_safeclib.h"
61 
62 #ifdef LOGMILESTONE
63 #include "rdk_logger_milestone.h"
64 #endif
65 
66 #ifdef BROADBAND
67 #include <syscfg/syscfg.h>
68 #endif
69 #include <libsoup/soup.h>
70 
71 #ifdef GUPNP_GENERIC_MEDIA_RENDERER
72 #include "mediabrowser_private.h"
73 #endif //GUPNP_GENERIC_MEDIA_RENDERER
74 
75 #define OUTPLAYURL_SIZE 180 //current max size of playbackurl with ocap locator is 145 adding few more just to accomdate future increase in receiver id or ipv6.
76 
77 #define DEVICE_PROTECTION_CONTEXT_PORT 50760
78 
79 #define ACCOUNTID_SIZE 30
80 
81 #define MILESTONE_LOG_FILENAME "/opt/logs/rdk_milestones.log"
82 
83 //Symbols defined in makefile (via defs.mk)
84 //#define USE_XUPNP_IARM
85 //#define GUPNP_0_19
86 //#define GUPNP_0_14
87 const char* localHostIP="127.0.0.1";
88 static int rfc_enabled ;
89 #if !defined(BROADBAND)
90 #define RESTART_XDISCOVERY_FILE "/tmp/restartedXdiscovery"
91 #endif
92 
93 #ifdef BROADBAND
94 #define WEBGUI_VIDEO_ANAL_FILE "/tmp/videoanalytic_started"
95 #endif
96 
97 static GMainLoop *main_loop;
98 gboolean checkDevAddInProgress=FALSE;
99 #define WAIT_TIME_SEC 5
100 #define PNAME "/tmp/xpki_cert"
101 #define PID 21699
102 #define SHM_EXISTS 17
103 guint deviceAddNo=0;
104 int getSoupStatusFromUrl(char* url);
105 
106 #ifdef SAFEC_DUMMY_API
107 //adding strcmp_s defination
108 errno_t strcmp_s(const char * d,int max ,const char * src,int *r)
109 {
110  *r= strcmp(d,src);
111  return EOK;
112 }
113 #endif
114 char *cert_File=NULL;
115 char *key_File=NULL;
116 char *ca_File="/tmp/UPnP_CA";
117 char accountId[ACCOUNTID_SIZE]={'\0',};
118 
119 #ifdef BROADBAND
120 // shared memory id for sharing white list
121 // with mrd
122 static int shmId;
123 DEF_FIFO(dp_wlist_fifo,MAX_OVERFLOW, unsigned int);
124 dp_wlist_t *dp_wlist=NULL;
125 dp_wlist_ss_t dpnode_insert(long ipaddr, char *macaddr);
126 #endif
127 
128 typedef GTlsInteraction XupnpTlsInteraction;
129 typedef GTlsInteractionClass XupnpTlsInteractionClass;
130 static void xupnp_tls_interaction_init (XupnpTlsInteraction *interaction);
131 static void xupnp_tls_interaction_class_init (XupnpTlsInteractionClass *xupnpClass);
132 static gboolean getAccountId(char *outValue);
133 static gboolean update_gwylist(GwyDeviceData* gwydata);
134 
135 GType xupnp_tls_interaction_get_type (void);
136 G_DEFINE_TYPE (XupnpTlsInteraction, xupnp_tls_interaction, G_TYPE_TLS_INTERACTION);
137 
138 #ifdef BROADBAND
139 void dp_signal_handlr(int sig)
140 {
141  //detach and remove
142  //white list from memory.
143  if (dp_wlist && (shmId > 0))
144  {
145  shmdt((void *) dp_wlist);
146  shmctl(shmId, IPC_RMID, NULL);
147  }
148  exit(0);
149 }
150 
151 /*
152  This function takes an ipv4 address as input
153  and returns a 10 bit hash table index.
154 */
155 unsigned short dp_hashindex (long ipaddr)
156 {
157  unsigned short ret;
158  // Fold the ip address to get a 9 bit hansh index
159  ret =(ipaddr & 0x3FF) + ((ipaddr >> 10)&0x3FF) + ((ipaddr >> 20)&0x3FF)
160  + ((ipaddr >> 30) & 0x3FF);
161  ret = ((ret & 0x3FF) + ((ret >> 10) && 0x3FF)) &0x3FF;
162  if (ret)
163  ret = ret-1;
164  return(ret);
165 }
166 
167 /*
168  Initialize the dp whitelist and associated data structures.
169 */
170 int dp_wlistInit()
171 {
172  int ret=0, fstat;
173  key_t key;
174  int i;
175 
176  // signal handlers for cleaning up
177  // on termination of service.
178  signal(SIGHUP,dp_signal_handlr);
179  signal(SIGINT,dp_signal_handlr);
180  signal(SIGQUIT,dp_signal_handlr);
181  signal(SIGABRT,dp_signal_handlr);
182  signal(SIGTSTP,dp_signal_handlr);
183  signal(SIGKILL,dp_signal_handlr);
184 
185  // create a unique key
186  if ((key = ftok(PNAME, PID)) != (key_t) -1) {
187  //Allocate white list in shared memory shared
188  //with 'mrd' service.
189  //White list contain 1024 hash indexed entries
190  //and 1024 overflow table. Hash is calculated
191  //by folding the IPv4 address to a 10 bit hash
192  //index value.
193  //Overflow table indexes are stored in a FIFO
194  //every entry in the whitelist contain a field
195  //(ofb_index) point to a collision index in the
196  //overflow table.
197  //On further collision,every collistion entry
198  //subsequently contain index of (ofb_index)
199  //another collision entry in the overflow table.
200  shmId = shmget(key, MAX_BUF_SIZE*sizeof(dp_wlist_t),
201  S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH|IPC_CREAT);
202 
203  if (shmId < 0)
204  {
205  g_message("dp_wlistInit:dp list creation, shared memory failure %d %s\n",
206  errno, strerror(errno));
207  if (errno != SHM_EXISTS) {
208  dp_wlist = (void *) -1;
209  return -1;
210  }
211  shmId = shmget(key, MAX_BUF_SIZE*sizeof(dp_wlist_t), S_IRUSR|S_IRGRP|S_IROTH);
212  if (shmId < 0) {
213  g_message("dp_wlistInit:shmget failure %d %s\n", errno, strerror(errno));
214  dp_wlist = (void *) -1;
215  return -1;
216  }
217  }
218  //get a pointer to white list created in shared memory.
219  dp_wlist = (dp_wlist_t *) shmat(shmId, 0, 0);
220  if (dp_wlist == (void *) -1)
221  {
222  g_message("dp_wlistInit: shared memory attach failed errno %d %s\n",
223  errno, strerror(errno));
224  ret = -1;
225  }
226  else
227  {
228  // push the overflow indexs into a fifo
229  for (i=MAX_ENTRIES; i<MAX_BUF_SIZE; i++)
230  {
231  ENQUEUE_FIFO(dp_wlist_fifo, i, fstat);
232  if (fstat== FIFO_FULL)
233  {
234  break;
235  }
236  }
237 
238  //initialize the white list
239  for (i=0; i<MAX_BUF_SIZE; i++)
240  {
241  //initialize next index entry of whilte list
242  //to -1, which indicate no collision for the.
243  //current index.
244  dp_wlist[i].ofb_index=(short ) -1;
245  }
246  }
247  }
248  else {
249  dp_wlist = (void *) -1;
250  ret = -1;
251  }
252  return (ret);
253 }
254 
255 /*
256  This function lookup the dp white list for a ip address
257  and mac address.
258 
259  input - ipaddr - ipv4 address
260  - MAC - mac address
261 
262  output - stat
263  - DP_COLLISION - entry in the collision table
264  - DP_INVALID_MAC - ip address existing in whitelist
265  mac address not matching.
266  return
267  - index - if the lookup found entry in whitelist.
268  - -1 - entry not existing in white list
269 */
270 
271 short dpnode_lookup(long ipaddr, char MAC[], dp_wlist_ss_t *stat,
272  unsigned short *lastnode)
273 {
274  short index;
275 
276  if (dp_wlist == (void *) -1) return (DP_WLIST_ERROR);
277  index = dp_hashindex(ipaddr);
278  //check if the ip address is already existing in the white list
279  if (dp_wlist[index].ofb_index == (short) -1) return -1;
280  else
281  {
282  if (dp_wlist[index].ipaddr == ipaddr)
283  {
284  if (!strncmp(MAC, dp_wlist[index].macaddr, MAC_ADDRESS_SIZE))
285  {
286  *stat = DP_SUCCESS;
287  }
288  else
289  {
290  *stat = DP_INVALID_MAC;
291  }
292  return (index);;
293  }
294  else
295  {
296  *lastnode = index;
297  //search overflow table
298  while (dp_wlist[index].ofb_index > 0)
299  {
300  *lastnode = index;
301  index = dp_wlist[index].ofb_index;
302  if (dp_wlist[index].ipaddr == ipaddr)
303  {
304  if (!strncmp(MAC, dp_wlist[index].macaddr,
305  MAC_ADDRESS_SIZE))
306  {
307  *stat = DP_COLLISION;
308  return (index);
309  }
310  else
311  {
312  *stat = DP_INVALID_MAC;
313  return (index);
314  }
315  }
316  }
317  *stat = DP_COLLISION;
318  }
319  }
320  return -1;
321 }
322 
323 /*
324  This function lookup the dp white list for a ip address
325  and mac address, if the entry is not existing add the .
326  entry into the white list. If entry is existing
327  but mac is not matching, update the mac address
328 
329  input - ipaddr - ipv4 address
330  - MAC - mac address
331 
332  return
333  - DP_COLLISION - entry in the collision table
334  - DP_SUCCESS - successfully added entry
335 */
336 dp_wlist_ss_t dpnode_insert(long ipaddr, char *macaddr)
337 {
338  dp_wlist_ss_t stat;
339  dp_wlist_ss_t ret=DP_SUCCESS;
340  fstat_t fret;
341  short index, pindex;
342 
343  if (dp_wlist == (void *) -1) return (DP_WLIST_ERROR);;
344  if ((index = dpnode_lookup(ipaddr, macaddr, &stat,&pindex)) == (short) -1)
345  {
346  // check if there is collision
347  if (stat == DP_COLLISION)
348  {
349  // collision add to the collision table and link the last index
350  // to the new node.
351  DEQUEUE_FIFO(dp_wlist_fifo, index, fret);
352  if (fret == FIFO_OK)
353  {
354  g_message("dpnode_insert:collsion ip:%lu mac:%s hash index %d\n",ipaddr, macaddr, index);
355  dp_wlist[pindex].ofb_index = index;
356  dp_wlist[index].ipaddr = ipaddr;
357  strncpy(dp_wlist[index].macaddr, macaddr, MAC_ADDRESS_SIZE);
358  dp_wlist[index].ofb_index = 0;
359  }
360  }
361  else
362  {
363  // add new entry
364  index = dp_hashindex (ipaddr);
365  g_message("dpnode_insert:new ip:%lu mac:%s hash index %d\n",ipaddr, macaddr, index);
366  dp_wlist[index].ipaddr = ipaddr;
367  strncpy(dp_wlist[index].macaddr, macaddr,MAC_ADDRESS_SIZE);
368  dp_wlist[index].ofb_index = 0;
369  }
370 
371  }
372  else
373  {
374  if (stat == DP_INVALID_MAC)
375  {
376  g_message("dpnode_insert:mac update ip:%lu mac:%s hash index %d\n",ipaddr, macaddr, index);
377  // update mac address
378  strncpy(dp_wlist[index].macaddr, macaddr,MAC_ADDRESS_SIZE);
379  }
380  else {
381  ret = DP_WLIST_ERROR;
382  }
383  }
384  return (ret);
385 }
386 
387 /*
388  This function delete an entry from dp whitelist.
389 
390  input - ipaddr - ipv4 address
391  - macaddr - mac address
392 
393  return
394  void.
395 */
396 void dpnode_delete(long ipaddr, char *macaddr)
397 {
398  dp_wlist_ss_t stat;
399  int ret = 0;
400  unsigned short index, pindex, tindex;
401 
402  if (((index = dpnode_lookup(ipaddr, macaddr, &stat, &pindex)) >= 0) && (index != DP_WLIST_ERROR))
403  {
404 
405  if (index < MAX_ENTRIES )
406  {
407  // The entry is in the main table
408  // If there are no subsequent nodes, delete the entry
409  if (dp_wlist[index].ofb_index ==0)
410  {
411  // No collision just delete the node
412  g_message("No Collision ip:%lu mac:%s \n",ipaddr, macaddr);
413  dp_wlist[index].ofb_index =-1;
414  dp_wlist[index].ipaddr = 0;
415  }
416  else
417  {
418  // there are subsequent nodes in overflow table, delete the entry
419  // copy the subsequent node from overflow table and then
420  // push the subsequent overflow table entry into fifo
421  g_message("Collision ip:%lu mac:%s \n",ipaddr, macaddr);
422  tindex = dp_wlist[index].ofb_index;
423  dp_wlist[index].ofb_index = dp_wlist[tindex].ofb_index;
424  dp_wlist[index].ipaddr = dp_wlist[tindex].ipaddr;
425  strncpy(dp_wlist[index].macaddr, dp_wlist[tindex].macaddr,MAC_ADDRESS_SIZE);
426  dp_wlist[tindex].ofb_index=-1;
427  dp_wlist[tindex].ipaddr=0;
428  ENQUEUE_FIFO(dp_wlist_fifo, tindex, ret);
429  }
430  }
431  else
432  {
433  // Entry is in the overflow table.
434  dp_wlist[pindex].ofb_index = dp_wlist[index].ofb_index;
435  dp_wlist[index].ofb_index=-1;
436  dp_wlist[index].ipaddr=0;
437  ENQUEUE_FIFO(dp_wlist_fifo, index, ret);
438  }
439  }
440  (void)(ret); // unused variable.
441 }
442 #endif
443 
444 static void addRouteToMocaBridge(char *subnetip)
445 {
446  int ret = 0;
447  ret = v_secure_system("/etc/Xupnp/addRouteToMocaBridge.sh %s &",subnetip );
448  if(ret != 0) {
449  g_message("Failure in executing command via v_secure_system. ret val : %d \n", ret);
450  }
451 }
452 
453 static void
454 xupnp_tls_interaction_init (XupnpTlsInteraction *interaction)
455 {
456 
457 }
458 static GTlsInteractionResult
459 xupnp_tls_interaction_request_certificate (GTlsInteraction *interaction,
460  GTlsConnection *connection,
461  GTlsCertificateRequestFlags flags,
462  GCancellable *cancellable,
463  GError **error)
464 {
465  GTlsCertificate *cert;
466  GError *xupnp_error = NULL;
467 
468  if ((cert_File == NULL) || (key_File == NULL) ) {
469 
470  g_message(" Certificate or Key file NULL");
471  return G_TLS_INTERACTION_FAILED;
472  }
473 
474  cert = g_tls_certificate_new_from_files (cert_File,
475  key_File,
476  &xupnp_error);
477  g_assert_no_error (xupnp_error);
478 
479  g_tls_connection_set_certificate (connection, cert);
480  g_object_unref (cert);
481 
482  return G_TLS_INTERACTION_HANDLED;
483 }
484 
485 static void
486 xupnp_tls_interaction_class_init (XupnpTlsInteractionClass *xupnpClass)
487 {
488  GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (xupnpClass);
489 
490  interaction_class->request_certificate = xupnp_tls_interaction_request_certificate;
491 }
492 
493 #ifdef BROADBAND
494 gboolean getAccountId(char *outValue)
495 {
496  char temp[ACCOUNTID_SIZE] = {0};
497  int rc;
498  rc = syscfg_get(NULL, "AccountID", temp, sizeof(temp));
499  if(!rc)
500  {
501  if ((outValue != NULL))
502  {
503  strncpy(outValue, temp, ACCOUNTID_SIZE-1);
504  return TRUE;
505  }
506  }
507  else
508  {
509  g_message("getAccountId: Unable to get the Account Id");
510  }
511  return FALSE;
512 }
513 #else
514 gboolean getAccountId(char *outValue)
515 {
516  gboolean result = FALSE;
517 #ifdef ENABLE_RFC
518  RFC_ParamData_t param = {0};
519 
520  WDMP_STATUS status = getRFCParameter("XUPNP","Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.AccountInfo.AccountID",&param);
521 
522  if (status == WDMP_SUCCESS)
523  {
524  if (((param.value == NULL)))
525  {
526  g_message("getAccountId : NULL string !");
527  return result;
528  }
529  else
530  {
531  if (strncpy(outValue,param.value, ACCOUNTID_SIZE-1))
532  {
533  result = TRUE;
534  }
535  }
536  }
537  else
538  {
539  g_message("getAccountId: getRFCParameter Failed : %s\n", getRFCErrorString(status));
540  }
541 #else
542  g_message("Not built with RFC support.");
543 #endif
544  return result;
545 }
546 #endif
547 
548 gboolean selfDeviceDiscovered=FALSE;
549 gboolean bSerialNum=FALSE;
550 
551 #if defined(USE_XUPNP_IARM) || defined(USE_XUPNP_IARM_BUS)
552 
553 typedef struct _iarmDeviceData {
554  unsigned long bufferLength;
555  char* pBuffer;
556 } IarmDeviceData;
557 
558 //static GMainLoop *main_loop;
559 #define WAIT_TIME_SEC 5
560 #ifdef USE_XUPNP_IARM
561 #include "uidev.h"
562 static void *gCtx = NULL;
563 static void _GetXUPNPDeviceInfo(void *callCtx, unsigned long methodID, void *arg, unsigned int serial);
564 #else
565 #include "libIBus.h"
566 #include "libIARMCore.h"
567 #include "sysMgr.h"
568 IARM_Result_t _GetXUPNPDeviceInfo(void *arg);
569 #endif
570 
571 
572 static IARM_Result_t GetXUPNPDeviceInfo(char *pDeviceInfo, unsigned long length)
573 {
574  g_mutex_lock(devMutex);
575  g_message("<<<<<<<IARM XUPnP Call Reached API Processor - length: %ld Output Data length: %d>>>>>>>>", length, outputcontents->len);
576 
577  //IarmDeviceData *param = (IarmDeviceData *)arg;
578  if (outputcontents->len <= length)
579  {
580  //Copy the output to buffer and return success
581  g_message("Output string is\n %s\nAddress of received memory is %p", outputcontents->str, pDeviceInfo);
582  //Append space for null character
583  strncpy (pDeviceInfo, outputcontents->str, outputcontents->len+1);
584  g_mutex_unlock(devMutex);
585  g_message("<<<<<<<IARM XUPnP Call Returned success from API Processor>>>>>>>>");
586  return IARM_RESULT_SUCCESS;
587  }
588  else
589  {
590  //return IARM Error
591  g_mutex_unlock(devMutex);
592  g_message("<<<<<<<IARM XUPnP Call Returned failure from API Processor>>>>>>>>");
593  return IARM_RESULT_INVALID_STATE;
594  }
595 
596  //IARM_CallReturn(callCtx, "UIMgr", "GetXUPNPDeviceInfo", ret, serial);
597  //g_mutex_unlock(mutex);
598 }
599 
600 //notifyXUPnPDataUpdateEvent(UIDEV_EVENT_XUPNP_DATA_UPDATE)
601 static void notifyXUPnPDataUpdateEvent(int eventId)
602 {
603 #ifdef USE_XUPNP_IARM
604  g_message("<<<<<<<IARM XUPnP Posted update request>>>>>>>>");
605  UIDev_EventData_t eventData;
606  eventData.id = eventId;
607 
608  // struct _UIDEV_XUPNP_DATA {
609  // unsigned long deviceInfoLength;
610  // } xupnpData;
611  //Add the length to accommodate NULL character
612  g_mutex_lock(devMutex);
613  eventData.data.xupnpData.deviceInfoLength = outputcontents->len+1;
614  g_mutex_unlock(devMutex);
615  UIDev_PublishEvent(eventId, &eventData);
616 #else
617 
618  IARM_Bus_SYSMgr_EventData_t eventData;
619  g_mutex_lock(devMutex);
620  eventData.data.xupnpData.deviceInfoLength = outputcontents->len+1;
621  g_mutex_unlock(devMutex);
622  g_message("<<<<<<<IARM XUPnP Posted update request with Length %ld>>>>>>>>",eventData.data.xupnpData.deviceInfoLength);
623  IARM_Bus_BroadcastEvent(IARM_BUS_SYSMGR_NAME, (IARM_EventId_t)IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_UPDATE,(void *)&eventData, sizeof(eventData));
624 
625 #endif
626 }
627 
628 #ifdef USE_XUPNP_IARM
629 
630 /**
631  * @brief If there is any other process wants to get XUPnP data, the event will be handled here.
632  *
633  * @param[in] eventId Event Identifier identifying the Data request event.
634  * @param[in] eventData Optional Event data.
635  * @ingroup XUPNP_XDISCOVERY_FUNC
636  */
637 void _evtHandler(int eventId, void *eventData)
638 #else
639 
640 /**
641  * @brief This is a call back function for handling SYS Manager events. It notifies the XUPnP
642  * about The Data update event triggered by IARM.
643  *
644  * @param[in] owner Owner of the event, contains name of the Manager.
645  * @param[in] eventId Event Identifier identifying the Data request event.
646  * @param[in] data Event data.
647  * @param[in] len Size of the event data.
648  * @ingroup XUPNP_XDISCOVERY_FUNC
649  */
650 void _evtHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
651 #endif
652 {
653  g_message("<<<<<<<IARM XUPnP Received update request>>>>>>>>");
654 #ifdef USE_XUPNP_IARM
655  UIDev_EventData_t *evt = eventData;
656  if (eventId == UIDEV_EVENT_XUPNP_DATA_REQUEST)
657  {
658  notifyXUPnPDataUpdateEvent(UIDEV_EVENT_XUPNP_DATA_UPDATE);
659  }
660 #else
661  errno_t rc = -1;
662  int ind = -1;
663 
664  rc = strcmp_s(owner, strlen(owner), IARM_BUS_SYSMGR_NAME, &ind );
665  ERR_CHK(rc);
666  if((ind == 0) && (rc == EOK))
667  {
668  switch (eventId) {
670  {
671  notifyXUPnPDataUpdateEvent(IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_UPDATE);
672  }
673  break;
674  default:
675  break;
676  }
677  }
678 #endif
679 }
680 
681 /**
682  * @brief This function will do the initialization procedure for using the IARM Bus within XUPnP.
683  * This will register the event handlers to receive events from IARM Managers and will connect
684  * with the IARM Bus.
685  *
686  * @return TRUE if initialization is successful.
687  * @ingroup XUPNP_XDISCOVERY_FUNC
688  */
689 gboolean XUPnP_IARM_Init(void)
690 {
691  g_message("<<<<< Iniializing IARM XUPnP >>>>>>>>");
692 
693 #ifdef USE_XUPNP_IARM
694  if (gCtx == NULL) {
695  UIDev_Init(_IARM_XUPNP_NAME);
696  g_message("<<<<<<<IARM XUPnP Init Done>>>>>>>>");
697  if (UIDev_GetContext(&gCtx) == IARM_RESULT_SUCCESS) {
698  g_message("<<<<<<<IARM XUPnP Got the context>>>>>>>");
699  IARM_RegisterCall(gCtx, "UIMgr", "GetXUPNPDeviceInfo", _GetXUPNPDeviceInfo, NULL/*callCtx*/);
700  UIDev_RegisterEventHandler(UIDEV_EVENT_XUPNP_DATA_REQUEST, _evtHandler);
701  g_message("<<<<<<<IARM XUPnP Registered the events>>>>>>>>");
702  return TRUE;
703  }
704  else {
705  return FALSE;
706  }
707  }
708 #else
709  if(IARM_RESULT_SUCCESS != IARM_Bus_Init(_IARM_XUPNP_NAME))
710  {
711  g_message("<<<<<<<%s - Failed in IARM Bus IARM_Bus_Init>>>>>>>>",__FUNCTION__);
712  return FALSE;
713  }
714  else if (IARM_RESULT_SUCCESS != IARM_Bus_Connect())
715  {
716  g_message("<<<<<<<%s - Failed in IARM_Bus_Connect>>>>>>>>",__FUNCTION__);
717  return FALSE;
718  }
719  else
720  {
723  g_message("<<<<<<<%s - Registered the BUS Events >>>>>>>>",__FUNCTION__);
724  return TRUE;
725  }
726 #endif
727 
728 }
729 
730 #ifdef USE_XUPNP_IARM
731 static void _GetXUPNPDeviceInfo(void *callCtx, unsigned long methodID, void *arg, unsigned int serial)
732 #else
733 IARM_Result_t _GetXUPNPDeviceInfo(void *arg)
734 #endif
735 {
736  g_message("<<<<<<<IARM XUPnP API Call received>>>>>>>>");
737  g_mutex_lock(mutex);
738 
739 #ifdef USE_XUPNP_IARM
740  IarmDeviceData *param = (IarmDeviceData *)arg;
741  g_message("Address of received memory is %p - Call 0", param->pBuffer);
742  IARM_Result_t ret = GetXUPNPDeviceInfo(param->pBuffer, param->bufferLength);
743  IARM_CallReturn(gCtx, "UIMgr", "GetXUPNPDeviceInfo", ret, serial);
744 #else
745  // Extract the XUPNP Info data
747 #ifdef USE_DBUS
748  GetXUPNPDeviceInfo((char *)param + sizeof(IARM_Bus_SYSMGR_GetXUPNPDeviceInfo_Param_t), param->bufLength);
749 #else
750  IARM_Result_t retCode = IARM_RESULT_SUCCESS;
751  // Create a Mem space for the buff
752  retCode = IARM_Malloc(IARM_MEMTYPE_PROCESSSHARE,param->bufLength, &(param->pBuffer));
753  g_message("Address of received memory is %p - Call 0", param->pBuffer);
754  if(IARM_RESULT_SUCCESS == retCode)
755  {
756  GetXUPNPDeviceInfo(param->pBuffer, param->bufLength);
757  }
758 #endif
759 #endif
760 
761  g_mutex_unlock(mutex);
762 
763  return IARM_RESULT_SUCCESS;
764 
765 }
766 #endif //#if defined(USE_XUPNP_IARM) || defined(USE_XUPNP_IARM_BUS)
767 
768 #ifndef BROADBAND
769 int xPKI_check_rfc()
770 {
771  errno_t rc = -1;
772  int ind = -1;
773 #ifdef ENABLE_RFC
774  RFC_ParamData_t param = {0};
775 
776  WDMP_STATUS status = getRFCParameter("XUPNP","Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UPnPxPKI.Enable",&param);
777 
778  if (status == WDMP_SUCCESS)
779  {
780  rc = strcmp_s(param.value,sizeof(param.value),"true",&ind);
781  if ((ind == 0) && (rc == EOK))
782  {
783  g_message("New Device xPKI rfc_enabled and xdiscovery is running with new certs");
784  return 1;
785  }
786  else
787  {
788  g_message("Running device protection with old certs");
789  }
790  }
791  else
792  {
793  g_message("getRFCParameter Failed : %s", getRFCErrorString(status));
794  }
795 #else
796  g_message("Not built with RFC support.");
797 #endif
798  return 0;
799 }
800 #endif
801 
802 int check_rfc()
803 {
804 #ifndef BROADBAND
805 #ifdef ENABLE_RFC
806  RFC_ParamData_t param = {0};
807 
808  WDMP_STATUS status = getRFCParameter("XUPNP","Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.UPnP.Refactor.Enable",&param);
809 
810  if (status == WDMP_SUCCESS)
811  {
812  if (!strncmp(param.value, "true", strlen("true")))
813  {
814  g_message("New Device Refactoring rfc_enabled");
815  return 1;
816  }
817  else
818  {
819  g_message("Running older xdiscovery");
820  }
821  }
822  else
823  {
824  g_message("getRFCParameter Failed : %s", getRFCErrorString(status));
825  }
826 #else
827  g_message("Not built with RFC support.");
828 #endif
829 #else
830  syscfg_init();
831  char temp[24] = {0};
832  errno_t rc = -1;
833  int ind = -1;
834  if (!syscfg_get(NULL, "Refactor", temp, sizeof(temp)) )
835  {
836  rc = strcmp_s("true", strlen("true"), temp, &ind);
837  ERR_CHK(rc);
838  if((ind == 0) && (rc == EOK))
839  {
840  return 1;
841  }
842  }
843 #endif
844  return 0;
845 }
846 
847 /**
848  * @brief This function is used to log the messages of XUPnP applications. Each Log message
849  * will be written to a file along with the timestamp formated in ISO8601 format.
850  *
851  * @param[in] log_domain Defines the log domain. For applications, this is typically left as
852  * the default NULL domain. Libraries should define this so that any messages that they log
853  * can be differentiated from messages from other libraries/applications.
854  * @param[in] log_level Log level used to categorize messages of type warning, error, info, debug etc.
855  * @param[in] message The Message to be logged represented in string format.
856  * @param[in] user_data Contains the Log file name.
857  * @ingroup XUPNP_XDISCOVERY_FUNC
858  */
859 void xupnp_logger (const gchar *log_domain, GLogLevelFlags log_level,
860  const gchar *message, gpointer user_data)
861 {
862 
863  GTimeVal timeval;
864  gchar *date_str;
865  g_get_current_time(&timeval);
866  if (logoutfile == NULL)
867  {
868  // Fall back to console output if unable to open file
869  g_print ("g_time_val_to_iso8601(&timeval): %s\n", message);
870  return;
871  }
872 
873  date_str = g_time_val_to_iso8601 (&timeval);
874  g_fprintf (logoutfile, "%s : %s\n", date_str, message);
875  if(date_str)
876  {
877  g_free (date_str);
878  }
879  fflush(logoutfile);
880 }
881 
882 
883 static gint
884 g_list_find_sno(GwyDeviceData* gwData, gconstpointer* sno )
885 {
886  if (g_strcmp0(g_strstrip(gwData->serial_num->str),g_strstrip((gchar *)sno)) == 0)
887  return 0;
888  else
889  return 1;
890 }
891 
892 static gint
893 g_list_find_udn(GwyDeviceData* gwData, gconstpointer* udn )
894 {
895  if (g_strcmp0(g_strstrip(gwData->receiverid->str),g_strstrip((gchar *)udn)) == 0)
896  return 0;
897  else
898  return 1;
899 }
900 
901 static gint
902 g_list_compare_sno(GwyDeviceData* gwData1, GwyDeviceData* gwData2, gpointer user_data )
903 {
904  gint result = g_strcmp0(g_strstrip(gwData1->serial_num->str),g_strstrip(gwData2->serial_num->str));
905  return result;
906 }
907 
908 /**
909  * @brief This will Scan through the device list to check whether a particular device entry exists.
910  *
911  * It will Match the device serial number in the list to find the desired device entry.
912  *
913  * @param[in] sno Serial number of the device represented in string format.
914  *
915  * @return Returns TRUE if serial number is present in the device list else returns FALSE.
916  * @ingroup XUPNP_XDISCOVERY_FUNC
917  */
918 //Find a device with given serial number is in our list of gateways
919 gboolean checkDeviceExists(const char* sno,char* outPlayUrl)
920 {
921  gboolean retval = FALSE;
922  errno_t rc = -1;
923  if (g_list_length(xdevlist) > 0)
924  {
925  GList *element = NULL;
926  element = g_list_first(xdevlist);
927  while(element)
928  {
929  gint result = g_strcmp0(g_strstrip((gchar *)(((GwyDeviceData *)element->data)->serial_num->str)),g_strstrip((gchar *)sno));
930  //Matched the serial number
931  if (result==0)
932  {
933  retval = TRUE;
934  if((((GwyDeviceData *)element->data)->isgateway) == TRUE)
935  {
936  rc = strcpy_s(outPlayUrl, OUTPLAYURL_SIZE, g_strstrip(((GwyDeviceData *)element->data)->playbackurl->str));
937  ERR_CHK(rc);
938  if ( rc != EOK)
939  {
940  retval = FALSE;
941  }
942  else
943  {
944  if (outPlayUrl)
945  {
946  strcat(outPlayUrl,"&live=ocap://0xffff");
947  }
948  }
949  }
950  break;
951  }
952  //Past the search string value in sorted list
953  else if (result>0)
954  {
955  retval = FALSE;
956  break;
957  }
958  //There are still elements to search
959  element = g_list_next(element);
960  }
961 // if (element) g_object_unref(element);
962  }
963  return retval;
964 }
965 
966 
967 static void
968 device_proxy_unavailable_cb (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
969 {
970  char gwyPlayUrl[OUTPLAYURL_SIZE]={'\0'};
971  const gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
972 
973  g_message ("In unavailable_cb Device %s went down",sno);
974 
975  if((g_strcmp0(g_strstrip(ownSerialNo->str),sno) == 0))
976  {
977  g_message ("Self Device [%s][%s] not removing",sno,ownSerialNo->str);
978  g_free((gpointer)sno);
979  return;
980  }
981  GUPnPServiceInfo *sproxy = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE);
982 
983  if (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)sproxy) == TRUE)
984  {
985  g_message("Removing notifications on %s", sno);
986  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)sproxy, FALSE);
987  gupnp_service_proxy_remove_notify((GUPnPServiceProxy *)sproxy, "PlaybackUrl", on_last_change, NULL);
988  gupnp_service_proxy_remove_notify((GUPnPServiceProxy *)sproxy, "SystemIds", on_last_change, NULL);
989  }
990 
991  if (checkDeviceExists(sno,gwyPlayUrl))
992  {
993  if(gwyPlayUrl[0] != '\0')
994  {
995  if (getSoupStatusFromUrl(gwyPlayUrl))
996  {
997  g_message("Network Multicast issue for device %s",sno);
998  g_free((gpointer)sno);
999  g_object_unref(sproxy);
1000  return;
1001  }
1002  else
1003  {
1004  g_message("Can't reach device %s",sno);
1005  }
1006  }
1007  else
1008  {
1009  g_message("GW playback url is NULL");
1010  }
1011 
1012  if (delete_gwyitem(sno) == FALSE)
1013  {
1014  g_message("%s found, but unable to delete it from list", sno);
1015  }
1016  else
1017  {
1018  g_message("Deleted %s from list", sno);
1019  sendDiscoveryResult(disConf->outputJsonFile);
1020  }
1021  }
1022  g_free((gpointer)sno);
1023  g_object_unref(sproxy);
1024 }
1025 
1026 static void
1027 device_proxy_unavailable_cb_client (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1028 {
1029  const gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1030 
1031  g_message ("In unavailable_client Device %s went down",sno);
1032  if((g_strcmp0(g_strstrip(ownSerialNo->str),sno) == 0))
1033  {
1034  g_message ("Self Device [%s][%s] not removing",sno,ownSerialNo->str);
1035  g_free((gpointer)sno);
1036  return;
1037  }
1038  GUPnPServiceInfo *sproxy = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_MEDIA);
1039  if (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)sproxy) == TRUE)
1040  {
1041  g_message("Removing notifications on %s", sno);
1042  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)sproxy, FALSE);
1043  }
1044  if (delete_gwyitem(sno) == FALSE)
1045  {
1046  g_message("%s found, but unable to delete it from list", sno);
1047  }
1048  else
1049  {
1050  g_message("Deleted %s from list", sno);
1051  sendDiscoveryResult(disConf->outputJsonFile);
1052  }
1053  g_free((gpointer)sno);
1054  g_object_unref(sproxy);
1055 }
1056 
1057 static void
1058 device_proxy_unavailable_cb_gw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1059 {
1060  const gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1061  char gwyPlayUrl[OUTPLAYURL_SIZE]={0};
1062  g_message ("In unavailable_gw Device %s went down",sno);
1063  if((g_strcmp0(g_strstrip(ownSerialNo->str),sno) == 0))
1064  {
1065  g_message ("Self Device [%s][%s] not removing",sno,ownSerialNo->str);
1066  g_free((gpointer)sno);
1067  return;
1068  }
1069  GUPnPServiceInfo *sproxy = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_MEDIA);
1070  if (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)sproxy) == TRUE)
1071  {
1072  g_message("Removing notifications on %s", sno);
1073  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)sproxy, FALSE);
1074  gupnp_service_proxy_remove_notify((GUPnPServiceProxy *)sproxy, "PlaybackUrl", on_last_change, NULL);
1075  }
1076  if (checkDeviceExists(sno, gwyPlayUrl))
1077  {
1078  if(gwyPlayUrl[0] != '\0')
1079  {
1080  if (getSoupStatusFromUrl(gwyPlayUrl))
1081  {
1082  g_message("Network Multicast issue for device %s",sno);
1083  g_free((gpointer)sno);
1084  g_object_unref(sproxy);
1085  return;
1086  }
1087  else
1088  {
1089  g_message("Can't reach device %s",sno);
1090  }
1091  }
1092  else
1093  {
1094  g_message("GW playback url is NULL");
1095  }
1096  if (delete_gwyitem(sno) == FALSE)
1097  {
1098  g_message("%s found, but unable to delete it from list", sno);
1099  }
1100  else
1101  {
1102  g_message("Deleted %s from list", sno);
1103  sendDiscoveryResult(disConf->outputJsonFile);
1104  }
1105  }
1106  g_free((gpointer)sno);
1107  g_object_unref(sproxy);
1108 }
1109 
1110 static void
1111 device_proxy_available_cb (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1112 {
1113  errno_t rc = -1;
1114  int ind = -1;
1115  //g_print("Found a new device\n");
1116 // if(!checkDevAddInProgress)
1117 // {
1118 // ret=g_mutex_trylock(devMutex);
1119 // if (TRUE == ret)
1120 // {
1121  g_message("Found a new device. deviceAddNo = %u ",deviceAddNo);
1122  deviceAddNo++;
1123  if ((NULL==cp) || (NULL==dproxy))
1124  {
1125 // g_mutex_unlock(devMutex);
1126  deviceAddNo--;
1127  g_message("WARNING - Received a null pointer for gateway device device no %u",deviceAddNo);
1128  return;
1129  }
1130  if(rfc_enabled)
1131  {
1132  gchar* upc = gupnp_device_info_get_upc (GUPNP_DEVICE_INFO (dproxy));
1133  if(upc)
1134  {
1135  rc =strcmp_s("10000", strlen("10000"), upc, &ind);
1136  ERR_CHK(rc);
1137  if((!ind) && (rc == EOK))
1138  {
1139  g_message("Exiting the device addition as UPC value matched");
1140  g_free(upc);
1141  deviceAddNo--;
1142  return;
1143  }
1144  }
1145  }
1146  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1147  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
1148  if(xdevlistitem!=NULL)
1149  {
1150  GwyDeviceData *gwdata = xdevlistitem->data;
1151  gchar *temp=NULL;
1152  if ( processStringRequest((GUPnPServiceProxy *)gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE), "GetIpv6Prefix", "Ipv6Prefix" , &temp, FALSE ))
1153  {
1154  if(g_strcmp0(g_strstrip(temp),gwdata->ipv6prefix->str) != 0)
1155  {
1156  g_string_assign(gwdata->ipv6prefix, temp);
1157  sendDiscoveryResult(disConf->outputJsonFile);
1158  }
1159  g_free(temp);
1160  }
1161  deviceAddNo--;
1162  g_message("Existing as SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
1163  g_free(sno);
1164  return;
1165  }
1166  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
1167  if(gwydata)
1168  {
1169  init_gwydata(gwydata);
1170  }
1171  else
1172  {
1173  g_critical("Could not allocate memory for Gwydata. Exiting...");
1174  exit(1);
1175  }
1176 
1177  gwydata->sproxy = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE);
1178  if(!gwydata->sproxy)
1179  {
1180  deviceAddNo--;
1181  g_message("Unable to get the services, sproxy null. returning");
1182  return;
1183  }
1184  if (sno != NULL)
1185  {
1186  //g_print("Device serial number is %s\n",sno);
1187  g_message("Device serial number is %s",sno);
1188  g_string_assign(gwydata->serial_num, sno);
1189  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
1190  if (udn != NULL)
1191  {
1192  if (g_strrstr(udn,"uuid:"))
1193  {
1194  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
1195  if(receiverid)
1196  {
1197  g_message("Device receiver id is %s",receiverid);
1198  g_string_assign(gwydata->receiverid, receiverid);
1199  g_free(receiverid);
1200 
1201  if(!process_gw_services((GUPnPServiceProxy *)gwydata->sproxy, gwydata))
1202  {
1203  free_gwydata(gwydata);
1204  g_free(gwydata);
1205  g_free(sno);
1206  deviceAddNo--;
1207  partialDiscovery=TRUE;
1208  g_message("Exting from device_proxy_available_cb since mandatory paramters are not there device no %u",deviceAddNo);
1209  return;
1210  }
1211  }
1212  else
1213  g_message("Device receiver id is NULL");
1214  }
1215  }
1216  else
1217  g_message("Device UDN is NULL");
1218  }
1219 
1220  if(g_strrstr(g_strstrip(gwydata->devicetype->str),"XB") != NULL )
1221  {
1222  g_message("Discovered a XB device");
1223  }
1224  else if(g_strrstr(g_strstrip(gwydata->devicetype->str),"XI") == NULL )
1225  {
1226  g_message("Discovered a XG device");
1227  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy, "PlaybackUrl", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1228  g_message("Failed to add url notifications for %s", sno);
1229  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy, "SystemIds", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1230  g_message("Failed to add systemid notifications for %s", sno);
1231  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy, "DnsConfig", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1232  g_message("Failed to add DNS notifications for %s", sno);
1233  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy, "TimeZone", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1234  g_message("Failed to add TimeZone notifications for %s", sno);
1235  }
1236  else
1237  {
1238  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy, "DataGatewayIPaddress", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1239  g_message("Failed to add DataGatewayIPaddress notifications for %s", sno);
1240  }
1241  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy, TRUE);
1242 
1243  if (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy) == FALSE)
1244  {
1245  g_message("Failed to register for notifications on %s", sno);
1246  g_clear_object(&(gwydata->sproxy));
1247  }
1248  g_free(sno);
1249  deviceAddNo--;
1250  g_message("Exting from device_proxy_available_cb deviceAddNo = %u",deviceAddNo);
1251 
1252 // }
1253 // else
1254 // {
1255 // g_message("Already Existing device addition going on ");
1256 // }
1257 // g_mutex_unlock(devMutex);
1258 // }
1259 // else
1260 // {
1261 // g_message("Not able to get the device mutex lock");
1262 // }
1263 }
1264 
1265 static void
1266 device_proxy_available_cb_client (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1267 {
1268  g_message("Found a new Client device. deviceAddNo = %u ",deviceAddNo);
1269  deviceAddNo++;
1270  if ((NULL==cp) || (NULL==dproxy))
1271  {
1272  deviceAddNo--;
1273  g_message("WARNING - Received a null pointer for client device device no %u",deviceAddNo);
1274  return;
1275  }
1276  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1277  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
1278  if(xdevlistitem!=NULL)
1279  {
1280  deviceAddNo--;
1281  g_message("Existing as client SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
1282  g_free(sno);
1283  return;
1284  }
1285 
1286  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
1287  init_gwydata(gwydata);
1288  gwydata->sproxy_i = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_IDENTITY);
1289  gwydata->sproxy_m = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_MEDIA);
1290  if (sno != NULL)
1291  {
1292  g_message("XI device serial number is %s",sno);
1293  g_string_assign(gwydata->serial_num, sno);
1294  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
1295  if (udn != NULL)
1296  {
1297  if (g_strrstr(udn,"uuid:"))
1298  {
1299  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
1300  if(receiverid)
1301  {
1302  g_message("Client device receiver id is %s",receiverid);
1303  g_string_assign(gwydata->receiverid, receiverid);
1304  g_free(receiverid);
1305  if(!process_gw_services_identity((GUPnPServiceProxy *)gwydata->sproxy_i, gwydata))
1306  {
1307  free_gwydata(gwydata);
1308  g_free(gwydata);
1309  g_free(sno);
1310  deviceAddNo--;
1311  g_message("Exting from device_proxy_available_cb_client since mandatory paramters are not there device no %u",deviceAddNo);
1312  return;
1313  }
1314  else
1315  {
1316  g_message("Received XI Identity service");
1317  }
1318  if(!process_gw_services_media_config((GUPnPServiceProxy *)gwydata->sproxy_m, gwydata))
1319  {
1320  free_gwydata(gwydata);
1321  g_free(gwydata);
1322  g_free(sno);
1323  deviceAddNo--;
1324  g_message("Exting from device_proxy_available_cb_client since mandatory paramters are not there device no %u",deviceAddNo);
1325  return;
1326  }
1327  else
1328  {
1329  g_message("Received XI Media Config service");
1330  gwydata->isDevRefactored = TRUE;
1331  if (update_gwylist(gwydata)==FALSE )
1332  {
1333  g_message("Failed to update gw data into the list");
1334  g_critical("Unable to update the Client device-%s in the list",(char*)gwydata->serial_num);
1335  return;
1336  }
1337  }
1338  }
1339  else
1340  {
1341  g_message("Client device receiver id is NULL");
1342  }
1343  }
1344  }
1345  else
1346  {
1347  g_message("Client UDN is NULL");
1348  }
1349  }
1350  g_message("Discovered a Xi device");
1351  g_free(sno);
1352  deviceAddNo--;
1353  g_message("Exting from Device_proxy_available_cb client deviceAddNo = %u",deviceAddNo);
1354 
1355 }
1356 
1357 static void
1358 device_proxy_available_cb_gw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1359 {
1360  g_message("In device_proxy_available_cb_gw found a Gateway device. deviceAddNo = %u ",deviceAddNo);
1361  deviceAddNo++;
1362  if ((NULL==cp) || (NULL==dproxy))
1363  {
1364  deviceAddNo--;
1365  g_message("WARNING - Received a null pointer for gateway device device no %u",deviceAddNo);
1366  return;
1367  }
1368  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1369  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
1370  if(xdevlistitem!=NULL)
1371  {
1372  GwyDeviceData *gwdata = xdevlistitem->data;
1373  gchar *temp=NULL;
1374  if ( processStringRequest((GUPnPServiceProxy *)gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_GW_CFG), "GetIpv6Prefix", "Ipv6Prefix" , &temp, FALSE ))
1375  {
1376  if(g_strcmp0(g_strstrip(temp),gwdata->ipv6prefix->str) != 0)
1377  {
1378  g_string_assign(gwdata->ipv6prefix, temp);
1379  sendDiscoveryResult(disConf->outputJsonFile);
1380  }
1381  g_free(temp);
1382  }
1383  deviceAddNo--;
1384  g_message("Existing available_cb_gw as SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
1385  g_free(sno);
1386  return;
1387  }
1388  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
1389  init_gwydata(gwydata);
1390  gwydata->sproxy_i = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_IDENTITY);
1391  gwydata->sproxy_m = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_MEDIA);
1392  gwydata->sproxy_t = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_TIME);
1393  gwydata->sproxy_g = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_GW_CFG);
1394  gwydata->sproxy_q = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_QAM_CFG);
1395  if (sno != NULL)
1396  {
1397  g_message("In available_cb_gw Gateway device serial number: %s",sno);
1398  g_string_assign(gwydata->serial_num, sno);
1399  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
1400  if (udn != NULL)
1401  {
1402  if (g_strrstr(udn,"uuid:"))
1403  {
1404  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
1405  if(receiverid)
1406  {
1407  g_message("Gateway device receiver id is %s",receiverid);
1408  g_string_assign(gwydata->receiverid, receiverid);
1409  g_free(receiverid);
1410  if(!process_gw_services_identity((GUPnPServiceProxy *)gwydata->sproxy_i, gwydata))
1411  {
1412  free_gwydata(gwydata);
1413  g_free(gwydata);
1414  g_free(sno);
1415  deviceAddNo--;
1416  partialDiscovery=TRUE;
1417  g_message("Exting from available_cb_gw since mandatory paramters are not there device no %u",deviceAddNo);
1418  return;
1419  }
1420  else
1421  {
1422  g_message("Received XI Identity service");
1423  }
1424  if(!process_gw_services_media_config((GUPnPServiceProxy *)gwydata->sproxy_m, gwydata))
1425  {
1426  free_gwydata(gwydata);
1427  g_free(gwydata);
1428  g_free(sno);
1429  deviceAddNo--;
1430  partialDiscovery=TRUE;
1431  g_message("Exting from available_cb_gw since mandatory paramters are not there device no %u",deviceAddNo);
1432  return;
1433  }
1434  else
1435  {
1436  g_message("Received XI Media Config service");
1437  }
1438  if(!process_gw_services_time_config((GUPnPServiceProxy *)gwydata->sproxy_t, gwydata))
1439  {
1440  free_gwydata(gwydata);
1441  g_free(gwydata);
1442  g_free(sno);
1443  deviceAddNo--;
1444  partialDiscovery=TRUE;
1445  g_message("Exting from available_cb_gw since mandatory paramters are not there device no %u",deviceAddNo);
1446  return;
1447  }
1448  else
1449  {
1450  g_message("Received XI Time Config service");
1451  }
1452  if(!process_gw_services_gateway_config((GUPnPServiceProxy *)gwydata->sproxy_g, gwydata))
1453  {
1454  free_gwydata(gwydata);
1455  g_free(gwydata);
1456  g_free(sno);
1457  deviceAddNo--;
1458  partialDiscovery=TRUE;
1459  g_message("Exting from available_cb_gw since mandatory paramters are not there device no %u",deviceAddNo);
1460  return;
1461  }
1462  else
1463  {
1464  g_message("Received XI Gateway Config service");
1465  }
1466  if(!process_gw_services_qam_config((GUPnPServiceProxy *)gwydata->sproxy_q, gwydata))
1467  {
1468  free_gwydata(gwydata);
1469  g_free(gwydata);
1470  g_free(sno);
1471  deviceAddNo--;
1472  partialDiscovery=TRUE;
1473  g_message("Exting from available_cb_gw since mandatory paramters are not there device no %u",deviceAddNo);
1474  return;
1475  }
1476  else
1477  {
1478  g_message("Received XI QAM Config service");
1479  gwydata->isDevRefactored = TRUE;
1480  if (update_gwylist(gwydata)==FALSE )
1481  {
1482  g_message("Failed to update gw data into the list\n");
1483  g_critical("Unable to update the gateway-%s in the device list",(char*)gwydata->serial_num);
1484  return;
1485  }
1486  }
1487  }
1488  else
1489  {
1490  g_message("In available_cb_gw gateway device receiver id is NULL");
1491  }
1492  }
1493  }
1494  else
1495  {
1496  g_message("Gateway UDN is NULL");
1497  }
1498  }
1499  if(!strcasestr(g_strstrip(gwydata->devicetype->str),"XI") )
1500  {
1501  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_m, "PlaybackUrl", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1502  g_message("Failed to add url notifications for %s", sno);
1503  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_q, "SystemIds", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1504  g_message("Failed to add systemid notifications for %s", sno);
1505  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_g, "DnsConfig", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1506  g_message("Failed to add DNS notifications for %s", sno);
1507  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_t, "TimeZone", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1508  g_message("Failed to add TimeZone notifications for %s", sno);
1509  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_q, "VideoBaseUrl", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1510  g_message("Failed to add VideoBaseUrl notifications for %s", sno);
1511  }
1512  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_m, TRUE);
1513  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_t, TRUE);
1514  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_g, TRUE);
1515  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_q, TRUE);
1516 
1517  if (gupnp_service_proxy_add_notify ((GUPnPServiceProxy *)gwydata->sproxy_m, "FogTsbUrl", G_TYPE_STRING, on_last_change, NULL) == FALSE)
1518  g_message("Failed to add FogTsbUrl notifications for %s", sno);
1519 
1520  if ((gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_m) == FALSE) && (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_t) == FALSE) && (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_g) == FALSE) && (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_q) == FALSE))
1521  {
1522  g_message("Failed to register for notifications on %s", sno);
1523  g_object_unref(gwydata->sproxy_m);
1524  g_object_unref(gwydata->sproxy_t);
1525  g_object_unref(gwydata->sproxy_g);
1526  g_object_unref(gwydata->sproxy_q);
1527  }
1528  g_free(sno);
1529  deviceAddNo--;
1530  g_message("Discovered a XG device");
1531  g_message("Exting from device_proxy_available_cb_gateway deviceAddNo = %u",deviceAddNo);
1532 }
1533 
1534 static void
1535 device_proxy_unavailable_cb_bgw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1536 {
1537  const gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1538  g_message ("In unavailable_bgw Device %s went down",sno);
1539  if((g_strcmp0(g_strstrip(ownSerialNo->str),sno) == 0))
1540  {
1541  g_message ("Self Device [%s][%s] not removing",sno,ownSerialNo->str);
1542  g_free((gpointer)sno);
1543  return;
1544  }
1545  if (delete_gwyitem(sno) == FALSE)
1546  {
1547  g_message("%s found, but unable to delete it from list", sno);
1548  return;
1549  }
1550  else
1551  {
1552  g_message("Deleted %s from list", sno);
1553  sendDiscoveryResult(disConf->outputJsonFile);
1554  }
1555  g_free((gpointer)sno);
1556 }
1557 
1558 static void
1559 device_proxy_available_cb_bgw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
1560 {
1561  g_message("In available_bgw found a Broadband device. deviceAddNo = %u ",deviceAddNo);
1562  deviceAddNo++;
1563  if ((NULL==cp) || (NULL==dproxy))
1564  {
1565  deviceAddNo--;
1566  g_message("WARNING - Received a null pointer for broadband device device no %u",deviceAddNo);
1567  return;
1568  }
1569  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
1570  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
1571  if(xdevlistitem!=NULL)
1572  {
1573  deviceAddNo--;
1574  g_message("Existing available_cb_bgw as SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
1575  g_free((gpointer)sno);
1576  return;
1577  }
1578  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
1579  init_gwydata(gwydata);
1580  gwydata->sproxy_i = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_IDENTITY);
1581  gwydata->sproxy_t = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_TIME);
1582  gwydata->sproxy_g = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), XDISC_SERVICE_GW_CFG);
1583  if (sno != NULL)
1584  {
1585  g_message("In available_cb_bgw Broadband device serial number: %s",sno);
1586  g_string_assign(gwydata->serial_num, sno);
1587  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
1588  if (udn != NULL)
1589  {
1590  if (g_strrstr(udn,"uuid:"))
1591  {
1592  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
1593  if(receiverid)
1594  {
1595  g_message("Gateway device receiver id is %s",receiverid);
1596  g_string_assign(gwydata->receiverid, receiverid);
1597  g_free(receiverid);
1598  if(!process_gw_services_identity((GUPnPServiceProxy *)gwydata->sproxy_i, gwydata))
1599  {
1600  free_gwydata(gwydata);
1601  g_free(gwydata);
1602  g_free(sno);
1603  deviceAddNo--;
1604  g_message("Exting from available_cb_bgw since Identity paramters are not there device no %u",deviceAddNo);
1605  return;
1606  }
1607  else
1608  {
1609  g_message("Received XI Identity service");
1610  }
1611  if(!process_gw_services_time_config((GUPnPServiceProxy *)gwydata->sproxy_t, gwydata))
1612  {
1613  free_gwydata(gwydata);
1614  g_free(gwydata);
1615  g_free(sno);
1616  deviceAddNo--;
1617  g_message("Exting from available_cb_bgw since Time paramters are not there device no %u",deviceAddNo);
1618  return;
1619  }
1620  else
1621  {
1622  g_message("Received XI Time Config service");
1623  }
1624  if(!process_gw_services_gateway_config((GUPnPServiceProxy *)gwydata->sproxy_g, gwydata))
1625  {
1626  free_gwydata(gwydata);
1627  g_free(gwydata);
1628  g_free(sno);
1629  deviceAddNo--;
1630  g_message("Exting from available_cb_bgw since mandatory paramters are not there device no %u",deviceAddNo);
1631  return;
1632  }
1633  else
1634  {
1635  g_message("Received XI Gateway Config service");
1636  gwydata->isDevRefactored = TRUE;
1637  if (update_gwylist(gwydata)==FALSE )
1638  {
1639  g_message("Failed to update gw data into the list\n");
1640  g_critical("Unable to update the gateway-%s in the device list",(char*)gwydata->serial_num);
1641  return;
1642  }
1643  }
1644  }
1645  else
1646  {
1647  g_message("In available_cb_bgw gateway device receiver id is NULL");
1648  }
1649  }
1650  }
1651  else
1652  {
1653  g_message("Gateway UDN is NULL");
1654  }
1655  }
1656 
1657  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_i, TRUE);
1658  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_t, TRUE);
1659  gupnp_service_proxy_set_subscribed((GUPnPServiceProxy *)gwydata->sproxy_g, TRUE);
1660 
1661  if ((gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_i) == FALSE) && (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_t) == FALSE) && (gupnp_service_proxy_get_subscribed((GUPnPServiceProxy *)gwydata->sproxy_g) == FALSE))
1662  {
1663  g_message("Failed to register for notifications on %s", sno);
1664  g_object_unref(gwydata->sproxy_i);
1665  g_object_unref(gwydata->sproxy_t);
1666  g_object_unref(gwydata->sproxy_g);
1667  }
1668  g_free(sno);
1669  deviceAddNo--;
1670  g_message("Discovered a XB device");
1671  g_message("Exting from device_proxy_available_cb_broadband deviceAddNo = %u",deviceAddNo);
1672 }
1673 
1674 int main(int argc, char *argv[])
1675 {
1676  //preamble
1677  g_thread_init (NULL);
1678  g_type_init();
1679 
1680  gboolean ipv6Enabled=FALSE;
1681  gboolean bInterfaceReady=FALSE;
1682 
1683  GError* error = 0;
1684  GTlsInteraction *xupnp_tlsinteraction= NULL;
1685  mutex = g_mutex_new ();
1686  devMutex = g_mutex_new ();
1687  cond = g_cond_new ();
1688  logoutfile = NULL;
1689 
1690 #ifdef INCLUDE_BREAKPAD
1691  breakpad_ExceptionHandler();
1692 #endif
1693 
1694 
1695  outputcontents = g_string_new(NULL);
1696  ipMode = g_string_new("ipv4");
1697 
1698  ownSerialNo=g_string_new(NULL);
1699  if (argc < 2)
1700  {
1701  fprintf(stderr, "Error in arguments\nUsage: %s config file name (eg: /etc/xdiscovery.conf) %s log file location \n", argv[0], argv[1]);
1702  exit(1);
1703  }
1704 
1705  // outputfilename = g_string_assign(outputfilename, argv[2]);
1706  // const char* ifname = argv[1];
1707 
1708  char* logfilename = argv[2];
1709  if(logfilename)
1710  {
1711  logoutfile = g_fopen (logfilename, "a");
1712  }
1713  /*else if (disConf->logFile)
1714  {
1715  logoutfile = g_fopen (disConf->logFile, "a");
1716  }*/
1717  else
1718 
1719  {
1720  g_message("xupnp not handling the logging");
1721  }
1722  if(logoutfile)
1723  {
1724  g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE | \
1725  G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR, xupnp_logger, NULL);
1726  }
1727 
1728  char* configfilename = argv[1];
1729 
1730  rfc_enabled = check_rfc();
1731  if(!rfc_enabled)
1732  {
1733  g_message("Running Older Xdiscovery");
1734  }
1735 
1736  if (readconffile(configfilename)==FALSE)
1737  {
1738  g_message("Unable to find xdevice config, Loading default settings ");
1739  // disConf->discIf = g_string_assign(disConf->discIf, "eth1");
1740  // disConf->gwIf = g_string_assign(disConf->gwIf, "eth1");
1741  // disConf->gwSetupFile = g_string_assign(disConf->gwSetupFile, "/lib/rdk/gwSetup.sh");
1742  // disConf->logFile = g_string_assign(disConf->logFile, "/opt/logs/xdiscovery.log");
1743  // disConf->outputJsonFile = g_string_assign(disConf->outputJsonFile, "/opt/output.json");
1744  // disConf->GwPriority = 500
1745  // disConf->enableGwSetup = false
1746  exit(1);
1747  }
1748 
1749  /* int result = getipaddress(disConf->discIf,ipaddress,ipv6Enabled);
1750 
1751  if (!result)
1752  {
1753  fprintf(stderr,"Could not locate the ipaddress of the discovery interface %s\n", disConf->discIf);
1754  g_critical("Could not locate the ipaddress of the discovery interface %s\n", disConf->discIf);
1755  exit(1);
1756  }
1757  else
1758  g_message("ipaddress of the interface %s\n", ipaddress);
1759  */
1760  gchar **tokens = g_strsplit_set(disConf->discIf,",", -1);
1761  guint toklength = g_strv_length(tokens);
1762  guint loopvar=0;
1763  for (loopvar=0; loopvar<toklength; loopvar++)
1764  {
1765  if ((strlen(g_strstrip(tokens[loopvar])) > 0))
1766  {
1767  int result = getipaddress(g_strstrip(tokens[loopvar]),ipaddress,ipv6Enabled);
1768  if (result)
1769  {
1770  g_message(" \n ***Got Ip address for interface = %s ipaddr = %s *****",g_strstrip(tokens[loopvar]),ipaddress);
1771  g_stpcpy(disConf->discIf,g_strstrip(tokens[loopvar]));
1772  g_stpcpy(disConf->gwIf,g_strstrip(tokens[loopvar]));
1773  bInterfaceReady=TRUE;
1774  break;
1775  }
1776  else
1777  {
1778  guint retries=3;
1779  int ipaddr = 0;
1780  for (retries=3; retries>0; retries--) {
1781  sleep(1); //sleep for every retries
1782  ipaddr = getipaddress(g_strstrip(tokens[loopvar]),ipaddress,ipv6Enabled);
1783  if (ipaddr) {
1784  g_message("\n **Got Ip address for interface = %s with retries = %d ipaddr = %s **",g_strstrip(tokens[loopvar]),retries,ipaddress);
1785  g_stpcpy(disConf->discIf,g_strstrip(tokens[loopvar]));
1786  g_stpcpy(disConf->gwIf,g_strstrip(tokens[loopvar]));
1787  bInterfaceReady=TRUE;
1788  break; //Exiting Inner for loop
1789  }
1790  }
1791  if (!ipaddr) {
1792  g_message("Could not locate the ipaddress of the broadcast interface %s continue with next ", g_strstrip(tokens[loopvar]));
1793  bInterfaceReady=FALSE;
1794  }
1795  else
1796  break; //Exiting outer for loop
1797  }
1798  }
1799  }
1800  g_strfreev(tokens);
1801  if ( FALSE == bInterfaceReady)
1802  {
1803 
1804  fprintf(stderr,"Could not locate the ipaddress of the discovery interface %s\n", disConf->discIf);
1805  g_critical("Could not locate the ipaddress of the discovery interface %s\n", disConf->discIf);
1806  exit(1);
1807  }
1808 
1809  g_message("Starting xdiscovery service on interface %s", disConf->discIf);
1810  g_print("Starting xdiscovery service on interface %s\n", disConf->discIf);
1811 
1812 
1813  bcastmac = (gchar *)getmacaddress(disConf->discIf);
1814 #ifndef GUPNP_1_2
1815  #ifdef GUPNP_0_14
1816  main_context = g_main_context_new();
1817  context = gupnp_context_new (main_context, disConf->discIf, host_port, &error);
1818  #else
1819  context = gupnp_context_new (NULL, disConf->discIf, host_port, &error);
1820  #endif
1821 #else
1822  context = gupnp_context_new (disConf->discIf, host_port, &error);
1823 #endif
1824 
1825  if (error) {
1826  g_message ("Error creating the GUPnP context: %s", error->message);
1827  g_critical("Error creating the XUPnP context on %s:%d Error:%s", disConf->discIf, host_port, error->message);
1828  g_error_free (error);
1829  return EXIT_FAILURE;
1830  }
1831 
1832 #if defined(USE_XUPNP_IARM) || defined(USE_XUPNP_IARM_BUS)
1833  gboolean iarminit = XUPnP_IARM_Init();
1834  if (iarminit==true)
1835  {
1836  //g_print("IARM init success");
1837  g_message("XUPNP IARM init success");
1838  }
1839  else
1840  {
1841  //g_print("IARM init failure");
1842  g_critical("XUPNP IARM init failed");
1843  }
1844 #endif
1845 
1846 #ifdef GUPNP_GENERIC_MEDIA_RENDERER
1848 #endif //GUPNP_GENERIC_MEDIA_RENDERER
1849 
1850  //context = gupnp_context_new (main_context, host_ip, host_port, NULL);
1851  gupnp_context_set_subscription_timeout(context, 0);
1852  if(rfc_enabled)
1853  {
1854  //Get account Id of the control point.
1855  if (!getAccountId(accountId)) {
1856  g_message("Failed to retrieve AccountId of the control point");
1857  }
1858 #ifndef BROADBAND
1859  if(xPKI_check_rfc() == 1)
1860  {
1861  cert_File= g_strdup ("/tmp/xpki_cert");
1862  key_File= g_strdup ("/tmp/xpki_key");
1863  g_message("Using xPKI certs for handshaking");
1864  }
1865 #endif
1866  if ( ( cert_File == NULL ) && (key_File == NULL )){
1867  if (g_path_is_absolute (disConf->disCertFile)) {
1868  cert_File= g_strdup (disConf->disCertFile);
1869  }
1870  else {
1871  cert_File = g_build_filename (disConf->disCertPath, disConf->disCertFile, NULL);
1872  }
1873  if (g_path_is_absolute (disConf->disKeyFile)) {
1874  key_File= g_strdup (disConf->disKeyFile);
1875  }
1876  else {
1877  key_File = g_build_filename (disConf->disKeyPath, disConf->disKeyFile, NULL);
1878  }
1879  }
1880  if (((cert_File != NULL) && (key_File !=NULL)) && ((g_file_test(cert_File, G_FILE_TEST_EXISTS)) && (g_file_test(key_File, G_FILE_TEST_EXISTS))
1881  && (g_file_test(ca_File, G_FILE_TEST_EXISTS)))) {
1882 
1883 #ifndef GUPNP_1_2
1884  upnpContextDeviceProtect = gupnp_context_new_s ( NULL, disConf->discIf, DEVICE_PROTECTION_CONTEXT_PORT, cert_File, key_File, &error);
1885 #else
1886  upnpContextDeviceProtect = gupnp_context_new_s ( disConf->discIf, DEVICE_PROTECTION_CONTEXT_PORT, cert_File, key_File, &error);
1887 #endif
1888  if (error) {
1889  g_printerr ("Error creating the Device Protection Broadcast context: %s\n",
1890  error->message);
1891  /* g_clear_error() frees the GError *error memory and reset pointer if set in above operation */
1892  g_clear_error(&error);
1893  rfc_enabled = 0;
1894  }
1895  else {
1896 
1897 #ifdef BROADBAND
1898  int ret = 0;
1899  //initialize the device protection white list
1900  g_message("calling dp whitelistInit ");
1901  ret = dp_wlistInit();
1902  if (!ret) {
1903  g_message("initialization of dp whitelist successful ");
1904  }
1905 #endif
1906 
1907  gupnp_context_set_subscription_timeout(upnpContextDeviceProtect, 0);
1908  xupnp_tlsinteraction = g_object_new (xupnp_tls_interaction_get_type (), NULL);
1909  g_message("tls interaction object created");
1910  // Set TLS config params here.
1911  gupnp_context_set_tls_params(upnpContextDeviceProtect,ca_File,key_File, xupnp_tlsinteraction);
1912 
1913  cp_client = gupnp_control_point_new(upnpContextDeviceProtect, "urn:schemas-upnp-org:device:X1Renderer:1");
1914  g_signal_connect (cp_client,"device-proxy-available", G_CALLBACK (device_proxy_available_cb_client), NULL);
1915  g_signal_connect (cp_client,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb_client), NULL);
1916  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp_client), TRUE);
1917  g_message("X1Renderer controlpoint created");
1918 
1919  cp_gw = gupnp_control_point_new(upnpContextDeviceProtect, "urn:schemas-upnp-org:device:X1VideoGateway:1");
1920  g_signal_connect (cp_gw,"device-proxy-available", G_CALLBACK (device_proxy_available_cb_gw), NULL);
1921  g_signal_connect (cp_gw,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb_gw), NULL);
1922  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp_gw), TRUE);
1923  g_message("X1VideoGateway controlpoint created");
1924 
1925  cp_bgw = gupnp_control_point_new(upnpContextDeviceProtect, "urn:schemas-upnp-org:device:X1BroadbandGateway:1");
1926  g_signal_connect (cp_bgw,"device-proxy-available", G_CALLBACK (device_proxy_available_cb_bgw), NULL);
1927  g_signal_connect (cp_bgw,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb_bgw), NULL);
1928  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp_bgw), TRUE);
1929  g_message("X1BroadbandGateway controlpoint created");
1930  }
1931  }
1932  else {
1933  g_message("DeviceProtection Error: check Cert File or Key File or CA file not existing");
1934  rfc_enabled = 0;
1935  }
1936  }
1937 
1938  cp = gupnp_control_point_new(context, "urn:schemas-upnp-org:device:BasicDevice:1");
1939  g_signal_connect (cp,"device-proxy-available", G_CALLBACK (device_proxy_available_cb), NULL);
1940  g_signal_connect (cp,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb), NULL);
1941  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
1942 
1943 #ifdef GUPNP_GENERIC_MEDIA_RENDERER
1944  registerBrowserConfig(context);
1945 #endif //GUPNP_GENERIC_MEDIA_RENDERER
1946 
1947 #ifdef LOGMILESTONE
1948  logMilestone("UPNP_START_DISCOVERY");
1949 #else
1950  g_message("UPNP_START_DISCOVERY");
1951 #endif
1952 
1953 #ifdef GUPNP_0_19
1954  main_loop = g_main_loop_new (NULL, FALSE);
1955 #else
1956  main_loop = g_main_loop_new (main_context, FALSE);
1957 #endif
1958  if(!bSerialNum)
1959  getserialnum(ownSerialNo);
1960 
1961  g_thread_create(verify_devices, NULL,FALSE, NULL);
1962  g_message("Started discovery on interface %s", disConf->discIf);
1963  g_main_loop_run (main_loop);
1964  g_main_loop_unref (main_loop);
1965  g_object_unref (cp);
1966  if(rfc_enabled)
1967  {
1968  g_object_unref (cp_client);
1969  g_object_unref (cp_gw);
1970  g_object_unref (cp_bgw);
1971  g_object_unref (upnpContextDeviceProtect);
1972  g_object_unref (xupnp_tlsinteraction);
1973 
1974  }
1975 #ifdef GUPNP_GENERIC_MEDIA_RENDERER
1977 #endif //GUPNP_GENERIC_MEDIA_RENDERER
1978 
1979  if (cert_File != NULL) {
1980  g_free(cert_File);
1981  }
1982  if (key_File != NULL) {
1983  g_free(key_File);
1984  }
1985  g_object_unref (context);
1986  if(logoutfile)
1987  {
1988  fclose (logoutfile);
1989  }
1990  return 0;
1991 }
1992 /**
1993  * @brief This function is used to retrieve a boolean parameter from discovered data.
1994  * Use this function only when there are no parameters passed to the action call
1995  *
1996  * @param[in] sproxy The Service proxy object
1997  * @param[in] requestFn The required parameter to be retrieved
1998  * @param[in] responseFn The function to retrieve requried function
1999  * @param[out] result the result to be stored.
2000  * @param[in] isInCriticalPath if true, a log message will be printed for telemetry
2001  * @return Returns TRUE if the gateway service requests processed successfully else returns FALSE.
2002  * @ingroup XUPNP_XDISCOVERY_FUNC
2003  */
2004 
2005 gboolean processBooleanRequest(const GUPnPServiceProxy *sproxy ,const char * requestFn,
2006  const char * responseFn,gboolean * result, gboolean isInCriticalPath)
2007 {
2008  GError *error = NULL;
2009 
2010 #ifdef GUPNP_1_2
2011  GUPnPServiceProxyAction *action;
2012  action = gupnp_service_proxy_action_new (requestFn, NULL);
2013  gupnp_service_proxy_call_action ((GUPnPServiceProxy *)sproxy, action, NULL, &error);
2014 
2015  if( NULL == error )
2016  {
2017  gupnp_service_proxy_action_get_result (action,
2018  &error, responseFn, G_TYPE_BOOLEAN, result, NULL);
2019  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2020 
2021  }
2022 #else
2023  gupnp_service_proxy_send_action ((GUPnPServiceProxy *)sproxy, requestFn, &error, NULL, responseFn, G_TYPE_BOOLEAN, result ,NULL);
2024 #endif
2025  if ( NULL != error ) //Didn't went well
2026  {
2027  g_message ("%s process gw services Error: %s\n", requestFn, error->message);
2028  if ( isInCriticalPath ) // Update telemetry
2029  {
2030  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,%s",error->code, requestFn);
2031  }
2032  g_clear_error(&error);
2033  return FALSE;
2034  }
2035  return TRUE;
2036 }
2037 
2038 /**
2039  * @brief This function is used to retrieve a string parameter from discovered data.
2040  * Use this function only when there are no parameters passed to the action call
2041  *
2042  * @param[in] sproxy The Service proxy object
2043  * @param[in] requestFn The required parameter to be retrieved
2044  * @param[in] responseFn The function to retrieve requried function
2045  * @param[out] result the result to be stored.
2046  * @param[in] isInCriticalPath if true, a log message will be printed for telemetry
2047  * @return Returns TRUE if the gateway service requests processed successfully else returns FALSE.
2048  * @ingroup XUPNP_XDISCOVERY_FUNC
2049  */
2050 gboolean processStringRequest(const GUPnPServiceProxy *sproxy ,const char * requestFn,
2051  const char * responseFn, gchar ** result, gboolean isInCriticalPath)
2052 {
2053  GError *error = NULL;
2054 
2055 #ifdef GUPNP_1_2
2056  GUPnPServiceProxyAction *action;
2057  action = gupnp_service_proxy_action_new (requestFn, NULL);
2058  gupnp_service_proxy_call_action ((GUPnPServiceProxy *)sproxy, action, NULL, &error);
2059 
2060  if( NULL == error )
2061  {
2062  gupnp_service_proxy_action_get_result (action,
2063  &error, responseFn, G_TYPE_STRING, result, NULL);
2064  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2065 
2066  }
2067 #else
2068  gupnp_service_proxy_send_action ((GUPnPServiceProxy *)sproxy, requestFn, &error,NULL, responseFn, G_TYPE_STRING, result ,NULL);
2069 #endif
2070  if ( NULL != error ) //Didn't went well
2071  {
2072  g_message ("%s process gw services Error: %s\n", requestFn, error->message);
2073  if ( isInCriticalPath ) // Update telemetry
2074  {
2075  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,%s",error->code, requestFn);
2076  }
2077  g_clear_error(&error);
2078  return FALSE;
2079  }
2080  return TRUE;
2081 }
2082 
2083 /**
2084  * @brief This function is used to retrieve a int parameter from discovered data.
2085  * Use this function only when there are no parameters passed to the action call
2086  *
2087  * @param[in] sproxy The Service proxy object
2088  * @param[in] requestFn The required parameter to be retrieved
2089  * @param[in] responseFn The function to retrieve requried function
2090  * @param[out] result the result to be stored.
2091  * @param[in] isInCriticalPath if true, a log message will be printed for telemetry
2092  * @return Returns TRUE if the gateway service requests processed successfully else returns FALSE.
2093  * @ingroup XUPNP_XDISCOVERY_FUNC
2094  */
2095 gboolean processIntRequest(const GUPnPServiceProxy *sproxy ,const char * requestFn,
2096  const char * responseFn,guint * result, gboolean isInCriticalPath)
2097 {
2098  GError *error = NULL;
2099 
2100 #ifdef GUPNP_1_2
2101  GUPnPServiceProxyAction *action;
2102  action = gupnp_service_proxy_action_new (requestFn, NULL);
2103  gupnp_service_proxy_call_action ((GUPnPServiceProxy *)sproxy, action, NULL, &error);
2104 
2105  if( NULL == error )
2106  {
2107  gupnp_service_proxy_action_get_result (action,
2108  &error, responseFn, G_TYPE_INT, result, NULL);
2109  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2110 
2111  }
2112 #else
2113  gupnp_service_proxy_send_action ((GUPnPServiceProxy *)sproxy, requestFn , &error,NULL, responseFn, G_TYPE_INT, result ,NULL);
2114 #endif
2115  if ( NULL != error ) //Didn't went well
2116  {
2117  g_message ("%s process gw services Error: %s\n", requestFn, error->message);
2118  if ( isInCriticalPath ) // Update telemetry
2119  {
2120  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,%s",error->code, requestFn);
2121  }
2122  g_clear_error(&error);
2123  return FALSE;
2124  }
2125  return TRUE;
2126 }
2127 
2128 /**
2129  * @brief This function is used to get attributes of different Gateway services using GUPnP Service Proxy.
2130  *
2131  * GUPnP Service Proxy sends commands to a remote UPnP service and handles incoming event notifications.
2132  * It will request the proxy to get services and attributes such as:
2133  * - Base TRM URL.
2134  * - Playback URL.
2135  * - Gateway IP.
2136  * - DNS Configuration.
2137  * - Device Type.
2138  * - Time Zone.
2139  * - DST (Daylight Saving Time).
2140  * - MAC Address.
2141  * - System ID and so on.
2142  *
2143  * @param[in] sproxy Address of the GUPnP Service Proxy instance.
2144  * @param[in] gwData Address of the Structure holding gateway service attributes.
2145  *
2146  * @return Returns TRUE if the gateway service requests processed successfully else returns FALSE.
2147  * @ingroup XUPNP_XDISCOVERY_FUNC
2148  */
2149 gboolean process_gw_services(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2150 {
2151  /* Does not look elegant, but call all the actions one after one - Seems like
2152  UPnP service proxy does not provide a way to call all the actions in a list
2153  */
2154  GError *error = NULL;
2155  gchar *temp=NULL;
2156  guint temp_i=0;
2157  gboolean temp_b=FALSE;
2158 
2159  /* Coverity Fix CID: 21875 REVERSE_INULL */
2160  if(gwData == NULL)
2161  return FALSE;
2162 
2163  g_message("Entering into process_gw_services ");
2164 
2165 #ifdef GUPNP_1_2
2166  GUPnPServiceProxyAction * action = gupnp_service_proxy_action_new ("GetIsGateway", "deviceProtection", G_TYPE_BOOLEAN, FALSE, "macAddr", G_TYPE_STRING, bcastmac, "ipAddr",G_TYPE_STRING, ipaddress,NULL);
2167  gupnp_service_proxy_call_action (sproxy, action, NULL, &error);
2168  if (error == NULL)
2169  {
2170  gupnp_service_proxy_action_get_result (action,
2171  &error, "IsGateway", G_TYPE_BOOLEAN, &temp_b, NULL);
2172  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2173  }
2174 #else
2175  gupnp_service_proxy_send_action (sproxy, "GetIsGateway", &error,"deviceProtection", G_TYPE_BOOLEAN, FALSE, "macAddr", G_TYPE_STRING, bcastmac, "ipAddr",G_TYPE_STRING, ipaddress,NULL,"IsGateway", G_TYPE_BOOLEAN, &temp_b ,NULL);
2176 #endif
2177  if (error!=NULL)
2178  {
2179  g_message ("GetIsGateway process gw services Error: %s", error->message);
2180  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,IsGateway",error->code);
2181  g_clear_error(&error);
2182  return FALSE;
2183  }
2184  else
2185  {
2186  gwData->isgateway = (gboolean)temp_b;
2187  }
2188  if ( processStringRequest(sproxy, "GetRecvDevType", "RecvDevType" , &temp, FALSE))
2189  {
2190  g_string_assign(gwData->recvdevtype,temp);
2191  g_free(temp);
2192  }
2193 
2194  if ( processStringRequest(sproxy, "GetBuildVersion", "BuildVersion" , &temp, FALSE))
2195  {
2196  g_string_assign(gwData->buildversion,temp);
2197  g_free(temp);
2198  }
2199 
2200  if ( processStringRequest(sproxy, "GetDeviceName", "DeviceName" , &temp, FALSE))
2201  {
2202  g_string_assign(gwData->devicename,temp);
2203  g_free(temp);
2204  }
2205 
2206  if ( processStringRequest(sproxy, "GetDeviceType", "DeviceType" , &temp, FALSE))
2207  {
2208  g_string_assign(gwData->devicetype,temp);
2209  g_free(temp);
2210  }
2211 
2212  if (! processStringRequest(sproxy, "GetBcastMacAddress", "BcastMacAddress" , &temp, TRUE))
2213  {
2214  return FALSE;
2215  }
2216  else
2217  {
2218  g_string_assign(gwData->bcastmacaddress,temp);
2219  g_free(temp);
2220  }
2221 
2222  if(!strcasestr(g_strstrip(gwData->devicetype->str),"XI") )
2223  {
2224  if (! processStringRequest(sproxy, "GetBaseUrl", "BaseUrl" , &temp, TRUE))
2225  {
2226  return FALSE;
2227  }
2228  else
2229  {
2230  g_string_assign(gwData->baseurl,temp);
2231  g_free(temp);
2232  }
2233 
2234  if (! processStringRequest(sproxy, "GetBaseTrmUrl", "BaseTrmUrl" , &temp, TRUE))
2235  {
2236  return FALSE;
2237  }
2238  else
2239  {
2240  g_string_assign(gwData->basetrmurl,temp);
2241  g_free(temp);
2242  }
2243  //Do not return error as the boxes which are not running single step tuning code base could still exist in the network
2244  if ( processStringRequest(sproxy, "GetGatewayIP", "GatewayIP" , &temp, FALSE))
2245  {
2246  g_string_assign(gwData->gwyip,temp);
2247  g_free(temp);
2248  }
2249 
2250  if ( processStringRequest(sproxy, "GetClientIP", "ClientIP" , &temp, FALSE))
2251  {
2252  g_string_assign(gwData->clientip,temp);
2253  g_free(temp);
2254  }
2255 
2256  if ( processStringRequest(sproxy, "GetGatewayIPv6", "GatewayIPv6" , &temp, FALSE))
2257  {
2258  g_string_assign(gwData->gwyipv6,temp);
2259  g_free(temp);
2260  }
2261 
2262  if ( processStringRequest(sproxy, "GetGatewayStbIP", "GatewayStbIP" , &temp, FALSE))
2263  {
2264  g_string_assign(gwData->gatewaystbip,temp);
2265  g_free(temp);
2266  }
2267  if ( processStringRequest(sproxy, "GetIpv6Prefix", "Ipv6Prefix" , &temp, FALSE))
2268  {
2269  g_string_assign(gwData->ipv6prefix,temp);
2270  g_free(temp);
2271 #ifdef LOGMILESTONE
2272  if (gwData && gwData->ipv6prefix && gwData->ipv6prefix->str && (g_strcmp0(gwData->ipv6prefix->str, "") != 0))
2273  {
2274  logMilestone("UPNP_RECV_IPV6_PREFIX");
2275  }
2276 #else
2277  g_message("UPNP_RECV_IPV6_PREFIX");
2278 #endif
2279  }
2280 
2281  if ( processStringRequest(sproxy, "GetDnsConfig", "DnsConfig" , &temp, FALSE))
2282  {
2283  g_string_assign(gwData->dnsconfig,temp);
2284  g_free(temp);
2285  }
2286  if ( processStringRequest(sproxy,"GetPlaybackUrl","PlaybackUrl", &temp, TRUE))
2287  {
2288  g_string_assign(gwData->playbackurl,temp);
2289  g_free(temp);
2290  }
2291  else
2292  {
2293  return FALSE;
2294  }
2295  g_message("GetPlaybackUrl = %s",gwData->playbackurl->str);
2296 
2297  if ( processStringRequest(sproxy, "GetSystemIds", "SystemIds" , &temp, FALSE))
2298  {
2299  g_string_assign(gwData->systemids,temp);
2300  g_free(temp);
2301  }
2302 
2303  if ( processStringRequest(sproxy, "GetTimeZone", "TimeZone" , &temp, FALSE))
2304  {
2305  g_string_assign(gwData->dsgtimezone,temp);
2306  g_free(temp);
2307  }
2308 
2309  if ( processStringRequest(sproxy, "GetHosts", "Hosts" , &temp, FALSE))
2310  {
2311  g_string_assign(gwData->etchosts,temp);
2312  g_free(temp);
2313  }
2314 
2315  if ( !processBooleanRequest(sproxy, "GetRequiresTRM", "RequiresTRM" , &temp_b, TRUE))
2316  {
2317  return FALSE;
2318  }
2319  else
2320  {
2321  gwData->requirestrm = (gboolean)temp_b;
2322  }
2323 
2324  if ( processStringRequest(sproxy, "GetHostMacAddress", "HostMacAddress" , &temp, FALSE))
2325  {
2326  g_string_assign(gwData->hostmacaddress,temp);
2327  g_free(temp);
2328  }
2329 
2330  if ( processIntRequest( sproxy, "GetRawOffSet", "RawOffSet" , &temp_i, FALSE))
2331  {
2332  gwData->rawoffset = (gint)temp_i;
2333  }
2334 
2335  if ( processIntRequest( sproxy, "GetDSTSavings", "DSTSavings" , &temp_i, FALSE))
2336  {
2337  gwData->dstsavings = (gint)temp_i;
2338  }
2339 
2340  if ( processBooleanRequest( sproxy, "GetUsesDaylightTime", "UsesDaylightTime" , &temp_b, FALSE))
2341  {
2342  gwData->usesdaylighttime = (gboolean)temp_b;
2343  }
2344 
2345  if ( processIntRequest( sproxy, "GetDSTOffset", "DSTOffset" , &temp_i, FALSE))
2346  {
2347  gwData->dstoffset = (gint)temp_i;
2348  }
2349  } // If discovered device is XG1 or RNG device
2350  else
2351  {
2352  g_message("Discovered a Xi device ");
2353 
2354  if ( processStringRequest(sproxy, "GetDataGatewayIPaddress", "DataGatewayIPaddress" , &temp, FALSE))
2355  {
2356  g_string_assign(gwData->dataGatewayIPaddress,temp);
2357  g_free(temp);
2358  }
2359  g_message("GetDataGatewayIPaddress = %s",gwData->dataGatewayIPaddress->str);
2360  }
2361 #ifndef CLIENT_XCAL_SERVER
2362 
2363  //if ((gwData->isgateway == TRUE) && (gwData->isOwnGateway == FALSE))
2364  if (gwData->isOwnGateway == FALSE)
2365  {
2366  if (replace_local_device_ip(gwData) == TRUE)
2367  {
2368  g_message("Replaced MocaIP for %s with localhost", gwData->serial_num->str);
2369  }
2370  }
2371 #endif
2372  gwData->devFoundFlag = TRUE;
2373  gwData->isDevRefactored = FALSE;
2374  if (update_gwylist(gwData)==FALSE )
2375  {
2376  g_message("Failed to update gw data into the list");
2377  /*Coverity Fix CID: 28232 PRINTF_ARGS_MISMATCH */
2378  g_critical("Unable to update the gateway-%s in the device list",gwData->serial_num->str);
2379  return FALSE;
2380  }
2381  g_message("Exiting from process_gw_services ");
2382  return TRUE;
2383 }
2384 
2385 gboolean process_gw_services_identity(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2386 {
2387  /* Does not look elegant, but call all the actions one after one - Seems like
2388  UPnP service proxy does not provide a way to call all the actions in a list
2389  */
2390  GError *error = NULL;
2391  gchar *temp=NULL;
2392 
2393  g_message("Entering into process_gw_services_identity ");
2394 /*
2395  DELIA-47613 : Need to use direct calls whenever there is an input parameter(s) to the service proxy call
2396 */
2397 #ifdef GUPNP_1_2
2398  GUPnPServiceProxyAction * action = gupnp_service_proxy_action_new ("GetAccountId", "SAccountId", G_TYPE_STRING, accountId, "macAddr", G_TYPE_STRING, bcastmac, "ipAddr",G_TYPE_STRING, ipaddress, NULL);
2399  gupnp_service_proxy_call_action (sproxy, action, NULL, &error);
2400  if (error == NULL)
2401  {
2402  gupnp_service_proxy_action_get_result (action,
2403  &error, "GAccountId", G_TYPE_STRING, &temp, NULL);
2404  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2405  }
2406 #else
2407  gupnp_service_proxy_send_action (sproxy, "GetAccountId", &error,"SAccountId", G_TYPE_STRING, accountId, "macAddr", G_TYPE_STRING, bcastmac, "ipAddr",G_TYPE_STRING, ipaddress, NULL, "GAccountId", G_TYPE_STRING, &temp, NULL);
2408 #endif
2409  if (error!=NULL)
2410  {
2411  g_message ("GetAccountId process gw Identity services Error: %s", error->message);
2412  g_clear_error(&error);
2413  }
2414  else
2415  {
2416  g_message ("Received account id: %s", temp);
2417  g_string_assign(gwData->accountid, temp);
2418  g_free(temp);
2419  }
2420 
2421  if ( processStringRequest(sproxy, "GetRecvDevType", "RecvDevType" , &temp, FALSE))
2422  {
2423  g_string_assign(gwData->recvdevtype, temp);
2424  g_free(temp);
2425  }
2426  if ( processStringRequest(sproxy, "GetBuildVersion", "BuildVersion" , &temp, FALSE))
2427  {
2428  g_string_assign(gwData->buildversion, temp);
2429  g_free(temp);
2430  }
2431  if ( processStringRequest(sproxy, "GetDeviceName", "DeviceName" , &temp, FALSE))
2432  {
2433  g_string_assign(gwData->devicename, temp);
2434  g_free(temp);
2435  }
2436  if ( processStringRequest(sproxy, "GetDeviceType", "DeviceType" , &temp, FALSE))
2437  {
2438  g_string_assign(gwData->devicetype, temp);
2439  g_free(temp);
2440  }
2441  if ( processStringRequest(sproxy, "GetModelClass", "ModelClass" , &temp, FALSE))
2442  {
2443  g_string_assign(gwData->modelclass, temp);
2444  g_free(temp);
2445  }
2446  if ( processStringRequest(sproxy, "GetModelNumber", "ModelNumber" , &temp, FALSE))
2447  {
2448  g_string_assign(gwData->modelnumber, temp);
2449  g_free(temp);
2450  }
2451  if ( processStringRequest(sproxy, "GetDeviceId", "DeviceId" , &temp, FALSE))
2452  {
2453  g_string_assign(gwData->deviceid, temp);
2454  g_free(temp);
2455  }
2456  if ( processStringRequest(sproxy, "GetHardwareRevision", "HardwareRevision" , &temp, FALSE))
2457  {
2458  g_string_assign(gwData->hardwarerevision, temp);
2459  g_free(temp);
2460  }
2461  if ( processStringRequest(sproxy, "GetSoftwareRevision", "SoftwareRevision" , &temp, FALSE))
2462  {
2463  g_string_assign(gwData->softwarerevision, temp);
2464  g_free(temp);
2465  }
2466  if ( processStringRequest(sproxy, "GetManagementUrl", "ManagementURL" , &temp, FALSE))
2467  {
2468  g_string_assign(gwData->managementurl, temp);
2469  g_free(temp);
2470  }
2471  if ( processStringRequest(sproxy, "GetMake", "Make" , &temp, FALSE))
2472  {
2473  g_string_assign(gwData->make, temp);
2474  g_free(temp);
2475  }
2476  if ( processStringRequest(sproxy, "GetReceiverId", "ReceiverId" , &temp, FALSE))
2477  {
2478  g_string_assign(gwData->receiverid, temp);
2479  g_free(temp);
2480  }
2481  if ( processStringRequest(sproxy, "GetClientIP", "ClientIP" , &temp, FALSE))
2482  {
2483  g_string_assign(gwData->clientip, temp);
2484  g_free(temp);
2485  }
2486  if ( processStringRequest(sproxy, "GetBcastMacAddress", "BcastMacAddress" , &temp, FALSE))
2487  {
2488  g_string_assign(gwData->bcastmacaddress, temp);
2489  g_free(temp);
2490  }
2491 
2492  g_message("Exiting from process_gw_services_identity ");
2493  return TRUE;
2494 }
2495 
2496 
2497 gboolean process_gw_services_media_config(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2498 {
2499  /* Does not look elegant, but call all the actions one after one - Seems like
2500  UPnP service proxy does not provide a way to call all the actions in a list
2501  */
2502  gchar *temp=NULL;
2503 
2504  g_message("Entering into process_gw services_media_config ");
2505  if ( processStringRequest(sproxy, "GetPlaybackUrl", "PlaybackUrl" , &temp, FALSE))
2506  {
2507  g_string_assign(gwData->playbackurl, temp);
2508  g_free(temp);
2509  }
2510 /* GError *error = NULL;
2511  gupnp_service_proxy_send_action (sproxy, "GetFogTsbUrl",&error,NULL,"FogTsbUrl",G_TYPE_STRING, gwData->fogtsburl ,NULL);
2512  if (error!=NULL)
2513  {
2514  g_message (" GetFogTsbUrl process gw services Error: %s\n", error->message);
2515  g_clear_error(&error);
2516  }*/
2517  g_message("Exiting from process_gw_services_media_config ");
2518  return TRUE;
2519 }
2520 
2521 gboolean process_gw_services_gateway_config(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2522 {
2523  /* Does not look elegant, but call all the actions one after one - Seems like
2524  UPnP service proxy does not provide a way to call all the actions in a list
2525  */
2526  GError *error = NULL;
2527  gchar *temp=NULL;
2528  gboolean temp_b=FALSE;
2529 
2530  g_message("Entering into process_gw_services_gateway_config ");
2531  if ( processStringRequest(sproxy, "GetDataGatewayIPaddress", "DataGatewayIPaddress" , &temp, FALSE))
2532  {
2533  g_string_assign(gwData->dataGatewayIPaddress, temp);
2534  g_free(temp);
2535  }
2536 
2537  if ( processStringRequest(sproxy, "GetGatewayStbIP", "GatewayStbIP" , &temp, FALSE))
2538  {
2539  g_string_assign(gwData->gatewaystbip, temp);
2540  g_free(temp);
2541  }
2542  if ( processStringRequest(sproxy, "GetIpv6Prefix", "Ipv6Prefix" , &temp, FALSE ))
2543  {
2544  g_string_assign(gwData->ipv6prefix, temp);
2545  g_free(temp);
2546  }
2547  if ( processStringRequest(sproxy, "GetDnsConfig", "DnsConfig" , &temp, FALSE))
2548  {
2549  g_string_assign(gwData->dnsconfig, temp);
2550  g_free(temp);
2551  }
2552  if ( processStringRequest(sproxy, "GetDeviceName", "DeviceName" , &temp, FALSE))
2553  {
2554  g_string_assign(gwData->devicename, temp);
2555  g_free(temp);
2556  }
2557  if ( processStringRequest(sproxy, "GetBcastMacAddress", "BcastMacAddress" , &temp, FALSE))
2558  {
2559  g_string_assign(gwData->bcastmacaddress,temp);
2560  g_free(temp);
2561  }
2562  if ( processStringRequest(sproxy, "GetGatewayIPv6", "GatewayIPv6" , &temp, FALSE))
2563  {
2564  g_string_assign(gwData->gwyipv6, temp);
2565  g_free(temp);
2566  }
2567  if ( processStringRequest(sproxy, "GetGatewayIP", "GatewayIP" , &temp, FALSE))
2568  {
2569  g_string_assign(gwData->gwyip, temp);
2570  g_free(temp);
2571  }
2572  if ( processStringRequest(sproxy, "GetHostMacAddress", "HostMacAddress" , &temp, FALSE))
2573  {
2574  g_string_assign(gwData->hostmacaddress, temp);
2575  g_free(temp);
2576  }
2577  if ( processStringRequest(sproxy, "GetHosts", "Hosts" , &temp, FALSE))
2578  {
2579  g_string_assign(gwData->etchosts, temp);
2580  g_free(temp);
2581  }
2582 #ifdef GUPNP_1_2
2583  GUPnPServiceProxyAction * action = gupnp_service_proxy_action_new ("GetIsGateway", "deviceProtection", G_TYPE_BOOLEAN,TRUE, NULL);
2584  gupnp_service_proxy_call_action (sproxy, action, NULL, &error);
2585  if (error == NULL)
2586  {
2587  gupnp_service_proxy_action_get_result (action,
2588  &error, "IsGateway", G_TYPE_BOOLEAN, &temp_b, NULL);
2589  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
2590  }
2591 
2592 #else
2593  gupnp_service_proxy_send_action (sproxy, "GetIsGateway", &error, "deviceProtection", G_TYPE_BOOLEAN, TRUE, NULL,"IsGateway", G_TYPE_BOOLEAN, &temp_b ,NULL);
2594 #endif
2595  if (error!=NULL)
2596  {
2597  g_message ("GetIsGateway process gw services Error: %s", error->message);
2598  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,IsGateway",error->code);
2599  g_clear_error(&error);
2600  return FALSE;
2601  }
2602  else
2603  {
2604  gwData->isgateway = (gboolean)temp_b;
2605  }
2606 
2607  if ( processStringRequest(sproxy, "GetIPSubNet", "IPSubNet" , &temp, FALSE))
2608  {
2609  g_string_assign(gwData->ipSubNet, temp);
2610  if(temp && strlen(temp))
2611  addRouteToMocaBridge(temp);
2612  g_free(temp);
2613  }
2614 
2615  g_message("Exiting from process_gw_services_gateway_config ");
2616  return TRUE;
2617 }
2618 
2619 
2620 gboolean process_gw_services_time_config(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2621 {
2622  /* Does not look elegant, but call all the actions one after one - Seems like
2623  UPnP service proxy does not provide a way to call all the actions in a list
2624  */
2625  gchar *temp=NULL;
2626  guint temp_i=0;
2627  gboolean temp_b=FALSE;
2628 
2629  g_message("Entering into process_gw_services_time_config ");
2630  if ( processStringRequest(sproxy, "GetTimeZone", "TimeZone" , &temp, FALSE))
2631  {
2632  g_string_assign(gwData->dsgtimezone, temp);
2633  g_free(temp);
2634  }
2635  if ( processIntRequest( sproxy, "GetRawOffSet", "RawOffSet" , &temp_i, FALSE))
2636  {
2637  gwData->rawoffset = (gint)temp_i;
2638  }
2639  if ( processIntRequest( sproxy, "GetDSTSavings", "DSTSavings" , &temp_i, FALSE))
2640  {
2641  gwData->dstsavings = (gint)temp_i;
2642  }
2643  if ( processBooleanRequest( sproxy, "GetUsesDaylightTime", "UsesDaylightTime" , &temp_b, FALSE ))
2644  {
2645  gwData->usesdaylighttime = (gboolean)temp_b;
2646  }
2647  if ( processIntRequest( sproxy, "GetDSTOffset", "DSTOffset" , &temp_i, FALSE))
2648  {
2649  gwData->dstoffset = (gint)temp_i;
2650  }
2651  g_message("Exiting from process_gw_services_time_config ");
2652  return TRUE;
2653 }
2654 
2655 gboolean process_gw_services_qam_config(GUPnPServiceProxy *sproxy, GwyDeviceData* gwData)
2656 {
2657  /* Does not look elegant, but call all the actions one after one - Seems like
2658  UPnP service proxy does not provide a way to call all the actions in a list
2659  */
2660  gchar *temp=NULL;
2661  gboolean temp_b=FALSE;
2662 
2663  g_message("Entering into process_gw_services_qam_config ");
2664 
2665  //Do not return error as the boxes which are not running trm supported code base could still exist in the network
2666  if ( processStringRequest(sproxy, "GetBaseTrmUrl", "BaseTrmUrl" , &temp, FALSE))
2667  {
2668  g_string_assign(gwData->basetrmurl , temp);
2669  g_free(temp);
2670  }
2671  if ( processStringRequest(sproxy, "GetSystemIds", "SystemIds" , &temp, FALSE ))
2672  {
2673  g_string_assign(gwData->systemids , temp);
2674  g_free(temp);
2675  }
2676  if ( processBooleanRequest(sproxy, "GetRequiresTRM", "RequiresTRM" , &temp_b, TRUE))
2677  {
2678  gwData->requirestrm = (gboolean)temp_b;
2679  }
2680 /* GError *error = NULL;
2681  gupnp_service_proxy_send_action (sproxy, "GetVideoBaseUrl", &error,NULL,"VideoBaseUrl",G_TYPE_STRING, gwData->videobaseurl,NULL);
2682  if (error!=NULL)
2683  {
2684  g_message (" GetVideoBaseUrl process gw services Error: %s\n", error->message);
2685  g_clear_error(&error);
2686  }*/
2687 #ifndef CLIENT_XCAL_SERVER
2688  if (gwData->isOwnGateway == FALSE)
2689  {
2690  if (replace_local_device_ip(gwData) == TRUE)
2691  {
2692  g_message("Replaced MocaIP for %s with localhost", gwData->serial_num->str);
2693  }
2694  }
2695 #endif
2696  g_message("Exiting from process_gw_services_qam_config ");
2697  return TRUE;
2698 }
2699 
2700 /**
2701  * @brief Replace IP Address part of the Gateway URL attributes from home networking IP with the local host IP.
2702  * It Replaces the URL attribute of playbackurl, baseurl, basetrmurl.
2703  *
2704  * @param[in] gwyData Address of the structure holding Gateway attributes.
2705  *
2706  * @return Returns TRUE indicating the call has finished.
2707  * @ingroup XUPNP_XDISCOVERY_FUNC
2708  */
2710 {
2711  /*Coverity Fix CID:29376 RESOURCE_LEAK */
2712  char * tempStr = NULL;
2713 
2714  //g_print("replace: %s with %s\n", gwyData->gwyip->str, localHostIP);
2715  tempStr = replace_string(gwyData->playbackurl->str, gwyData->gwyip->str, (char *)localHostIP);
2716  g_string_assign(gwyData->playbackurl, tempStr);
2717  free(tempStr);
2718 
2719 
2720  tempStr = replace_string(gwyData->baseurl->str, gwyData->gwyip->str, (char *)localHostIP);
2721  g_string_assign(gwyData->baseurl,tempStr);
2722  free(tempStr);
2723 
2724 
2725  tempStr = replace_string(gwyData->basetrmurl->str, gwyData->gwyip->str, (char *)localHostIP);
2726  g_string_assign(gwyData->basetrmurl,tempStr);
2727  free(tempStr);
2728 
2729 
2730  g_message("baseurl:%s, playbackurl:%s, basetrumurl:%s", gwyData->baseurl->str,
2731  gwyData->playbackurl->str, gwyData->gwyip->str);
2732  return TRUE;
2733 }
2734 
2735 /**
2736  * @brief Initializes gateway attributes such as serial number, IP details , MAC details, URL details etc.
2737  *
2738  * @param[in] gwyData Address of the structure holding gateway attributes.
2739  *
2740  * @return Returns TRUE indicating the call has finished.
2741  * @ingroup XUPNP_XDISCOVERY_FUNC
2742  */
2743 //Initializes gateway data item
2744 gboolean init_gwydata(GwyDeviceData* gwydata)
2745 {
2746  gwydata->serial_num = g_string_new(NULL);
2747  gwydata->isgateway=FALSE;
2748  gwydata->requirestrm=TRUE;
2749  gwydata->gwyip = g_string_new(NULL);
2750  gwydata->gwyipv6 = g_string_new(NULL);
2751  gwydata->hostmacaddress = g_string_new(NULL);
2752  gwydata->recvdevtype = g_string_new(NULL);
2753  gwydata->devicetype = g_string_new(NULL);
2754  gwydata->buildversion = g_string_new(NULL);
2755  gwydata->dsgtimezone = g_string_new(NULL);
2756  gwydata->ipSubNet = g_string_new(NULL);
2757  gwydata->dataGatewayIPaddress = g_string_new(NULL);
2758  gwydata->dstoffset = 0;
2759  gwydata->dstsavings = 0;
2760  gwydata->rawoffset = 0;
2761  gwydata->usesdaylighttime = FALSE;
2762  gwydata->baseurl = g_string_new(NULL);
2763  gwydata->basetrmurl = g_string_new(NULL);
2764  gwydata->playbackurl = g_string_new(NULL);
2765  gwydata->dnsconfig = g_string_new(NULL);
2766  gwydata->etchosts = g_string_new(NULL);
2767  gwydata->systemids = g_string_new(NULL);
2768  gwydata->receiverid = g_string_new(NULL);
2769  gwydata->gatewaystbip = g_string_new(NULL);
2770  gwydata->ipv6prefix = g_string_new(NULL);
2771  gwydata->devicename = g_string_new(NULL);
2772  gwydata->bcastmacaddress = g_string_new(NULL);
2773  gwydata->modelclass = g_string_new(NULL);
2774  gwydata->modelnumber = g_string_new(NULL);
2775  gwydata->deviceid = g_string_new(NULL);
2776  gwydata->hardwarerevision = g_string_new(NULL);
2777  gwydata->softwarerevision = g_string_new(NULL);
2778  gwydata->managementurl = g_string_new(NULL);
2779  gwydata->make = g_string_new(NULL);
2780  gwydata->accountid = g_string_new(NULL);
2781  gwydata->clientip = g_string_new(NULL);
2782  gwydata->devFoundFlag=FALSE;
2783  gwydata->isOwnGateway=FALSE;
2784  gwydata->isRouteSet=FALSE;
2785  gwydata->isDevRefactored=FALSE;
2786  gwydata->sproxy=NULL;
2787  gwydata->sproxy_i=NULL;
2788  gwydata->sproxy_m=NULL;
2789  gwydata->sproxy_t=NULL;
2790  gwydata->sproxy_g=NULL;
2791  gwydata->sproxy_q=NULL;
2792  return TRUE;
2793 }
2794 
2795 /**
2796  * @brief Uninitialize gateway data attributes by resetting them to default value.
2797  *
2798  * @param[in] gwyData Address of the structure variable holding Gateway attributes.
2799  *
2800  * @return Returns a boolean value indicating success/failure of the call.
2801  * @ingroup XUPNP_XDISCOVERY_FUNC
2802  */
2803 gboolean free_gwydata(GwyDeviceData* gwydata)
2804 {
2805  if(gwydata)
2806  {
2807  g_string_free(gwydata->serial_num, TRUE);
2808  g_string_free(gwydata->gwyip, TRUE);
2809  g_string_free(gwydata->gwyipv6, TRUE);
2810  g_string_free(gwydata->hostmacaddress, TRUE);
2811  g_string_free(gwydata->recvdevtype, TRUE);
2812  g_string_free(gwydata->devicetype, TRUE);
2813  g_string_free(gwydata->buildversion, TRUE);
2814  g_string_free(gwydata->dataGatewayIPaddress, TRUE);
2815  g_string_free(gwydata->dsgtimezone, TRUE);
2816  g_string_free(gwydata->ipSubNet, TRUE);
2817  g_string_free(gwydata->baseurl, TRUE);
2818  g_string_free(gwydata->basetrmurl, TRUE);
2819  g_string_free(gwydata->playbackurl, TRUE);
2820  g_string_free(gwydata->dnsconfig, TRUE);
2821  g_string_free(gwydata->etchosts, TRUE);
2822  g_string_free(gwydata->systemids, TRUE);
2823  g_string_free(gwydata->receiverid, TRUE);
2824  g_string_free(gwydata->gatewaystbip, TRUE);
2825  g_string_free(gwydata->ipv6prefix, TRUE);
2826  g_string_free(gwydata->devicename, TRUE);
2827  g_string_free(gwydata->bcastmacaddress, TRUE);
2828  g_string_free(gwydata->clientip, TRUE);
2829  if(gwydata->sproxy)
2830  {
2831  g_clear_object(&(gwydata->sproxy));
2832  }
2833  if(gwydata->sproxy_i)
2834  {
2835  g_string_free(gwydata->make, TRUE);
2836  g_string_free(gwydata->accountid, TRUE);
2837  g_string_free(gwydata->modelnumber, TRUE);
2838  g_clear_object(&(gwydata->sproxy_i));
2839  }
2840  if(gwydata->sproxy_m)
2841  {
2842  g_clear_object(&(gwydata->sproxy_m));
2843  }
2844  if(gwydata->sproxy_t)
2845  {
2846  g_clear_object(&(gwydata->sproxy_t));
2847  }
2848  if(gwydata->sproxy_g)
2849  {
2850  g_clear_object(&(gwydata->sproxy_g));
2851  }
2852  if(gwydata->sproxy_q)
2853  {
2854  g_clear_object(&(gwydata->sproxy_q));
2855  }
2856  }
2857  return TRUE; /*CID-10127*/
2858 }
2859 
2860 /**
2861  * @brief Check for any addition or deletion of gateway from the list. If any update occurs, this routine
2862  * will validate and add/delete the entry to/from the gateway list and the updated list will be published
2863  * to others.
2864  *
2865  * @param[in] gwyData Address of the structure holding Gateway attributes.
2866  *
2867  * @return Returns TRUE if successfully updated the gateway list else returns FALSE.
2868  * @ingroup XUPNP_XDISCOVERY_FUNC
2869  */
2870 gboolean update_gwylist(GwyDeviceData* gwydata)
2871 {
2872  char* sno = gwydata->serial_num->str;
2873  gchar* gwipaddr = gwydata->gwyip->str;
2874  int ret=0;
2875 #ifdef BROADBAND
2876  dp_wlist_ss_t wstatus;
2877  struct in_addr x_r;
2878 #endif
2879 
2880  if (sno != NULL)
2881  {
2882  GList* xdevlistitem = g_list_find_custom (xdevlist, sno, (GCompareFunc)g_list_find_sno);
2883  //If item already exists delete it - may be efficient than looking for
2884  //all the data items and updating them
2885  if (xdevlistitem != NULL)
2886  {
2887  gint result = g_strcmp0(g_strstrip(((GwyDeviceData *)xdevlistitem->data)->gwyip->str),g_strstrip(gwipaddr));
2888 #ifdef ENABLE_ROUTE
2889  if ((disConf->enableGwSetup == TRUE) && (gwydata->isRouteSet) && (result != 0))
2890  {
2891  g_message("***** stored device gwip = %s new device gwip = %s result = %d sno = %s *****",(((GwyDeviceData *)xdevlistitem->data)->gwyip->str),g_strstrip(gwipaddr),result,sno);
2892 
2893  ret = v_secure_system("route del default gw %s", gwydata->gwyip->str);
2894  if(ret != 0) {
2895  g_message("Failure in executing v_secure_system. ret val: %d \n", ret);
2896  }
2897 
2898  g_message("Clearing the default gateway %s from route list", gwydata->gwyip->str);
2899  }
2900 #else
2901  (void)(result); // this variable is unused if ENABLE_ROUTE is not defined.
2902 #endif
2903  if (delete_gwyitem(sno) == FALSE)
2904  {
2905  //g_print("Item found, but not able to delete it from list\n");
2906  g_message("Found device: %s in the list, but unable to delete for update", sno);
2907  return FALSE;
2908  }
2909  else
2910  {
2911  //g_print("Deleted existing item\n");
2912  g_message("Found device: %s in the list, Deleted before update", sno);
2913  }
2914  }
2915  else
2916  {
2917  g_message("Item %s not found in the list", sno);
2918  }
2919 
2920  g_mutex_lock(mutex);
2921  xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL);
2922  g_mutex_unlock(mutex);
2923  g_message("Inserted new/updated device %s in the list", sno);
2924 #ifdef BROADBAND
2925  if ((rfc_enabled) && (gwydata->isDevRefactored)) {
2926  // for XG devices insert ip address and mac address to whitelist
2927  if(g_strrstr(g_strstrip(gwydata->devicetype->str),"XG") != NULL)
2928  {
2929  if (gwydata->gwyip->str) {
2930  ret = inet_aton(gwydata->gwyip->str, &x_r);
2931  if (ret) {
2932  if ((wstatus = dpnode_insert(x_r.s_addr, gwydata->bcastmacaddress->str)) != DP_WLIST_ERROR) {
2933  g_message("Inserted ip address:index %s:%d mac address %s to whitelist", gwydata->gwyip->str, x_r.s_addr, gwydata->bcastmacaddress->str);
2934  }
2935  else
2936  {
2937  g_message("dpnode_insert failure");
2938  }
2939  }
2940  else
2941  {
2942  g_message("ip address conversion failure");
2943  }
2944  }
2945  else
2946  {
2947  g_message("gateway ip address empty");
2948  }
2949  }
2950  else if ((g_strrstr(g_strstrip(gwydata->devicetype->str),"XID") != NULL ) || (g_strrstr(g_strstrip(gwydata->devicetype->str),"XI3") != NULL))
2951  {
2952  if (gwydata->clientip->str) {
2953  ret = inet_aton(gwydata->clientip->str, &x_r);
2954  if (ret) {
2955  if ((wstatus = dpnode_insert(x_r.s_addr, gwydata->bcastmacaddress->str)) != DP_WLIST_ERROR) {
2956  g_message("Inserted ip address:index %s:%d mac address %s to whitelist", gwydata->clientip->str, x_r.s_addr, gwydata->bcastmacaddress->str);
2957  }
2958  else
2959  {
2960  g_message("dpnode_insert failure");
2961  }
2962  }
2963  else
2964  {
2965  g_message("ip address conversion failure");
2966  }
2967  }
2968  else
2969  {
2970  g_message("client ip address empty");
2971  }
2972  }
2973  }
2974 #else
2975  (void)(ret); //variable unused
2976 #endif
2977  sendDiscoveryResult(disConf->outputJsonFile);
2978  if(xdevlistitem)
2979  xdevlistitem=NULL;
2980  return TRUE;
2981  }
2982  else
2983  {
2984  //g_print("Serial numer is NULL\n");
2985  g_critical("Got a device with empty serianl number");
2986  return FALSE;
2987  }
2988 }
2989 
2990 /**
2991  * @brief Deletes a gateway entry from the list of Gateway devices if it matches
2992  * with the serial number supplied as input.
2993  *
2994  * @param[in] serial_num Serial number of the gateway device represented in string format.
2995  *
2996  * @return Returns TRUE if successfully deleted an item from the Gateway device list else returns FALSE.
2997  * @ingroup XUPNP_XDISCOVERY_FUNC
2998  */
2999 gboolean delete_gwyitem(const char* serial_num)
3000 {
3001 #ifdef BROADBAND
3002  struct in_addr x_r;
3003  int ret=0;
3004 #endif
3005  //look if the item exists
3006  GList* lstXdev = g_list_find_custom (xdevlist, serial_num, (GCompareFunc)g_list_find_sno);
3007  //if item exists delete the item
3008  if (lstXdev)
3009  {
3010  GwyDeviceData *gwdata = lstXdev->data;
3011  g_mutex_lock(mutex);
3012  if(gwdata->isgateway == TRUE)
3013  {
3014 #ifdef CLIENT_XCAL_SERVER
3015  if (gatewayDetected)
3016  {
3017  gatewayDetected--;
3018  }
3019  g_message("Removing Gateway Device %s from the device list %d", gwdata->serial_num->str,gatewayDetected);
3020 
3021 #ifdef BROADBAND
3022  if ((rfc_enabled) && (g_strrstr(g_strstrip(gwdata->devicetype->str),"XG") != NULL ) && (gwdata->isDevRefactored)) {
3023  // Delete the entry from white list
3024  // since the device is not in the network.
3025  ret = inet_aton(gwdata->gwyip->str, &x_r);
3026  if (ret) {
3027  dpnode_delete(x_r.s_addr, " ");
3028  }
3029  }
3030 #endif
3031 #else
3032  g_message("Removing Gateway Device %s from the device list", gwdata->serial_num->str);
3033 #endif
3034  }
3035  else
3036  {
3037  g_message("Removing Client Device %s from the device list", gwdata->serial_num->str);
3038 #ifdef BROADBAND
3039  if ((rfc_enabled) && ((g_strrstr(g_strstrip(gwdata->devicetype->str),"XID") != NULL ) || (g_strrstr(g_strstrip(gwdata->devicetype->str),"XI3") != NULL )) && (gwdata->isDevRefactored)) {
3040  // Delete the entry from white list
3041  // since the device is not in the network.
3042  ret = inet_aton(gwdata->clientip->str, &x_r);
3043  if (ret) {
3044  dpnode_delete(x_r.s_addr, " ");
3045  }
3046  }
3047 #endif
3048  }
3049 /* g_mutex_lock(mutex);
3050  free_gwydata(gwdata);
3051  g_free(gwdata);
3052  xdevlist = g_list_remove(xdevlist, gwdata);
3053  g_mutex_unlock(mutex);
3054  g_message("Deleted device %s from the list", serial_num);
3055  if(lstXdev)
3056  lstXdev=NULL;
3057  return TRUE;
3058  GwyDeviceData *gwdata = lstXdev->data;*/
3059  xdevlist = g_list_remove_link(xdevlist, lstXdev);
3060  free_gwydata(gwdata);
3061  g_free(gwdata);
3062  g_mutex_unlock(mutex);
3063  g_message("Deleted device %s from the list", serial_num);
3064  if(lstXdev)
3065  g_list_free (lstXdev);
3066  return TRUE;
3067  }
3068  else
3069  {
3070  g_message("Device %s to be removed not in the discovered device list", serial_num);
3071  }
3072  return FALSE;
3073 }
3074 
3075 /**
3076  * @brief This will store the updated device discovery results in local storage as JSON formatted data.
3077  *
3078  * Whenever there's add/delete of gateway list it will create a json file, and all service variables will
3079  * be added to output.json. It will notify to all the listeners that listen for change of xupnp data.
3080  *
3081  * @param[in] outfilename Name of the output file to store JSON data.
3082  *
3083  * @return Returns TRUE when successfully stored the device discovery result else returns FALSE.
3084  * @ingroup XUPNP_XDISCOVERY_FUNC
3085  */
3086 
3087 gboolean sendDiscoveryResult(const char* outfilename)
3088 {
3089  gboolean firstXG1GwData=TRUE;
3090  gboolean firstXG2GwData=TRUE;
3091  const gchar v4ModeValue[]="ipv4";
3092  const gchar v6ModeValue[]="ipv6";
3093  gboolean isMediaClientConnected=FALSE;
3094 
3095  if(!bSerialNum)
3096  {
3097  getserialnum(ownSerialNo);
3098  }
3099 
3100  GString *localOutputContents=g_string_new(NULL);
3101  GString *logDevicesList=g_string_new(NULL);
3102  g_string_printf(localOutputContents, "{\n\"xmediagateways\":\n\t[");
3103 
3104  GList *xdevlistDup=NULL;
3105  g_mutex_lock(mutex);
3106  if((xdevlist) && (g_list_length(xdevlist) > 0))
3107  {
3108  xdevlistDup = g_list_copy(xdevlist);
3109  g_mutex_unlock(mutex);
3110  GList *element;
3111  element = g_list_first(xdevlistDup);
3112  while(element)
3113  {
3114  g_string_append_printf(localOutputContents,"\n\t\t{\n\t\t\t");
3115  GwyDeviceData *gwdata = (GwyDeviceData *)element->data;
3116  if(g_strcmp0(gwdata->recvdevtype->str, "broadband")) {
3117  g_string_append_printf(logDevicesList, "%s,%s,", gwdata->bcastmacaddress->str, gwdata->devicetype->str);
3118  }
3119  {
3120  g_string_append_printf(localOutputContents,"\"sno\":\"%s\",\n", gwdata->serial_num->str);
3121  g_string_append_printf(localOutputContents,"\t\t\t\"isgateway\":\"%s\",\n", gwdata->isgateway?"yes":"no");
3122  g_string_append_printf(localOutputContents,"\t\t\t\"deviceName\":\"%s\",\n", gwdata->devicename->str);
3123  g_string_append_printf(localOutputContents,"\t\t\t\"recvDevType\":\"%s\",\n", gwdata->recvdevtype->str);
3124  g_string_append_printf(localOutputContents,"\t\t\t\"DevType\":\"%s\",\n", gwdata->devicetype->str);
3125  g_string_append_printf(localOutputContents,"\t\t\t\"bcastMacAddress\":\"%s\",\n", gwdata->bcastmacaddress->str);
3126 
3127  if(gwdata->sproxy_i != NULL)
3128  {
3129  g_string_append_printf(localOutputContents,"\t\t\t\"accountId\":\"%s\",\n", gwdata->accountid->str);
3130  g_string_append_printf(localOutputContents,"\t\t\t\"modelNumber\":\"%s\",\n", gwdata->modelnumber->str);
3131  g_string_append_printf(localOutputContents,"\t\t\t\"modelClass\":\"%s\",\n", gwdata->modelclass->str);
3132  g_string_append_printf(localOutputContents,"\t\t\t\"make\":\"%s\",\n", gwdata->make->str);
3133  g_string_append_printf(localOutputContents,"\t\t\t\"softwareRevision\":\"%s\",\n", gwdata->buildversion->str);
3134  if(g_strcmp0(gwdata->recvdevtype->str,"broadband"))
3135  {
3136  g_string_append_printf(localOutputContents,"\t\t\t\"hardwareRevision\":\"%s\",\n", gwdata->hardwarerevision->str);
3137  g_string_append_printf(localOutputContents,"\t\t\t\"managementUrl\":\"%s\",\n", gwdata->managementurl->str);
3138  }
3139  }
3140  else
3141  {
3142  g_string_append_printf(localOutputContents,"\t\t\t\"buildVersion\":\"%s\",\n", gwdata->buildversion->str);
3143  }
3144  if(strcasestr(g_strstrip(gwdata->devicetype->str),"XI") == NULL )
3145  {
3146  g_string_append_printf(localOutputContents,"\t\t\t\"gatewayip\":\"%s\",\n", gwdata->gwyip->str);
3147  g_string_append_printf(localOutputContents,"\t\t\t\"gatewayipv6\":\"%s\",\n", gwdata->gwyipv6->str);
3148  g_string_append_printf(localOutputContents,"\t\t\t\"hostMacAddress\":\"%s\",\n", gwdata->hostmacaddress->str);
3149  if(g_strcmp0(gwdata->recvdevtype->str,"hybrid"))
3150  g_string_append_printf(localOutputContents,"\t\t\t\"IPSubNet\":\"%s\",\n", gwdata->ipSubNet->str);
3151  if(g_strcmp0(gwdata->recvdevtype->str,"broadband"))
3152  {
3153  g_string_append_printf(localOutputContents,"\t\t\t\"gatewayStbIP\":\"%s\",\n", gwdata->gatewaystbip->str);
3154  g_string_append_printf(localOutputContents,"\t\t\t\"ipv6Prefix\":\"%s\",\n", gwdata->ipv6prefix->str);
3155  g_string_append_printf(localOutputContents,"\t\t\t\"timezone\":\"%s\",\n", gwdata->dsgtimezone->str);
3156  g_string_append_printf(localOutputContents,"\t\t\t\"rawoffset\":\"%d\",\n", gwdata->rawoffset);
3157  g_string_append_printf(localOutputContents,"\t\t\t\"dstoffset\":\"%d\",\n", gwdata->dstoffset);
3158  g_string_append_printf(localOutputContents,"\t\t\t\"dstsavings\":\"%d\",\n", gwdata->dstsavings);
3159  g_string_append_printf(localOutputContents,"\t\t\t\"usesdaylighttime\":\"%s\",\n", gwdata->usesdaylighttime?"yes":"no");
3160  g_string_append_printf(localOutputContents,"\t\t\t\"requiresTRM\":\"%s\",\n", gwdata->requirestrm?"true":"false");
3161  g_string_append_printf(localOutputContents,"\t\t\t\"baseTrmUrl\":\"%s\",\n", gwdata->basetrmurl->str);
3162  g_string_append_printf(localOutputContents,"\t\t\t\"systemids\":\"%s\",\n", gwdata->systemids->str);
3163  g_string_append_printf(localOutputContents,"\t\t\t\"playbackUrl\":\"%s\",\n", gwdata->playbackurl->str);
3164  g_string_append_printf(localOutputContents,"\t\t\t\"dnsconfig\":\"%s\",\n", gwdata->dnsconfig->str);
3165  g_string_append_printf(localOutputContents,"\t\t\t\"hosts\":\"%s\",\n", gwdata->etchosts->str);
3166  }
3167  if(gwdata->sproxy_i != NULL)
3168  {
3169  g_string_append_printf(localOutputContents,"\t\t\t\"dataGatewayIPaddress\":\"%s\",\n", gwdata->dataGatewayIPaddress->str);
3170  g_string_append_printf(localOutputContents,"\t\t\t\"clientip\":\"%s\",\n", gwdata->clientip->str);
3171  }
3172  }
3173  else
3174  {
3175  g_string_append_printf(localOutputContents,"\t\t\t\"clientip\":\"%s\",\n", gwdata->clientip->str);
3176  g_string_append_printf(localOutputContents,"\t\t\t\"dataGatewayIPaddress\":\"%s\",\n", gwdata->dataGatewayIPaddress->str);
3177  }
3178  g_string_append_printf(localOutputContents,"\t\t\t\"receiverid\":\"%s\"\n\t\t}", gwdata->receiverid->str);
3179  #ifdef CLIENT_XCAL_SERVER
3180  if (gwdata->isgateway)
3181  {
3182  gatewayDetected++;
3183  }
3184  #endif
3185  }
3186  if((!selfDeviceDiscovered) && (g_strcmp0(g_strstrip(ownSerialNo->str),gwdata->serial_num->str) == 0))
3187  {
3188  selfDeviceDiscovered=TRUE;
3189  g_message("Self Discovery Success %s",ownSerialNo->str);
3190  }
3191  if((disConf->enableGwSetup == TRUE) && ((firstXG1GwData == TRUE) || (firstXG2GwData == TRUE)) && (gwdata->isgateway == TRUE) && (checkvalidhostname(gwdata->dnsconfig->str) == TRUE ) && (checkvalidhostname(gwdata->etchosts->str) == TRUE) && (checkvalidip(gwdata->gwyip->str) == TRUE) && (checkvalidip(gwdata->gwyipv6->str) == TRUE))
3192  {
3193 
3194 #ifdef ENABLE_ROUTE
3195  GString *GwRouteParam=g_string_new(NULL);
3196  g_string_printf(GwRouteParam,"%s" ,disConf->gwSetupFile);
3197  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->gwyip->str);
3198  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->dnsconfig->str);
3199  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->etchosts->str);
3200  g_string_append_printf(GwRouteParam," \"%s\"" ,disConf->gwIf);
3201  g_string_append_printf(GwRouteParam," \"%d\"" ,disConf->GwPriority);
3202  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->ipv6prefix->str);
3203  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->gwyipv6->str);
3204  g_string_append_printf(GwRouteParam," \"%s\"" ,gwdata->devicetype->str);
3205 // g_string_append_printf(GwRouteParam," %s " ,"&");
3206  g_message("Calling gateway script %s",GwRouteParam->str);
3207  system(GwRouteParam->str);
3208  g_string_free(GwRouteParam,TRUE);
3209  gwdata->isRouteSet = TRUE;
3210  if(firstXG1GwData == TRUE)
3211  {
3212  firstXG1GwData=FALSE;
3213  }
3214  else if(firstXG2GwData == TRUE)
3215  {
3216 
3217  firstXG2GwData=FALSE;
3218  }
3219 #endif
3220  if (g_strrstr(g_strstrip(gwdata->ipv6prefix->str),"null") || ! *(gwdata->ipv6prefix->str))
3221  {
3222 
3223  if( g_strcmp0(ipMode->str,v4ModeValue) != 0 )
3224  {
3225  g_message("v4 mode changed");
3226  g_string_assign(ipMode,v4ModeValue);
3227  }
3228  }
3229  else
3230  {
3231  if( g_strcmp0(ipMode->str,v6ModeValue) != 0 )
3232  {
3233  g_message("v6 mode changed");
3234  g_string_assign(ipMode,v6ModeValue);
3235  }
3236  }
3237 
3238 
3239 #ifdef USE_XUPNP_TZ_UPDATE
3240  if (g_strcmp0(g_strstrip(gwdata->dsgtimezone->str),"null") != 0)
3241  broadcastTimeZoneChange(gwdata);
3242 #endif
3243 
3244  }
3245  element = g_list_next(element);
3246  if (element) g_string_append_printf(localOutputContents, ",");
3247  }
3248  if(element)
3249  g_list_free(element);
3250  if(xdevlistDup)
3251  g_list_free(xdevlistDup);
3252  }
3253  else
3254  {
3255  g_message("Send Discovery Result : Device List Null or Empty");
3256  g_mutex_unlock(mutex);
3257  }
3258  if (logDevicesList->len)
3259  {
3260  g_string_truncate(logDevicesList, logDevicesList->len-1);
3261  }
3262  g_message("DISCOVERED_MANAGED_DEVICE:%s\n", logDevicesList->str);
3263 
3264 #if defined(ENABLE_FEATURE_TELEMETRY2_0)
3265  char telemetryBuff[4096] = {'\0'};
3266  strncpy(telemetryBuff, logDevicesList->str, logDevicesList->len);
3267  t2_event_s("Discovered_MngdDev_split", telemetryBuff);
3268 #endif
3269 
3270  //g_print("\n\t]\n}\n");
3271  g_string_append_printf(localOutputContents,"\n\t]\n}\n");
3272  //g_print("\nOutput is\n%s", outputcontents->str);
3273  g_message("Output is\n%s", localOutputContents->str);
3274  g_mutex_lock(devMutex);
3275  g_string_assign(outputcontents,localOutputContents->str);
3276  g_mutex_unlock(devMutex);
3277 
3278  //IARM Update
3279 #if defined(USE_XUPNP_IARM)
3280  notifyXUPnPDataUpdateEvent(UIDEV_EVENT_XUPNP_DATA_UPDATE);
3281 #elif defined(USE_XUPNP_IARM_BUS)
3282  notifyXUPnPDataUpdateEvent(IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_UPDATE);
3283 #endif
3284  //End - IARM Update
3285 
3286 
3287  if (g_file_set_contents(outfilename, localOutputContents->str, -1, NULL)==FALSE)
3288  {
3289  g_string_free(localOutputContents,TRUE);
3290  g_print("xdiscovery:Problem in updating the output file contents\n");
3291  g_critical("Problem in updating the file contents");
3292  return FALSE;
3293  } else {
3294  /* Flag to set if media client is discovered */
3295  if (strstr(localOutputContents->str, "mediaclient") != NULL)
3296  isMediaClientConnected = TRUE;
3297  g_string_free(localOutputContents,TRUE);
3298  }
3299 
3300 #ifdef BROADBAND
3301  // Restart webgui.sh to listen on video analytics port if not listesting and
3302  // mediaclient is connected after webgui process up
3303  int ret = 0;
3304  if ((access(WEBGUI_VIDEO_ANAL_FILE, F_OK) == -1) && (isMediaClientConnected == TRUE))
3305  {
3306  g_message("Open Video Analytic port if mediaclient is connected\n");
3307  ret = v_secure_system ("/etc/webgui.sh &");
3308  if(ret != 0) {
3309  g_message("Failure in executing command via v_secure_system. ret val : %d\n", ret);
3310  }
3311  }
3312 #else
3313  // isMediaClientConnected is unused if BROADBAND is not defined.
3314  (void)(isMediaClientConnected);
3315 #endif
3316 
3317  return TRUE;
3318 }
3319 
3320 /*Thread to continuously pole and verify that existing devices are alive and responding
3321  If not take them off from device list*/
3322 
3323 //#ifdef GUPNP_0_19
3324 
3325 /**
3326  * @brief Verify and update the gateway list according to the availability of the gateway devices
3327  * connected to the network. New devices will be added to the list and dead devices will be deleted
3328  * from the list.
3329  *
3330  * @ingroup XUPNP_XDISCOVERY_FUNC
3331  */
3333 {
3334 /*
3335  guint lenPrevDevList = 0;
3336  guint lenCurDevList = 0;
3337  guint lenXdevList = 0;
3338 //workaround to remove device in second attempt -Start
3339  guint removeDeviceNo=0;
3340  guint counter=0;
3341  guint preCounter=0;
3342  guint removeDeviceNo1=0;
3343  guint counter1=0;
3344  guint preCounter1=0;
3345 */
3346  guint checkMainLoopCounter=0;
3347  guint sleepCounter=0;
3348 #ifdef CLIENT_XCAL_SERVER
3349  guint browserDisableEnableCounter=0;
3350 #endif
3351 #if !defined(BROADBAND)
3352  guint selfDiscoveryFailCount=0;
3353 #endif
3354  //workaround to remove device in second attempt -Start
3355  usleep(XUPNP_RESCAN_INTERVAL);
3356  while(1)
3357  {
3358  //g_main_context_push_thread_default(main_context);
3359  if (! g_main_loop_is_running(main_loop))
3360  {
3361  if(checkMainLoopCounter < 7)
3362  g_message("TELEMETRY_XUPNP_DISCOVERY_MAIN_LOOP_NOT_RUNNING");
3363  checkMainLoopCounter++;
3364  }
3365  if(deviceAddNo)
3366  {
3367  if((sleepCounter > 6) && (sleepCounter < 12)) //wait for device addition to complete in 60 seconds and print only for another 60 seconds if there is a hang
3368  {
3369  g_message("Device Addition %u going in main loop",deviceAddNo);
3370  }
3371  sleepCounter++;
3372  usleep(XUPNP_RESCAN_INTERVAL);
3373  continue;
3374  }
3375  // If self discovery fails even after local xdevice is publishing then do an restart of xdiscovery for one time.
3376 #if !defined(BROADBAND)
3377  if((!selfDeviceDiscovered) && (access(RESTART_XDISCOVERY_FILE, F_OK ) == -1))
3378  {
3379  if (selfDiscoveryFailCount >= 20)
3380  {
3381  FILE *fDiscoveryFile;
3382  fDiscoveryFile = fopen(RESTART_XDISCOVERY_FILE, "w");
3383  if(! fDiscoveryFile)
3384  {
3385  g_message("Restart Xdiscovery File open failure");
3386  }
3387  else
3388  {
3389  g_message("Self Discovery Failed %d ! exiting",selfDiscoveryFailCount);
3390  fclose(fDiscoveryFile);
3391  exit(1);
3392  }
3393  }
3394  else
3395  selfDiscoveryFailCount++;
3396  }
3397 #endif
3398  sleepCounter=0;
3399 #ifdef CLIENT_XCAL_SERVER
3400  // When there is a partial discovery make sure that we gssdp cache is flushed out using resource browser
3401  if((partialDiscovery) && (!gatewayDetected) && (browserDisableEnableCounter <=2))
3402  {
3403  g_message("Partial Device Discovery Disable Enable Resource Browser");
3404  gssdp_resource_browser_set_active(GSSDP_RESOURCE_BROWSER(cp),FALSE);
3405  partialDiscovery=FALSE;
3406  usleep(XUPNP_RESCAN_INTERVAL/5);
3407  gssdp_resource_browser_set_active(GSSDP_RESOURCE_BROWSER(cp),TRUE);
3408  usleep(XUPNP_RESCAN_INTERVAL);
3409  browserDisableEnableCounter++;
3410  continue;
3411  }
3412 #endif
3413  if(rfc_enabled)
3414  {
3415  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp_client))==FALSE)
3416  {
3417  g_message("Forced rescan failed for renderer");
3418  usleep(XUPNP_RESCAN_INTERVAL);
3419  }
3420  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp_gw))==FALSE)
3421  {
3422  g_message("Forced rescan failed for gateway");
3423  usleep(XUPNP_RESCAN_INTERVAL);
3424  }
3425  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp_bgw))==FALSE)
3426  {
3427  g_message("Forced rescan failed for broadband");
3428  usleep(XUPNP_RESCAN_INTERVAL);
3429  }
3430  }
3431  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp))==FALSE)
3432  {
3433  g_message("Forced rescan failed");
3434  //g_debug("Forced rescan failed, sleeping");
3435  usleep(XUPNP_RESCAN_INTERVAL);
3436  continue;
3437  }
3438  //else
3439  // g_print("Forced rescan success\n");
3440  //g_debug("Forced rescan success");
3441  usleep(XUPNP_RESCAN_INTERVAL);
3442 /* const GList *constLstProxies = gupnp_control_point_list_device_proxies(cp);
3443  counter++;
3444  counter1++;
3445  if (NULL == constLstProxies)
3446  {
3447  if(disConf->enableGwSetup == TRUE)
3448  {
3449  g_message("Error in getting list of device proxies or No device proxies found");
3450  }
3451  if( removeDeviceNo == 0 )
3452  {
3453  removeDeviceNo++;
3454  preCounter=counter;
3455  }
3456  else if(( removeDeviceNo == 1) && (preCounter == (counter-1)))
3457  {
3458  removeDeviceNo=0;
3459  delOldItemsFromList(TRUE);
3460  counter=0;
3461  preCounter=0;
3462  }
3463  else
3464  {
3465  removeDeviceNo=0;
3466  counter=0;
3467  preCounter=0;
3468 
3469  }
3470  continue;
3471  }
3472  GList *xdevlistDup=NULL;
3473 
3474  lenCurDevList = g_list_length(constLstProxies);
3475  g_mutex_lock(mutex);
3476  if((xdevlist) && (g_list_length(xdevlist) > 0))
3477  {
3478  xdevlistDup = g_list_copy(xdevlist);
3479  lenXdevList = g_list_length(xdevlistDup);
3480  }
3481  g_mutex_unlock(mutex);
3482 
3483 
3484 // lenXdevList = g_list_length(xdevlist);
3485  //g_message("Current list length is %u\n",lenCurDevList);
3486 
3487  if (lenCurDevList > 0)
3488  {
3489  //Compare new list with existing list
3490  if (lenXdevList > 0)
3491  {
3492  gboolean existsFlag = FALSE;
3493  gboolean delCheckFlag = FALSE;
3494  GList *element = NULL;
3495 
3496  element = g_list_first(xdevlistDup);
3497  while(element)
3498  {
3499  GwyDeviceData *gwdata = (GwyDeviceData *)element->data;
3500 
3501  //Loop through all new found devices
3502  GList* lstProxies = g_list_first(constLstProxies);
3503  //g_message("Length of lstProxies is %u", g_list_length(lstProxies));
3504  existsFlag = FALSE;
3505  while(lstProxies)
3506  {
3507  if (NULL == lstProxies->data)
3508  {
3509  g_message("1-Error - Got Null pointer as deviceproxy");
3510  continue;
3511  }
3512  const GUPnPDeviceProxy* dproxy;
3513  dproxy = (GUPnPDeviceProxy *)lstProxies->data;
3514  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO(dproxy));
3515  gint result = g_strcmp0(g_strstrip(gwdata->serial_num->str),g_strstrip(sno));
3516  g_free(sno);
3517  lstProxies = g_list_next(lstProxies);
3518  //Matched the serial number - No need to do anything - quit the loop
3519  if (result==0)
3520  {
3521  existsFlag=TRUE;
3522  break;
3523  }
3524 
3525  //There are still elements to search
3526 
3527  }
3528  //g_list_free(lstProxies);
3529  //End - Loop through all new found devices
3530 
3531  //Device not found in new device list. Mark it for deletion later.
3532  if (existsFlag==FALSE)
3533  {
3534  delCheckFlag = TRUE;
3535  gwdata->devFoundFlag = FALSE;
3536  }
3537 
3538  //There are still elements to search
3539  element = g_list_next(element);
3540  }
3541  if (delCheckFlag == TRUE)
3542  {
3543  // g_message("delCheckFlag is enabled ");
3544  if( removeDeviceNo1 == 0 )
3545  {
3546  removeDeviceNo1++;
3547  preCounter1=counter1;
3548  }
3549  else if(( removeDeviceNo1 == 1) && (preCounter1 == (counter1-1)))
3550  {
3551  removeDeviceNo1=0;
3552  delOldItemsFromList(FALSE);
3553  counter1=0;
3554  preCounter1=0;
3555  }
3556  else
3557  {
3558  removeDeviceNo1=0;
3559  counter1=0;
3560  preCounter1=0;
3561  }
3562  }
3563  }
3564  }
3565  else
3566  {
3567  //g_message("Device List length - Current length: %u - Previous Length: %u",lenCurDevList, lenPrevDevList);
3568  g_message("Current dev length is empty ");
3569  delOldItemsFromList(TRUE);
3570  }
3571  if(xdevlistDup)
3572  {
3573  g_list_free(xdevlistDup);
3574  }
3575 
3576  //Find out newly discovered devices and add to cleaned up list
3577  lenXdevList = g_list_length(xdevlist);
3578  if (lenCurDevList > 0)
3579  {
3580  //Loop through all new found devices
3581  //g_message("Device List length change - Current length: %u - Previous Length: %u - xdevlist len %u",lenCurDevList, lenPrevDevList, lenXdevList);
3582 
3583 
3584  gboolean existsFlag = FALSE;
3585  GList* lstProxies = g_list_first(constLstProxies);
3586  while(lstProxies)
3587  {
3588  if (NULL == lstProxies->data)
3589  {
3590  g_message("2-Error - Got Null pointer as deviceproxy");
3591  continue;
3592  }
3593  const GUPnPDeviceProxy* dproxy;
3594  dproxy = (GUPnPDeviceProxy *)lstProxies->data;
3595 
3596  //g_print("Serial Number %s\n", sno, lenCurDevList);
3597  existsFlag = FALSE;
3598  if (lenXdevList > 0)
3599  {
3600 
3601  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
3602  //g_message("Searching for serial number %s", sno);
3603  existsFlag = checkDeviceExists(sno);
3604  }
3605  //End - Loop through all new found devices
3606 
3607  //Device not found in device list. Mark it for addition.
3608  if (existsFlag==FALSE)
3609  {
3610  device_proxy_available_cb(cp, (GUPnPDeviceProxy *)lstProxies->data);
3611  }
3612 
3613  //There are still elements to search
3614  lstProxies = g_list_next(lstProxies);
3615  }
3616  //g_list_free(lstProxies);
3617 
3618  //g_print("Current list is greater\n");
3619  }
3620 
3621 */
3622 
3623 
3624  //After cleaning up, update the prev list length
3625 // lenPrevDevList=lenCurDevList;
3626  //g_print("\nWaiting Discovery...\n");
3627  }
3628 }
3629 
3630 /**
3631  * @brief Delete all the devices from the device list or delete devices marked
3632  * as "Not Found" from device list.
3633  *
3634  * @param[in] bDeleteAll Boolean variable indicating whether to delete all entries.
3635  * @ingroup XUPNP_XDISCOVERY_FUNC
3636  */
3637 void delOldItemsFromList(gboolean bDeleteAll)
3638 {
3639  guint lenXDevList = 0;
3640  guint deletedDeviceNo=0;
3641  lenXDevList = g_list_length(xdevlist);
3642  int ret = 0;
3643  //g_message("Length of the list before deletion is %u", lenXDevList);
3644  if (lenXDevList > 0)
3645  {
3646  GwyDeviceData *gwdata = NULL;
3647  GList *element = g_list_first(xdevlist);
3648 
3649  while (element && (lenXDevList > 0))
3650  {
3651  gwdata = element->data;
3652  element = g_list_next(element);
3653  if (gwdata->isOwnGateway==FALSE)
3654  {
3655  if (gwdata->devFoundFlag==FALSE || bDeleteAll==TRUE)
3656  {
3657  if(gwdata->isgateway == TRUE)
3658  g_message("Removing Gateway Device %s from the device list", gwdata->serial_num->str);
3659  else
3660  g_message("Removing Client Device %s from the device list", gwdata->serial_num->str);
3661 #ifdef ENABLE_ROUTE
3662  if ((disConf->enableGwSetup == TRUE) && (gwdata->isRouteSet) && checkvalidip(gwdata->gwyip->str))
3663  {
3664  ret = v_secure_system("route del default gw %s", gwdata->gwyip->str);
3665  if(ret != 0) {
3666  g_message("Failure in executing command via v_secure_system. ret val : %d \n", ret);
3667  }
3668  g_message("Clearing the default gateway %s from route list", gwdata->gwyip->str);
3669  }
3670 #else
3671  (void)(ret); //variable not used outside ENABLE_ROUTE flag.
3672 #endif
3673  g_mutex_lock(mutex);
3674  deletedDeviceNo++;
3675  /* Coverity Fix CID:125350 : Used After Free */
3676  xdevlist = g_list_remove(xdevlist, gwdata);
3677  free_gwydata(gwdata);
3678  g_free(gwdata);
3679  //g_print("Element Removed\n");
3680 
3681  g_mutex_unlock(mutex);
3682  }
3683  }
3684  lenXDevList--;
3685  }
3686  g_list_free(element);
3687  if(deletedDeviceNo > 0)
3688  {
3689  g_message("removed %d devices,sending updated discovery result",deletedDeviceNo);
3690  sendDiscoveryResult(disConf->outputJsonFile);
3691  }
3692  }
3693 }
3694 
3695 static void on_last_change (GUPnPServiceProxy *sproxy, const char *variable_name, GValue *value, gpointer user_data)
3696 {
3697  GwyDeviceData *gwdata = NULL;
3698  const char* updated_value;
3699  gboolean bUpdateDiscoveryResult=FALSE;
3700  const char* udn = gupnp_service_info_get_udn(GUPNP_SERVICE_INFO(sproxy));
3701  g_message("Variable name is %s udn is %s", variable_name, udn);
3702 
3703  if (udn != NULL)
3704  {
3705  if (g_strrstr(udn,"uuid:"))
3706  {
3707  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
3708  GList* xdevlistitem = g_list_find_custom (xdevlist, receiverid, (GCompareFunc)g_list_find_udn);
3709  if (xdevlistitem != NULL)
3710  {
3711  gwdata = xdevlistitem->data;
3712  g_message("Found device: %s - Receiver id %s in the list, Updating %s",
3713  gwdata->serial_num->str,gwdata->receiverid->str, variable_name);
3714  if (g_strcmp0(g_strstrip((gchar *)variable_name),"PlaybackUrl") == 0)
3715  {
3716  updated_value = g_value_get_string(value);
3717  g_message("Updated value is %s ", updated_value);
3718  if(g_strcmp0(g_strstrip((gchar *)updated_value),gwdata->playbackurl->str) != 0)
3719  {
3720  bUpdateDiscoveryResult=TRUE;
3721  g_string_assign(gwdata->playbackurl, updated_value);
3722 
3723  //Check if it is local device and replace MoCA IP with 127.0.0.1
3724  //if ((gwdata->isgateway == TRUE))
3725  //{
3726  if (replace_local_device_ip(gwdata) == TRUE)
3727  {
3728  g_message("Replaced MocaIP for %s with localhost", gwdata->serial_num->str);
3729  }
3730  //}
3731  }
3732 
3733  }
3734 
3735  if (g_strcmp0(g_strstrip((gchar *)variable_name),"SystemIds") == 0)
3736  {
3737  updated_value = g_value_get_string(value);
3738  g_message("Updated value is %s ", updated_value);
3739  if(g_strcmp0(g_strstrip((gchar *)updated_value),gwdata->systemids->str) != 0)
3740  {
3741  bUpdateDiscoveryResult=TRUE;
3742  g_string_assign(gwdata->systemids, updated_value);
3743  }
3744  }
3745  if (g_strcmp0(g_strstrip((gchar *)variable_name),"DataGatewayIPaddress") == 0)
3746  {
3747  updated_value = g_value_get_string(value);
3748  g_message("Updated value of DataGatewayIPaddressis %s ", updated_value);
3749  if(g_strcmp0(g_strstrip((gchar *)updated_value),gwdata->dataGatewayIPaddress->str) != 0)
3750  {
3751  bUpdateDiscoveryResult=TRUE;
3752  g_string_assign(gwdata->dataGatewayIPaddress, updated_value);
3753  }
3754  }
3755  if (g_strcmp0(g_strstrip((gchar *)variable_name),"DnsConfig") == 0)
3756  {
3757  updated_value = g_value_get_string(value);
3758  g_message("Updated value is %s ", updated_value);
3759  if(g_strcmp0(g_strstrip((gchar *)updated_value),gwdata->dnsconfig->str) != 0)
3760  {
3761  bUpdateDiscoveryResult=TRUE;
3762  g_string_assign(gwdata->dnsconfig, updated_value);
3763  }
3764  }
3765  if (g_strcmp0(g_strstrip((gchar *)variable_name),"TimeZone") == 0)
3766  {
3767  updated_value = g_value_get_string(value);
3768  g_message("Updated value is %s ", updated_value);
3769  if(g_strcmp0(g_strstrip((gchar *)updated_value),gwdata->dsgtimezone->str) != 0)
3770  {
3771  bUpdateDiscoveryResult=TRUE;
3772  g_string_assign(gwdata->dsgtimezone, updated_value);
3773 #ifdef USE_XUPNP_TZ_UPDATE
3774  if (g_strcmp0(g_strstrip(gwdata->dsgtimezone->str),"null") != 0)
3775  broadcastTimeZoneChange(gwdata);
3776 #endif
3777  }
3778  }
3779  if (g_strcmp0(g_strstrip((gchar*)variable_name),"IPSubNet") == 0)
3780  {
3781  updated_value = g_value_get_string(value);
3782  g_message("Updated value is %s ", updated_value);
3783  if(g_strcmp0(g_strstrip((gchar*)updated_value),gwdata->ipSubNet->str) != 0)
3784  {
3785  bUpdateDiscoveryResult=TRUE;
3786  g_string_assign(gwdata->ipSubNet, updated_value);
3787  if(updated_value && strlen(updated_value))
3788  addRouteToMocaBridge((char*)updated_value);
3789  }
3790  }
3791  //update_gwylist(gwdata);
3792  g_free(receiverid);
3793  if(bUpdateDiscoveryResult)
3794  sendDiscoveryResult(disConf->outputJsonFile);
3795 
3796  }
3797  }
3798  }
3799  return;
3800 }
3801 /**
3802  * @brief This will parse and load the configuration file in a key/value pair format as specified
3803  * in GLib encoding. The configuration file contain attributes which are categorized into following:
3804  * - Network : Contains parameters such as interface name, IP etc.
3805  * - Datafiles : Contains Name of Script and Log files.
3806  *
3807  * @param[in] configfile Name of the configuration file.
3808  *
3809  * @return Returns TRUE if successfully loaded the configuration file in GKey file structure else returns FALSE.
3810  * @ingroup XUPNP_XDISCOVERY_FUNC
3811  */
3812 gboolean readconffile(const char* configfile)
3813 {
3814 
3815  GKeyFile *keyfile = NULL;
3816  GKeyFileFlags flags;
3817  GError *error = NULL;
3818 
3819  if(configfile)
3820  {
3821 
3822  /* Create a new GKeyFile object and a bitwise list of flags. */
3823  keyfile = g_key_file_new ();
3824  flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
3825 
3826  /* Load the GKeyFile from keyfile.conf or return. */
3827  if (!g_key_file_load_from_file (keyfile, configfile, flags, &error))
3828  {
3829  /*Coverity Fix CID:28701 NON_CONST_PRINTF_FORMAT */
3830  g_error("%s",error->message);
3831  g_clear_error(&error);
3832  g_key_file_free(keyfile);
3833  return FALSE;
3834  }
3835  //g_message("Starting with Settings %s\n", g_key_file_to_data(keyfile, NULL, NULL));
3836 
3837  disConf = g_new(ConfSettings,1);
3838  /*
3839  # Names of all network interfaces used for publishing
3840  [Network]
3841  discIf=eth1
3842  GwIf=eth1
3843  GwPriority=50
3844  */
3845 
3846  /* Read in data from the key file from the group "Network". */
3847  disConf->discIf = g_key_file_get_string(keyfile, "Network","discIf", NULL);
3848  disConf->gwIf = g_key_file_get_string(keyfile, "Network","GwIf", NULL);
3849  disConf->GwPriority = g_key_file_get_integer(keyfile, "Network","GwPriority", NULL);
3850  /*
3851  # Paths and names of all input data files
3852  [DataFiles]
3853  gwSetupFile=/lib/rdk/gwSetup.sh
3854  LogFile=/opt/logs/xdiscovery.log
3855  outputJsonFile=/opt/output.json
3856  certPath=/tmp/
3857  keyPath=/tmp/
3858  certFile=xpki_cert
3859  keyFile=xpki_key
3860  */
3861  /* Read in data from the key file from the group "DataFiles". */
3862  disConf->gwSetupFile = g_key_file_get_string(keyfile, "DataFiles","gwSetupFile", NULL);
3863  disConf->logFile = g_key_file_get_string(keyfile, "DataFiles","LogFile", NULL);
3864  disConf->outputJsonFile = g_key_file_get_string(keyfile, "DataFiles","outputJsonFile", NULL);
3865 
3866  if(rfc_enabled)
3867  {
3868  disConf->disCertFile= g_key_file_get_string(keyfile, "DataFiles","certFile", NULL);
3869  disConf->disCertPath= g_key_file_get_string(keyfile, "DataFiles","certPath", NULL);
3870  disConf->disKeyPath= g_key_file_get_string(keyfile, "DataFiles","keyPath", NULL);
3871  disConf->disKeyFile= g_key_file_get_string(keyfile, "DataFiles","keyFile", NULL);
3872  }
3873  /*
3874  # Enable/Disable feature flags
3875  enableGwSetup=TRUE
3876  */
3877  disConf->enableGwSetup = g_key_file_get_boolean(keyfile, "Flags","enableGwSetup", NULL);
3878 
3879  g_key_file_free(keyfile);
3880  if (disConf->logFile == NULL)
3881  g_warning("configuration doesnt have log file so log file should be given explicitly or it will be written in console\n");
3882 
3883  if (disConf->discIf == NULL)
3884  {
3885  g_warning("Invalid or no values found for mandatory parameters\n");
3886  return FALSE;
3887  }
3888 
3889  return TRUE;
3890  }
3891  else
3892  {
3893  g_warning("No configuration file \n");
3894  return FALSE;
3895  }
3896 }
3897 
3898 /**
3899  * @brief Get the serial number of the device from Vendor specific UDHCPC config file.
3900  *
3901  * @param[out] ownSerialNo Address of the string to return the Serial number.
3902  *
3903  * @return Returns TRUE if successfully get the own serial number else returns FALSE.
3904  * @ingroup XUPNP_XDISCOVERY_FUNC
3905  */
3906 
3907 gboolean getserialnum(GString* ownSerialNo)
3908 {
3909 #ifndef CLIENT_XCAL_SERVER
3910  GError *error=NULL;
3911  gboolean result = FALSE;
3912  gchar* udhcpcvendorfile = NULL;
3913 
3914  result = g_file_get_contents ("//etc//udhcpc.vendor_specific", &udhcpcvendorfile, NULL, &error);
3915  if (result == FALSE) {
3916  g_message("Problem in reading /etc/udhcpcvendorfile file %s", error->message);
3917  }
3918  else
3919  {
3920  /* reset result = FALSE to identify serial number from udhcpcvendorfile contents */
3921  result = FALSE;
3922  gchar **tokens = g_strsplit_set(udhcpcvendorfile," \n\t\b\0", -1);
3923  guint toklength = g_strv_length(tokens);
3924  guint loopvar=0;
3925  for (loopvar=0; loopvar<toklength; loopvar++)
3926  {
3927  //g_print("Token is %s\n",g_strstrip(tokens[loopvar]));
3928  if (g_strrstr(g_strstrip(tokens[loopvar]), "SUBOPTION4"))
3929  {
3930  if ((loopvar+1) < toklength )
3931  {
3932  g_string_assign(ownSerialNo, g_strstrip(tokens[loopvar+2]));
3933  bSerialNum=TRUE;
3934  g_message("serialNumber fetched from udhcpcvendorfile:%s", ownSerialNo->str);
3935  }
3936  result = TRUE;
3937  break;
3938  }
3939  }
3940  g_strfreev(tokens);
3941  }
3942  //diagid=1000;
3943 
3944  if(error)
3945  {
3946  /* g_clear_error() frees the GError *error memory and reset pointer if set in above operation */
3947  g_clear_error(&error);
3948  }
3949  if (udhcpcvendorfile) g_free(udhcpcvendorfile);
3950 
3951  return result;
3952 #elif BROADBAND
3953  gboolean result = FALSE;
3954  char serialNumber[50] = {0};
3955  if ( platform_hal_GetSerialNumber(serialNumber) == 0)
3956  {
3957  g_message("serialNumber returned from hal:%s", serialNumber);
3958  g_string_assign(ownSerialNo, serialNumber);
3959  result = TRUE;
3960  bSerialNum=TRUE;
3961  }
3962  else
3963  {
3964  g_error("Unable to get SerialNumber");
3965  }
3966  return result;
3967 #else
3968  bool bRet;
3970  IARM_Result_t iarmRet = IARM_RESULT_IPCCORE_FAIL;
3971  memset(&param, 0, sizeof(param));
3972  param.type = mfrSERIALIZED_TYPE_SERIALNUMBER;
3974  if(iarmRet == IARM_RESULT_SUCCESS)
3975  {
3976  if(param.buffer && param.bufLen)
3977  {
3978  g_message( " serialized data %s \n",param.buffer );
3979  g_string_assign(ownSerialNo,param.buffer);
3980  bRet = true;
3981  bSerialNum=TRUE;
3982  }
3983  else
3984  {
3985  g_message( " serialized data is empty \n" );
3986  bRet = false;
3987  }
3988  }
3989  else
3990  {
3991  bRet = false;
3992  g_message( "IARM CALL failed for mfrtype \n");
3993  }
3994  return bRet;
3995 #endif
3996 }
3997 
3998 
3999 /**
4000  * @brief Replace all occurrences of a sub-string in the given string to value the specified.
4001  *
4002  * @param[in] src_string Source String.
4003  * @param[in] sub_string Sub string which has to be searched and replaced.
4004  * @param[in] replace_string New sub string that will be replaced.
4005  *
4006  * @return Returns TRUE if successfully replaced the sub string with replace string else returns FALSE.
4007  * @ingroup XUPNP_XDISCOVERY_FUNC
4008  */
4009 char *replace_string(char *src_string, char *sub_string, char *replace_string) {
4010 
4011  char *return_str = NULL;
4012  char *insert_str = NULL;
4013  char *tmp_str = NULL;
4014  errno_t rc = -1;
4015  int distance, lenSubStr, lenRepStr, numOccurences;
4016 
4017  if ((!src_string) || (!sub_string) || (!replace_string))return src_string;
4018 
4019  lenSubStr = strlen(sub_string);
4020  lenRepStr = strlen(replace_string);
4021 
4022  insert_str = src_string;
4023  for (numOccurences = 0; (tmp_str = strstr(insert_str, sub_string)); ++numOccurences) {
4024  insert_str = tmp_str + lenSubStr;
4025  }
4026 
4027  int rstrsize = strlen(src_string) + (lenRepStr - lenSubStr) * numOccurences + 1;
4028  tmp_str = return_str = malloc(rstrsize);
4029 
4030  if (!return_str) return src_string;
4031 
4032  while (numOccurences--) {
4033  insert_str = strstr(src_string, sub_string);
4034  distance = insert_str - src_string;
4035  rc = strncpy_s(tmp_str, rstrsize, src_string, distance);
4036  ERR_CHK(rc);
4037  tmp_str += distance;
4038  rstrsize -= distance;
4039  rc = strcpy_s(tmp_str, rstrsize, replace_string);
4040  ERR_CHK(rc);
4041  tmp_str += lenRepStr;
4042  rstrsize -= lenRepStr;
4043  src_string += distance + lenSubStr;
4044  }
4045  rc =strcpy_s(tmp_str, rstrsize, src_string);
4046  ERR_CHK(rc);
4047  return return_str;
4048 }
4049 
4050 /**
4051  * @brief This function gets the IP address for the given interface. The IP Address will be
4052  * formatted to IPv6 or IPv4 address depending upon the configuration.
4053  *
4054  * @param[in] ifname Name of the network interface.
4055  * @param[out] ipAddressBuffer String which will store the result IP Address.
4056  * @param[in] ipv6Enabled Boolean value indicating whether IPv6 is enabled.
4057  *
4058  * @return Returns an Integer value.
4059  * @retval 1 If an IP address is found.
4060  * @retval 0 If No IP address found on specified interface.
4061  * @ingroup XUPNP_XDISCOVERY_FUNC
4062  */
4063 int getipaddress(const char* ifname, char* ipAddressBuffer, gboolean ipv6Enabled)
4064 {
4065  struct ifaddrs * ifAddrStruct=NULL;
4066  struct ifaddrs * ifa=NULL;
4067  void * tmpAddrPtr=NULL;
4068  /* Coverity Fix CID:28732 CHECKED_RETURN */
4069  if( getifaddrs(&ifAddrStruct) < 0 )
4070  {
4071  g_message(" getifaddrs is failed\n");
4072  return -1;
4073  }
4074  //char addressBuffer[INET_ADDRSTRLEN] = NULL;
4075  int found=0;
4076  errno_t rc = -1;
4077  int ind = -1;
4078 
4079  for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
4080  if (ifa->ifa_addr == NULL) continue;
4081  if ((ifa ->ifa_addr->sa_family==AF_INET6) && (ipv6Enabled == TRUE)) { // check it is IP6
4082  // is a valid IP6 Address
4083  tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
4084 
4085  inet_ntop(AF_INET6, tmpAddrPtr, ipAddressBuffer, INET6_ADDRSTRLEN);
4086 
4087  //if (strcmp(ifa->ifa_name,"eth0")==0)
4088  rc = strcmp_s(ifa->ifa_name, strlen(ifa->ifa_name) ,ifname, &ind);
4089  ERR_CHK(rc);
4090  if((ind == 0) && (rc == EOK))
4091  {
4092  found = 1;
4093  break;
4094  }
4095  }
4096 
4097  else {
4098 
4099  if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
4100  // is a valid IP4 Address
4101  tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
4102 
4103  inet_ntop(AF_INET, tmpAddrPtr, ipAddressBuffer, INET_ADDRSTRLEN);
4104 
4105  //if (strcmp(ifa->ifa_name,"eth0")==0)
4106  rc =strcmp_s(ifa->ifa_name,strlen(ifa->ifa_name), ifname, &ind);
4107  ERR_CHK(rc);
4108  if((ind == 0) && (rc == EOK))
4109  {
4110  found = 1;
4111  break;
4112  }
4113  }
4114  }
4115  }
4116 
4117  if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct);
4118  return found;
4119 
4120 }
4121 
4122 /**
4123  * @brief When the discovered device is the own device then MOcA IP is replaced.
4124  *
4125  * @param[in] gwyData Address of structure holding the Gateway device attributes.
4126  *
4127  * @return Returns TRUE if successfully replaced the IP else returns FALSE.
4128  * @ingroup XUPNP_XDISCOVERY_FUNC
4129  */
4131 {
4132  //if(gwydata->isgateway == TRUE)
4133  //{
4134  if ((g_strcmp0 (g_strstrip(gwydata->gwyip->str), g_strstrip(ipaddress)) == 0))
4135  {
4136  g_message("isown gateway is true");
4137  gwydata->isOwnGateway=TRUE;
4138  gboolean result = replace_hn_with_local(gwydata);
4139  return result;
4140  }
4141  //}
4142  return FALSE;
4143 }
4144 
4145 /**
4146  * @brief This will check whether the input IP Address is a valid IPv4 or IPv6 address.
4147  *
4148  * @param[in] ipAddress IP Address in string format.
4149  *
4150  * @return Returns TRUE if IP address is valid else returns FALSE.
4151  * @ingroup XUPNP_XDISCOVERY_FUNC
4152  */
4153 gboolean checkvalidip( char* ipAddress)
4154 {
4155  struct in_addr addr4;
4156  struct in6_addr addr6;
4157  int validip4 = inet_pton(AF_INET, ipAddress, &addr4);
4158  int validip6 = inet_pton(AF_INET6, ipAddress, &addr6);
4159  if (g_strrstr(g_strstrip(ipAddress),"null") || ! *ipAddress )
4160  {
4161  g_message ("ipaddress are empty %s",ipAddress);
4162  return TRUE;
4163  }
4164 
4165  if ((validip4 == 1 ) || (validip6 == 1 ))
4166  {
4167  return TRUE;
4168  }
4169  else
4170  {
4171  g_message("Not a valid ip address %s " , ipAddress);
4172  return FALSE;
4173  }
4174 }
4175 
4176 /**
4177  * @brief This function will check whether a Host name is valid by validating all the associated IP addresses.
4178  *
4179  * @param[in] hostname Host name represented as a string.
4180  *
4181  * @return Returns TRUE if host name is valid else returns FALSE.
4182  * @ingroup XUPNP_XDISCOVERY_FUNC
4183  */
4184 gboolean checkvalidhostname( char* hostname)
4185 {
4186  if (g_strrstr(g_strstrip(hostname),"null") || ! *hostname )
4187  {
4188  g_message ("hostname values are empty %s",hostname);
4189  return TRUE;
4190  }
4191  gchar **tokens = g_strsplit_set(hostname," ;\n\0", -1);
4192  guint toklength = g_strv_length(tokens);
4193  guint loopvar=0;
4194 
4195  for (loopvar=0; loopvar<toklength; loopvar++)
4196  {
4197  if (checkvalidip(tokens[loopvar]))
4198  {
4199  g_strfreev(tokens);
4200  return TRUE;
4201  }
4202  }
4203  g_message(" no valid ip so rejecting the dns values %s ",hostname);
4204  g_strfreev(tokens); /*CID-24000*/
4205  return FALSE;
4206 }
4207 
4208 #if defined(USE_XUPNP_IARM) || defined(USE_XUPNP_IARM_BUS)
4209 void broadcastIPModeChange(void)
4210 {
4211  errno_t rc = -1;
4212  IARM_Bus_SYSMgr_EventData_t eventData;
4213  eventData.data.systemStates.stateId = IARM_BUS_SYSMGR_SYSSTATE_IP_MODE;
4214  eventData.data.systemStates.state = 1;
4215  eventData.data.systemStates.error = 0;
4216  rc = strcpy_s(eventData.data.systemStates.payload, sizeof(eventData.data.systemStates.payload), ipMode->str);
4217  ERR_CHK(rc);
4218  eventData.data.systemStates.payload[strlen(ipMode->str)]='\0';
4219  IARM_Bus_BroadcastEvent(IARM_BUS_SYSMGR_NAME, (IARM_EventId_t) IARM_BUS_SYSMGR_EVENT_SYSTEMSTATE, (void *)&eventData, sizeof(eventData));
4220  g_message("sent event for ipmode= %s",ipMode->str);
4221 }
4222 #endif
4223 
4224 #ifdef USE_XUPNP_TZ_UPDATE
4225 void broadcastTimeZoneChange(GwyDeviceData *gwdata)
4226 {
4227  IARM_Bus_SYSMgr_EventData_t eventData;
4228  static int prevTzIndex = -1;
4229  int currTZIndex = -1;
4230  static bool IsDst = false;
4231 
4232  //g_message("broadcastTimeZoneChange: Input Payload - %s",gwdata->dsgtimezone->str);
4233  /* get the Mapped Time Zone for Sys Mgr */
4234  int size = sizeof(m_timezoneinfo)/sizeof(struct _Timezone);
4235  int i = 0;
4236  for (i = 0; i < size; i++ )
4237  {
4238  if (g_strcmp0(m_timezoneinfo[i].upnpTZ, gwdata->dsgtimezone->str) == 0)
4239  {
4240  currTZIndex = i;
4241  break;
4242  }
4243  }
4244 
4245  /* No Valid Mapped Time Zone Found , return */
4246  if(currTZIndex == -1)
4247  {
4248  g_message("broadcastTimeZoneChange: Do Not Update Inavlid Time Zone - %s ",gwdata->dsgtimezone->str);
4249  return;
4250  }
4251 
4252 
4253  //g_message("broadcastTimeZoneChange Size = %d : currTZIndex = %d",size,currTZIndex);
4254  /* Broadcast only on Change of Time Zone Information */
4255  if((prevTzIndex != currTZIndex) || (IsDst != gwdata->usesdaylighttime))
4256  {
4257  eventData.data.systemStates.stateId = IARM_BUS_SYSMGR_SYSSTATE_TIME_ZONE;
4258  eventData.data.systemStates.state = 2;
4259  eventData.data.systemStates.error = 0;
4260 
4261  /* Send the pay load based on DST */
4262  if(gwdata->usesdaylighttime)
4263  {
4264  snprintf(eventData.data.systemStates.payload,
4265  sizeof(eventData.data.systemStates.payload),"%s", m_timezoneinfo[currTZIndex].tzInDst);
4266  }
4267  else
4268  {
4269  snprintf(eventData.data.systemStates.payload,
4270  sizeof(eventData.data.systemStates.payload),"%s", m_timezoneinfo[currTZIndex].tz);
4271  }
4272  g_message("broadcastTimeZoneChange: sending SysMgr TZ Event with Payload - %s",eventData.data.systemStates.payload);
4273 
4274  IARM_Bus_BroadcastEvent(IARM_BUS_SYSMGR_NAME, (IARM_EventId_t) IARM_BUS_SYSMGR_EVENT_SYSTEMSTATE, (void *)&eventData, sizeof(eventData));
4275  prevTzIndex = currTZIndex;
4276  IsDst = gwdata->usesdaylighttime;
4277  }
4278 }
4279 #endif
4280 
4281 int getSoupStatusFromUrl(char* url)
4282 {
4283  int ret=0;
4284  SoupSession *session = soup_session_sync_new_with_options (SOUP_SESSION_TIMEOUT,1, NULL); //timeout 1 secs
4285  if(session)
4286  {
4287  SoupMessage *msg = soup_message_new ("HEAD", url);
4288  if(msg != NULL)
4289  {
4290  soup_session_send_message (session, msg);
4291  if (SOUP_STATUS_IS_SUCCESSFUL(msg->status_code))
4292  {
4293  g_message("soup status for %s success",url);
4294  ret=1;
4295  }
4296  }
4297  else
4298  g_message("soup message creation failed url %s ",url);
4299  soup_session_abort (session);
4300  g_object_unref (session);
4301  }
4302  else
4303  g_message("soup session creation failed");
4304  return ret;
4305 }
4306 
4307 /**
4308  * @brief This function is used to get the mac address of the target device.
4309  *
4310  * @param[in] ifname Name of the network interface.
4311  *
4312  * @return Returns the mac address of the interface given.
4313  * @ingroup XUPNP_XCALDEV_FUNC
4314  */
4315 gchar *getmacaddress(const gchar *ifname)
4316 {
4317  int fd;
4318  struct ifreq ifr;
4319  unsigned char *mac;
4320  GString *data = g_string_new(NULL);
4321  fd = socket(AF_INET, SOCK_DGRAM, 0);
4322  if (fd < 0) {
4323  g_message("socket failed\n");
4324  return data->str;
4325  }
4326  ifr.ifr_addr.sa_family = AF_INET;
4327  strncpy(ifr.ifr_name , ifname , IFNAMSIZ - 1);
4328  /* Coverity Fix CID:18403 CHECKED_RETURN */
4329  if(ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 )
4330  {
4331  g_message(" ioctl is failed\n");
4332  }
4333  close(fd); //CID:18597 , 158830- negative returns
4334  mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;
4335  //display mac address
4336  //g_print("Mac : %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n" , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4337  g_string_printf(data, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0], mac[1], mac[2],
4338  mac[3], mac[4], mac[5]);
4339  return data->str;
4340 }
verify_devices
void * verify_devices()
Verify and update the gateway list according to the availability of the gateway devices connected to ...
Definition: xdiscovery.c:3332
sysMgr.h
IARM-Bus Sys Manager Public API.
replace_string
char * replace_string(char *src_string, char *sub_string, char *replace_string)
Replace all occurrences of a sub-string in the given string to value the specified.
Definition: xdiscovery.c:4009
IARM_BUS_SYSMGR_NAME
#define IARM_BUS_SYSMGR_NAME
Definition: sysMgr.h:110
_IARM_Bus_MFRLib_GetSerializedData_Param_t::buffer
char buffer[(1280)]
Definition: mfrMgr.h:120
init_media_browser
void init_media_browser()
Definition: mediabrowser.c:202
delOldItemsFromList
void delOldItemsFromList(gboolean bDeleteAll)
Delete all the devices from the device list or delete devices marked as "Not Found" from device list.
Definition: xdiscovery.c:3637
IARM_Bus_Call
IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen)
This API is used to Invoke RPC method by its application name and method name.
Definition: iarm_bus.c:57
_IARM_Bus_MFRLib_GetSerializedData_Param_t::bufLen
int bufLen
Definition: mfrMgr.h:121
IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_UPDATE
@ IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_UPDATE
Definition: sysMgr.h:131
_IARM_BUS_SYSMGR_GetXUPNPDeviceInfo_Param_t::bufLength
int bufLength
Definition: sysMgr.h:115
getipaddress
int getipaddress(const char *ifname, char *ipAddressBuffer, gboolean ipv6Enabled)
This function gets the IP address for the given interface. The IP Address will be formatted to IPv6 o...
Definition: xdiscovery.c:4063
IARM_Bus_RegisterEventHandler
IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler)
This API register to listen to event and provide the callback function for event notification....
Definition: iarmMgrMocks.cpp:43
_IARM_XUPNP_NAME
#define _IARM_XUPNP_NAME
Definition: xdiscovery.h:125
getserialnum
gboolean getserialnum(GString *ownSerialNo)
Get the serial number of the device from Vendor specific UDHCPC config file.
Definition: xdiscovery.c:3907
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.
checkvalidip
gboolean checkvalidip(char *ipAddress)
This will check whether the input IP Address is a valid IPv4 or IPv6 address.
Definition: xdiscovery.c:4153
checkvalidhostname
gboolean checkvalidhostname(char *hostname)
This function will check whether a Host name is valid by validating all the associated IP addresses.
Definition: xdiscovery.c:4184
update_gwylist
static gboolean update_gwylist(GwyDeviceData *gwydata)
Check for any addition or deletion of gateway from the list. If any update occurs,...
Definition: xdiscovery.c:2870
checkDeviceExists
gboolean checkDeviceExists(const char *sno, char *outPlayUrl)
This will Scan through the device list to check whether a particular device entry exists.
Definition: xdiscovery.c:919
ConfSettings
Definition: xdevice-library-private.h:27
xupnp_logger
void xupnp_logger(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
This function is used to log the messages of XUPnP applications. Each Log message will be written to ...
Definition: xdiscovery.c:859
_IARM_BUS_SYSMgr_EventData_t
Definition: sysMgr.h:229
xdiscovery.h
The header file provides xdiscovery APIs.
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...
getmacaddress
gchar * getmacaddress(const gchar *ifname)
This function is used to get the mac address of the target device.
Definition: xcal-device.c:2253
libIBus.h
RDK IARM-Bus API Declarations.
_IARM_BUS_SYSMGR_GetXUPNPDeviceInfo_Param_t
Definition: sysMgr.h:113
replace_local_device_ip
gboolean replace_local_device_ip(GwyDeviceData *gwydata)
When the discovered device is the own device then MOcA IP is replaced.
Definition: xdiscovery.c:4130
close_media_browser
void close_media_browser()
Definition: mediabrowser.c:210
_gwyDeviceData
Definition: xdiscovery_private.h:96
delete_gwyitem
gboolean delete_gwyitem(const char *serial_num)
Deletes a gateway entry from the list of Gateway devices if it matches with the serial number supplie...
Definition: xdiscovery.c:2999
readconffile
gboolean readconffile(const char *configfile)
This will parse and load the configuration file in a key/value pair format as specified in GLib encod...
Definition: xdiscovery.c:3812
IARM_BUS_MFRLIB_API_GetSerializedData
#define IARM_BUS_MFRLIB_API_GetSerializedData
Definition: mfrMgr.h:100
g_list_find_udn
static gint g_list_find_udn(mediaServerCfg *gwData, gconstpointer *udn)
Definition: mediabrowser.c:32
free_gwydata
gboolean free_gwydata(GwyDeviceData *gwydata)
Uninitialize gateway data attributes by resetting them to default value.
Definition: xdiscovery.c:2803
IARM_BUS_MFRLIB_NAME
#define IARM_BUS_MFRLIB_NAME
Definition: mfrMgr.h:98
_IARM_Bus_MFRLib_GetSerializedData_Param_t
Definition: mfrMgr.h:118
_IARM_Bus_MFRLib_GetSerializedData_Param_t::type
mfrSerializedType_t type
Definition: mfrMgr.h:119
IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_REQUEST
@ IARM_BUS_SYSMGR_EVENT_XUPNP_DATA_REQUEST
Definition: sysMgr.h:130
IARM_Bus_Connect
IARM_Result_t IARM_Bus_Connect(void)
This API is used to connect application to the IARM bus daemon. After connected, the application can ...
Definition: iarmMgrMocks.cpp:33
IARM_BUS_XUPNP_API_GetXUPNPDeviceInfo
#define IARM_BUS_XUPNP_API_GetXUPNPDeviceInfo
Definition: xdiscovery.h:126
processIntRequest
gboolean processIntRequest(const GUPnPServiceProxy *sproxy, const char *requestFn, const char *responseFn, guint *result, gboolean isInCriticalPath)
This function is used to retrieve a int parameter from discovered data. Use this function only when t...
Definition: xdiscovery.c:2095
replace_hn_with_local
gboolean replace_hn_with_local(GwyDeviceData *gwyData)
Replace IP Address part of the Gateway URL attributes from home networking IP with the local host IP....
Definition: xdiscovery.c:2709
processBooleanRequest
gboolean processBooleanRequest(const GUPnPServiceProxy *sproxy, const char *requestFn, const char *responseFn, gboolean *result, gboolean isInCriticalPath)
This function is used to retrieve a boolean parameter from discovered data. Use this function only wh...
Definition: xdiscovery.c:2005
registerBrowserConfig
void registerBrowserConfig(GUPnPContext *context)
Definition: mediabrowser.c:191
IARM_Bus_Init
IARM_Result_t IARM_Bus_Init(const char *name)
This API is used to initialize the IARM-Bus library.
Definition: iarmMgrMocks.cpp:38
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199
_IARM_BUS_SYSMGR_GetXUPNPDeviceInfo_Param_t::pBuffer
char * pBuffer
Definition: sysMgr.h:114
init_gwydata
gboolean init_gwydata(GwyDeviceData *gwydata)
Initializes gateway attributes such as serial number, IP details , MAC details, URL details etc.
Definition: xdiscovery.c:2744
sendDiscoveryResult
gboolean sendDiscoveryResult(const char *outfilename)
This will store the updated device discovery results in local storage as JSON formatted data.
Definition: xdiscovery.c:3087
processStringRequest
gboolean processStringRequest(const GUPnPServiceProxy *sproxy, const char *requestFn, const char *responseFn, gchar **result, gboolean isInCriticalPath)
This function is used to retrieve a string parameter from discovered data. Use this function only whe...
Definition: xdiscovery.c:2050
process_gw_services
gboolean process_gw_services(GUPnPServiceProxy *sproxy, GwyDeviceData *gwData)
This function is used to get attributes of different Gateway services using GUPnP Service Proxy.
Definition: xdiscovery.c:2149