RDK Documentation (Open Sourced RDK Components)
idm_client.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 idm_client.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 "secure_wrapper.h"
41 #include <sysevent/sysevent.h>
42 #include <glib/gprintf.h>
43 #include <string.h>
44 #include <glib/gstdio.h>
45 #include "rdk_safeclib.h"
46 #ifndef BROADBAND
47 #ifdef ENABLE_RFC
48 #include "rfcapi.h"
49 #endif
50 #else
51 #include <platform_hal.h>
52 #include <syscfg/syscfg.h>
53 #endif
54 #if defined(CLIENT_XCAL_SERVER) && !defined(BROADBAND)
55 #include "mfrMgr.h"
56 #endif
57 #include <libsoup/soup.h>
58 #include <idm_client.h>
59 #define CLIENT_CONTEXT_PORT 50767
60 #define IDM_CLIENT_DEVICE "urn:schemas-upnp-org:device:IDM:1"
61 #define IDM_SERVICE "urn:schemas-upnp-org:service:X1IDM:1"
62 #define IDM_DP_CLIENT_DEVICE "urn:schemas-upnp-org:device:IDM_DP:1"
63 #define IDM_DP_SERVICE "urn:schemas-upnp-org:service:X1IDM_DP:1"
64 #define IDM_CERT_FILE "/tmp/idm_xpki_cert"
65 #define IDM_KEY_FILE "/tmp/idm_xpki_key"
66 #define IDM_CA_FILE "/tmp/idm_UPnP_CA"
67 static int fd = -1;
68 int idm_upnp_restart_triggered = 0;
69 typedef GTlsInteraction XupnpTlsInteraction;
70 typedef GTlsInteractionClass XupnpTlsInteractionClass;
71 static void xupnp_tls_interaction_init (XupnpTlsInteraction *interaction);
72 static void xupnp_tls_interaction_class_init (XupnpTlsInteractionClass *xupnpClass);
73 int s_sysevent_connect (token_t *out_se_token);
74 int SE_msg_receive(int fd, char *replymsg, unsigned int *replymsg_size, token_t *who);
75 GType xupnp_tls_interaction_get_type (void);
76 
77 G_DEFINE_TYPE (XupnpTlsInteraction, xupnp_tls_interaction, G_TYPE_TLS_INTERACTION);
78 
79 static gint
80 g_list_compare_sno(GwyDeviceData* gwData1, GwyDeviceData* gwData2, gpointer user_data )
81 {
82  gint result = g_strcmp0(g_strstrip(gwData1->serial_num->str),g_strstrip(gwData2->serial_num->str));
83  return result;
84 }
85 
86 static gint
87 g_list_find_sno(GwyDeviceData* gwData, gconstpointer* sno )
88 {
89  if (g_strcmp0(g_strstrip(gwData->serial_num->str),g_strstrip((gchar *)sno)) == 0)
90  return 0;
91  else
92  return 1;
93 }
94 int s_sysevent_connect (token_t *out_se_token)
95 {
96  static token_t sysevent_token = 0;
97  if (0 > fd )
98  {
99  unsigned short sysevent_port = SE_SERVER_WELL_KNOWN_PORT;
100  char *sysevent_ip = "127.0.0.1";
101  char *sysevent_name = "idm_client";
102  fd = sysevent_open(sysevent_ip, sysevent_port, SE_VERSION, sysevent_name, &sysevent_token);
103  g_message("%s: open new sysevent fd %d", __FUNCTION__,fd);
104  }
105  else
106  {
107  g_message("Inside %s:%d",__FUNCTION__,__LINE__);
108  }
109  *out_se_token = sysevent_token;
110  return fd;
111 }
112 int EventListen(void)
113 {
114  fd_set rfds;
115  FD_ZERO(&rfds);
116  FD_SET(fd, &rfds);
117  int retval,ret=-2;
118  FD_ZERO(&rfds);
119  FD_SET(fd, &rfds);
120  retval=select(fd+1, &rfds, NULL, NULL, NULL);
121 
122  if(retval)
123  {
124  se_buffer msg_buffer;
125  se_notification_msg *msg_body = (se_notification_msg *)msg_buffer;
126  unsigned int msg_size;
127  token_t from;
128  int msg_type;
129 
130  msg_size = sizeof(msg_buffer);
131  msg_type = SE_msg_receive(fd, msg_buffer, &msg_size, &from);
132  // if not a notification message then ignore it
133  if (SE_MSG_NOTIFICATION == msg_type)
134  {
135  // extract the name and value from the return message data
136  int name_bytes;
137  int value_bytes;
138  char *name_str;
139  char *value_str;
140  char *data_ptr;
141 
142  data_ptr = (char *)&(msg_body->data);
143  name_str = (char *)SE_msg_get_string(data_ptr, &name_bytes);
144  data_ptr += name_bytes;
145  value_str = (char *)SE_msg_get_string(data_ptr, &value_bytes);
146  if(!strcmp(name_str, "wan-status"))
147  {
148  if (!strncmp(value_str, "started", 7))
149  {
150  g_message("wan-status returned started");
151  ret = 0;
152  }
153  else if (!strncmp(value_str, "stopped", 7))
154  {
155  g_message("wan-status returned stopped");
156  ret = -1;
157  }
158  }
159  }
160  else
161  {
162  g_message("Received msg that is not a SE_MSG_NOTIFICATION (%d)\n", msg_type);
163  }
164  }
165  else
166  {
167  g_message("%s: Received no event retval=%d\n", __FUNCTION__, retval);
168  }
169  return ret;
170 }
171 void* EventHandler(void* args)
172 {
173  char wan_status[8]={'\0'};
174  token_t token;
175  async_id_t wan_status_id;
176  int ret,rc;
177 start:
178  fd = s_sysevent_connect(&token);
179  sysevent_set_options(fd, token, "wan-status", TUPLE_FLAG_EVENT);
180  rc = sysevent_setnotification(fd, token, "wan-status", &wan_status_id);
181  if(rc)
182  {
183  g_message("goto start");
184  goto start;
185  }
186  if ( 0 == sysevent_get(fd, token, "wan-status", wan_status,sizeof(wan_status)) && '\0' != wan_status)
187  {
188  if (0 == strncmp(wan_status,"stopped",strlen("stopped")))
189  {
190  g_message("present wan-status stopped");
191  gupnp_set_cert_flags(0x0010);
192  }
193  else
194  {
195  g_message("present wan-status started");
196  sysevent_rmnotification(fd, token, wan_status_id);
197  sysevent_close(fd, token);
198  pthread_exit(NULL);
199  }
200  while(1)
201  {
202  ret = EventListen();
203  if(ret == 0)
204  {
205  g_message("EventListen returned zero");
206  gupnp_set_cert_flags(0x001C);
207  v_secure_system("/etc/Xupnp/idm_certs.sh");
208  break;
209  }
210  else if(ret == -1)
211  {
212  g_message("EventListen returned minus 1");
213  gupnp_set_cert_flags(0x0010);
214  }
215  else
216  {
217  g_message("EventListen returned neither 1 or -1");
218  }
219  }
220  sysevent_rmnotification(fd, token, wan_status_id);
221  sysevent_close(fd, token);
222  pthread_exit(NULL);
223  }
224  return NULL;
225 }
226 
227 static void
228 xupnp_tls_interaction_init (XupnpTlsInteraction *interaction)
229 {
230 
231 }
232 static GTlsInteractionResult
233 xupnp_tls_interaction_request_certificate (GTlsInteraction *interaction,
234  GTlsConnection *connection,
235  GTlsCertificateRequestFlags flags,
236  GCancellable *cancellable,
237  GError **error)
238 {
239  GTlsCertificate *cert;
240  GError *xupnp_error = NULL;
241 
242  if ((certFile == NULL) || (keyFile == NULL) ) {
243 
244  g_message(" Certificate or Key file NULL");
245  return G_TLS_INTERACTION_FAILED;
246  }
247 
248  cert = g_tls_certificate_new_from_files (certFile,
249  keyFile,
250  &xupnp_error);
251  g_assert_no_error (xupnp_error);
252 
253  g_tls_connection_set_certificate (connection, cert);
254  g_object_unref (cert);
255 
256  return G_TLS_INTERACTION_HANDLED;
257 }
258 
259 static void
260 xupnp_tls_interaction_class_init (XupnpTlsInteractionClass *xupnpClass)
261 {
262  GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (xupnpClass);
263 
264  interaction_class->request_certificate = xupnp_tls_interaction_request_certificate;
265 }
266 
267 gboolean init_gwydata(GwyDeviceData* gwydata)
268 {
269  gwydata->serial_num = g_string_new(NULL);
270  gwydata->bcastmacaddress = g_string_new(NULL);
271  gwydata->clientip = g_string_new(NULL);
272  gwydata->receiverid = g_string_new(NULL);
273  gwydata->gwyipv6 = g_string_new(NULL);
274  gwydata->sproxy=NULL;
275  gwydata->sproxy_i=NULL;
276  return TRUE;
277 }
278 
279 guint deviceAddNo=0;
280 gboolean processStringRequest(const GUPnPServiceProxy *sproxy ,const char * requestFn,
281  const char * responseFn, gchar ** result, gboolean isInCriticalPath)
282 {
283 GError *error = NULL;
284 #ifdef GUPNP_1_2
285  GUPnPServiceProxyAction *action;
286  action = gupnp_service_proxy_action_new (requestFn, NULL);
287  gupnp_service_proxy_call_action ((GUPnPServiceProxy *)sproxy, action, NULL, &error);
288  if( NULL == error )
289  {
290  gupnp_service_proxy_action_get_result (action,
291  &error, responseFn, G_TYPE_STRING, result, NULL);
292  g_clear_pointer (&action, gupnp_service_proxy_action_unref);
293  }
294 #else
295  gupnp_service_proxy_send_action ((GUPnPServiceProxy *)sproxy, requestFn, &error,NULL, responseFn, G_TYPE_STRING, result ,NULL);
296 #endif
297  if ( NULL != error ) //Didn't went well
298  {
299  g_message ("%s process gw services Error: %s\n", requestFn, error->message);
300  if ( isInCriticalPath ) // Update telemetry
301  {
302  g_message("TELEMETRY_XUPNP_PARTIAL_DISCOVERY:%d,%s",error->code, requestFn);
303  }
304  g_clear_error(&error);
305  return FALSE;
306  }
307  return TRUE;
308 }
309 
311 {
312  guint sleepCounter=0;
313  //workaround to remove device in second attempt -Start
314  usleep(sleep_seconds);
315  while(1)
316  {
317  if(deviceAddNo)
318  {
319  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
320  {
321  g_message("Device Addition %u going in main loop",deviceAddNo);
322  }
323  sleepCounter++;
324  usleep(sleep_seconds);
325  continue;
326  }
327  sleepCounter=0;
328 
329 #ifdef IDM_DEBUG
330  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp))==FALSE)
331  {
332  g_message("Forced rescan failed");
333  usleep(sleep_seconds);
334  }
335 #else
336  if (gssdp_resource_browser_rescan(GSSDP_RESOURCE_BROWSER(cp_bgw))==FALSE)
337  {
338  g_message("Forced rescan failed for broadband");
339  usleep(sleep_seconds);
340  }
341 #endif
342  usleep(sleep_seconds);
343  }
344 }
345 
346 gboolean delete_gwyitem(const char* serial_num)
347 {
348  //look if the item exists
349  GList* lstXdev = g_list_find_custom (xdevlist, serial_num, (GCompareFunc)g_list_find_sno);
350  //if item exists delete the item
351  if (lstXdev)
352  {
353  GwyDeviceData *gwydata = lstXdev->data;
354  g_mutex_lock(mutex);
355  xdevlist = g_list_remove_link(xdevlist, lstXdev);
356  if(gwydata)
357  {
358  device_info_t di;
359  strcpy(di.Ipv4,gwydata->clientip->str);
360  strcpy(di.mac,gwydata->bcastmacaddress->str);
361  strcpy(di.Ipv6,gwydata->gwyipv6->str);
362  g_message("callback=%p",callback);
363  callback(&di,0,0);
364  g_string_free(gwydata->serial_num, TRUE);
365  g_string_free(gwydata->bcastmacaddress, TRUE);
366  g_string_free(gwydata->gwyipv6,TRUE);
367  g_string_free(gwydata->clientip,TRUE);
368  g_string_free(gwydata->receiverid,TRUE);
369  if(gwydata->sproxy)
370  {
371  g_clear_object(&(gwydata->sproxy));
372  }
373  if(gwydata->sproxy_i)
374  {
375  g_clear_object(&(gwydata->sproxy_i));
376  }
377  }
378  g_free(gwydata);
379  g_mutex_unlock(mutex);
380  g_message("Deleted device %s from the list", serial_num);
381  g_list_free (lstXdev);
382  return TRUE;
383  }
384  else
385  {
386  g_message("Device %s to be removed not in the discovered device list", serial_num);
387  }
388  return FALSE;
389 }
390 
391 static void
392 device_proxy_unavailable_cb_bgw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
393 {
394  const gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
395  g_message ("In unavailable_bgw Device %s went down",sno);
396  if((g_strcmp0(g_strstrip(ownSerialNo->str),sno) == 0))
397  {
398  g_message ("Self Device [%s][%s] not removing",sno,ownSerialNo->str);
399  g_free((gpointer)sno);
400  return;
401  }
402  if (delete_gwyitem(sno) == FALSE)
403  {
404  g_message("%s found, but unable to delete it from list", sno);
405  return;
406  }
407  else
408  {
409  g_message("Deleted %s from list", sno);
410  }
411  g_free((gpointer)sno);
412 }
413 #ifndef IDM_DEBUG
414 static void
415 device_proxy_available_cb_bgw (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
416 {
417  g_message("In available_bgw found a Broadband device. deviceAddNo = %u ",deviceAddNo);
418  deviceAddNo++;
419  if ((NULL==cp) || (NULL==dproxy))
420  {
421  deviceAddNo--;
422  g_message("WARNING - Received a null pointer for broadband device device no %u",deviceAddNo);
423  return;
424  }
425  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
426  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
427  if(xdevlistitem!=NULL)
428  {
429  deviceAddNo--;
430  g_message("Existing available_cb_bgw as SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
431  g_free((gpointer)sno);
432  return;
433  }
434  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
435  init_gwydata(gwydata);
436  gwydata->sproxy_i = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), IDM_DP_SERVICE);
437  if (sno != NULL)
438  {
439  g_message("In available_cb_bgw Broadband device serial number: %s",sno);
440  g_string_assign(gwydata->serial_num, sno);
441  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
442  if (udn != NULL)
443  {
444  if (g_strrstr(udn,"uuid:"))
445  {
446  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
447  if(receiverid)
448  {
449  g_message("Gateway device receiver id is %s",receiverid);
450  device_info_t di;
451  memset(&di,0,sizeof(di));
452  g_string_assign(gwydata->receiverid, receiverid);
453  g_free(receiverid);
454  gchar *temp=NULL;
455  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetClientIP", "ClientIP" , &temp, FALSE))
456  {
457  g_string_assign(gwydata->clientip, temp);
458  strncpy(di.Ipv4,gwydata->clientip->str,IPv4_ADDR_SIZE);
459  g_message("clientIP=%s",di.Ipv4);
460  g_free(temp);
461  }
462  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetBcastMacAddress", "BcastMacAddress" , &temp, FALSE))
463  {
464  g_string_assign(gwydata->bcastmacaddress, temp);
465  strncpy(di.mac,gwydata->bcastmacaddress->str,MAC_ADDR_SIZE);
466  g_message("BcastMacAddress=%s",di.mac);
467  g_free(temp);
468  }
469  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetGatewayIPv6", "GatewayIPv6" , &temp, FALSE))
470  {
471  g_string_assign(gwydata->gwyipv6,temp);
472  strncpy(di.Ipv6,gwydata->gwyipv6->str,IPv6_ADDR_SIZE);
473  g_message("GatewayIPv6=%s",di.Ipv6);
474  g_free(temp);
475  }
476  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy_i, "GetAccountId","AccountId", &temp, FALSE))
477  {
478  int valid_account=1,loop=0;
479  g_message("Discovered device sent accountId as %s",temp);
480  for(loop=0;loop<(int)(strlen(temp));loop++)
481  {
482  if(temp[loop] < '0' || temp[loop] > '9')
483  {
484  g_message("not a valid account due to %c presence",temp[loop]);
485  valid_account=0;
486  break;
487  }
488  }
489  if(valid_account==1)
490  {
491  g_message("Discovered device AccountId is valid");
492  if(g_strcmp0(g_strstrip(accountId),temp)==0)
493  {
494  g_mutex_lock(mutex);
495  xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL);
496  g_mutex_unlock(mutex);
497  g_message("Inserted new/updated device %s in the list as accountId %s is same", sno,temp);
498  callback(&di,1,1);
499  }
500  else
501  {
502  g_message("Not adding to the list as accountId %s is different",temp);
503  }
504  }
505  else
506  {
507  g_message("Its not valid accountID so accountId %s not adding to the list",temp);
508  }
509  g_free(temp);
510  }
511  }
512  else
513  {
514  g_message("In available_cb_bgw gateway device receiver id is NULL");
515  }
516  }
517  }
518  else
519  {
520  g_message("Gateway UDN is NULL");
521  }
522  }
523  g_free(sno);
524  deviceAddNo--;
525  g_message("Exiting from device_proxy_available_cb_broadband deviceAddNo = %u",deviceAddNo);
526 }
527 #else
528 static void device_proxy_available_cb (GUPnPControlPoint *cp, GUPnPDeviceProxy *dproxy)
529 {
530  g_message("Found a new device. deviceAddNo = %u ",deviceAddNo);
531  deviceAddNo++;
532  if ((NULL==cp) || (NULL==dproxy))
533  {
534  deviceAddNo--;
535  g_message("WARNING - Received a null pointer for gateway device device no %u",deviceAddNo);
536  return;
537  }
538  gchar* sno = gupnp_device_info_get_serial_number (GUPNP_DEVICE_INFO (dproxy));
539  GList* xdevlistitem = g_list_find_custom(xdevlist,sno,(GCompareFunc)g_list_find_sno);
540  if(xdevlistitem!=NULL)
541  {
542  deviceAddNo--;
543  g_message("Existing as SNO is present in list so no update of devices %s device no %u",sno,deviceAddNo);
544  g_free(sno);
545  return;
546  }
547  GwyDeviceData *gwydata = g_new(GwyDeviceData,1);
548  if(gwydata)
549  {
550  init_gwydata(gwydata);
551  }
552  else
553  {
554  g_critical("Could not allocate memory for Gwydata. Exiting...");
555  exit(1);
556  }
557  gwydata->sproxy = gupnp_device_info_get_service(GUPNP_DEVICE_INFO (dproxy), IDM_SERVICE);
558  if(!gwydata->sproxy)
559  {
560  deviceAddNo--;
561  g_message("Unable to get the services, sproxy null. returning");
562  return;
563  }
564  if (sno != NULL)
565  {
566  g_message("Device serial number is %s",sno);
567  g_string_assign(gwydata->serial_num, sno);
568  const char* udn = gupnp_device_info_get_udn(GUPNP_DEVICE_INFO (dproxy));
569  if (udn != NULL)
570  {
571  if (g_strrstr(udn,"uuid:"))
572  {
573  gchar* receiverid = g_strndup(udn+5, strlen(udn)-5);
574  if(receiverid)
575  {
576  g_message("Device receiver id is %s",receiverid);
577  g_string_assign(gwydata->receiverid, receiverid);
578  g_free(receiverid);
579  gchar *temp=NULL;
580  device_info_t di;
581  memset(&di,0,sizeof(di));
582  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy, "GetClientIP", "ClientIP" , &temp, FALSE))
583  {
584  g_string_assign(gwydata->clientip, temp);
585  strncpy(di.Ipv4,gwydata->clientip->str,IPv4_ADDR_SIZE);
586  g_message("clientIP=%s",di.Ipv4);
587  g_free(temp);
588  }
589  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy, "GetBcastMacAddress", "BcastMacAddress" , &temp, FALSE))
590  {
591  g_string_assign(gwydata->bcastmacaddress, temp);
592  strncpy(di.mac,gwydata->bcastmacaddress->str,MAC_ADDR_SIZE);
593  g_message("BcastMacAddress=%s",di.mac);
594  g_free(temp);
595  }
596  if ( processStringRequest((GUPnPServiceProxy *)gwydata->sproxy, "GetGatewayIPv6", "GatewayIPv6" , &temp, FALSE))
597  {
598  g_string_assign(gwydata->gwyipv6,temp);
599  strncpy(di.Ipv6,gwydata->gwyipv6->str,IPv6_ADDR_SIZE);
600  g_message("GatewayIPv6=%s",di.Ipv6);
601  g_free(temp);
602  }
603  g_mutex_lock(mutex);
604  xdevlist = g_list_insert_sorted_with_data(xdevlist, gwydata,(GCompareDataFunc)g_list_compare_sno, NULL);
605  g_mutex_unlock(mutex);
606  g_message("Inserted new/updated device %s in the list", sno);
607  callback(&di,1,0);
608  }
609  else
610  g_message("Device receiver id is NULL");
611  }
612  }
613  else
614  g_message("Device UDN is NULL");
615  }
616  g_free(sno);
617  deviceAddNo--;
618  g_message("Exiting from device_proxy_available_cb deviceAddNo = %u",deviceAddNo);
619 }
620 #endif
621 
622 void remove_entries_in_list()
623 {
624  g_message("%s:%d Entered.",__FUNCTION__,__LINE__);
625  if (g_list_length(xdevlist) > 0)
626  {
627  GList *element = NULL;
628  element = g_list_first(xdevlist);
629  while(element)
630  {
631  GwyDeviceData *gwydata = element->data;
632  g_mutex_lock(mutex);
633  xdevlist = g_list_remove_link(xdevlist,element);
634  g_message("%s:%d Deleting %s from the list",__FUNCTION__,__LINE__,gwydata->bcastmacaddress->str);
635  g_string_free(gwydata->serial_num, TRUE);
636  g_string_free(gwydata->bcastmacaddress, TRUE);
637  g_string_free(gwydata->gwyipv6,TRUE);
638  g_string_free(gwydata->clientip,TRUE);
639  g_string_free(gwydata->receiverid,TRUE);
640  if(gwydata->sproxy)
641  {
642  g_clear_object(&(gwydata->sproxy));
643  }
644  if(gwydata->sproxy_i)
645  {
646  g_clear_object(&(gwydata->sproxy_i));
647  }
648  g_free(gwydata);
649  g_mutex_unlock(mutex);
650  element = g_list_next(element);
651  }
652  }
653 }
654 
655 int stop_discovery()
656 {
657  g_message("%s:%d Called.",__FUNCTION__,__LINE__);
658  if(g_main_loop_is_running(main_loop))
659  {
660  idm_upnp_restart_triggered = 1;
661  g_main_loop_quit(main_loop);
662  }
663  g_message("%s:%d completed",__FUNCTION__,__LINE__);
664  return 0;
665 }
666 void start_discovery(discovery_config_t* dc_obj,int (*func_callback)(device_info_t*,uint,uint))
667 {
668  int rvalue=0;
669  if(!(dc_obj->interface)||(dc_obj->port)==0||(dc_obj->discovery_interval)==0||(dc_obj->loss_detection_window)==0)
670  {
671  g_message("some of mandatory values are missing");
672  g_message("interface=%s port=%d discovery_interval=%d loss_detection_window=%d\n", dc_obj->interface, dc_obj->port, dc_obj->discovery_interval, dc_obj->loss_detection_window);
673  return;
674  }
675  g_message("interface=%s port=%d",dc_obj->interface,dc_obj->port);
676  g_thread_init (NULL);
677  g_type_init();
678  GError* error = 0;
679  ownSerialNo=g_string_new(NULL);
680  getserialnum(ownSerialNo);
681  callback=func_callback;
682 #ifndef IDM_DEBUG
683  int ind=-1;
684  errno_t rc = -1;
685  memset(accountId,0,ACCOUNTID_SIZE);
686  while(1)
687  {
688  getAccountId(accountId);
689  g_message("%s:AccountId=%s",__FUNCTION__,accountId);
690  rc = strcasecmp_s("unknown",strlen("unknown"),accountId,&ind);
691  ERR_CHK(rc);
692  if(ind || rc != EOK)
693  {
694  break;
695  }
696  sleep(30);
697  }
698 #endif
699  rvalue=idm_server_start(dc_obj->interface, dc_obj->base_mac);
700  if(rvalue==1)
701  {
702  g_message("id_server_start has facing some issue");
703  return;
704  }
705  mutex = g_mutex_new ();
706 #ifndef IDM_DEBUG
707  GTlsInteraction *xupnp_tlsinteraction= NULL;
708  char caFile[24]=IDM_CA_FILE;
709  strcpy(certFile,IDM_CERT_FILE);
710  strcpy(keyFile,IDM_KEY_FILE);
711  g_message("cert file=%s key file = %s",certFile,keyFile);
712  if((access(certFile,F_OK ) == 0) && (access(keyFile,F_OK ) == 0) && (access(caFile,F_OK ) == 0))
713  {
714 #ifndef GUPNP_1_2
715  upnpContextDeviceProtect = gupnp_context_new_s ( NULL, dc_obj->interface, dc_obj->port,certFile,keyFile, &error);
716 #else
717  upnpContextDeviceProtect = gupnp_context_new_s (dc_obj->interface, dc_obj->port,certFile,keyFile, &error);
718 #endif
719  if (error) {
720  g_printerr ("%s:%d Error creating the Device Protection Broadcast context: %s\n",
721  __FUNCTION__,__LINE__,error->message);
722  /* g_clear_error() frees the GError *error memory and reset pointer if set in above operation */
723  g_clear_error(&error);
724  }
725  else
726  {
727  g_message("IDM UPnP is running in secure mode");
728  gupnp_context_set_subscription_timeout(upnpContextDeviceProtect, 0);
729  xupnp_tlsinteraction = g_object_new (xupnp_tls_interaction_get_type (), NULL);
730  g_message("tls interaction object created");
731  // Set TLS config params here.
732  gupnp_context_set_tls_params(upnpContextDeviceProtect,caFile,keyFile, xupnp_tlsinteraction);
733  if(idm_upnp_restart_triggered == 0) //Start event_handle_thread only for first time.
734  {
735  pthread_t event_handle_thread;
736  int err = pthread_create(&event_handle_thread, NULL,&EventHandler,NULL);
737  if(0 != err)
738  {
739  g_message("%s: create the event handle thread error!\n", __FUNCTION__);
740  }
741  }
742  cp_bgw = gupnp_control_point_new(upnpContextDeviceProtect, IDM_DP_CLIENT_DEVICE);
743  g_signal_connect (cp_bgw,"device-proxy-available", G_CALLBACK (device_proxy_available_cb_bgw), NULL);
744  g_signal_connect (cp_bgw,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb_bgw), NULL);
745  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp_bgw), TRUE);
746  g_message("X1BroadbandGateway controlpoint created for idm");
747  }
748  }
749  else
750  {
751  g_message("%s:mandatory files doesn't present",__FUNCTION__);
752  }
753 #ifdef GUPNP_0_19
754  main_loop = g_main_loop_new (NULL, FALSE);
755 #else
756  main_loop = g_main_loop_new (upnpContextDeviceProtect, FALSE);
757 #endif
758 #else
759  g_message("IDM is running in non secure mode");
760 #ifndef GUPNP_1_2
761 #ifdef GUPNP_0_14
762  main_context = g_main_context_new();
763  context = gupnp_context_new (main_context, dc_obj->interface, CLIENT_CONTEXT_PORT, &error);
764 #else
765  context = gupnp_context_new (NULL, dc_obj->interface, CLIENT_CONTEXT_PORT, &error);
766 #endif
767 #else
768  context = gupnp_context_new (dc_obj->interface, CLIENT_CONTEXT_PORT, &error);
769 #endif
770  if (error) {
771  g_message ("Error creating the GUPnP context: %s", error->message);
772  g_critical("%s:Error creating the XUPnP context on %s:%d Error:%s", __FUNCTION__,dc_obj->interface, CLIENT_CONTEXT_PORT, error->message);
773  g_error_free (error);
774  return;
775  }
776  gupnp_context_set_subscription_timeout(context, 0);
777  cp = gupnp_control_point_new(context, IDM_CLIENT_DEVICE);
778  g_signal_connect (cp,"device-proxy-available", G_CALLBACK (device_proxy_available_cb), NULL);
779  g_signal_connect (cp,"device-proxy-unavailable", G_CALLBACK (device_proxy_unavailable_cb_bgw), NULL);
780  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), TRUE);
781 #ifdef GUPNP_0_19
782  main_loop = g_main_loop_new (NULL, FALSE);
783 #else
784  main_loop = g_main_loop_new (main_context, FALSE);
785 #endif
786 #endif
787  sleep_seconds=((dc_obj->loss_detection_window+8)*1000000);
788  g_message("%s %d calling discovery_interval_configuration function %u loss_detection_window=%u",__FUNCTION__,__LINE__,dc_obj->discovery_interval,dc_obj->loss_detection_window);
789  dc_obj->discovery_interval=dc_obj->discovery_interval*1000;
790  discovery_interval_configuration(dc_obj->discovery_interval,dc_obj->loss_detection_window);
791  g_message("done timeout source assigning\n");
792  if(idm_upnp_restart_triggered == 0) //Start verify_devices thread only for first time.
793  {
794  g_thread_create(verify_devices, NULL,FALSE, NULL);
795  }
796  g_main_loop_run (main_loop);
797  g_message("%s:%d main loop broken",__FUNCTION__,__LINE__);
798  /* emit unavailable signal for the resource connected devices */
799 #ifndef IDM_DEBUG
800  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp_bgw), FALSE);
801 #else
802  gssdp_resource_browser_set_active (GSSDP_RESOURCE_BROWSER (cp), FALSE);
803 #endif
804  g_message("invoke free_server_memory");
805  free_server_memory();
806  g_message("Invoke remove_entries_in_list");
807  remove_entries_in_list();
808  g_main_loop_unref (main_loop);
809 #ifdef IDM_DEBUG
810  g_object_unref (cp);
811  g_object_unref (context);
812 #else
813  g_object_unref (cp_bgw);
814  g_object_unref (upnpContextDeviceProtect);
815  g_object_unref (xupnp_tlsinteraction);
816 #endif
817  /* upnp needs four seconds before restarting for avoiding port bind issues */
818  sleep(4);
819  g_message("%s:%d Completed.",__FUNCTION__,__LINE__);
820 }
verify_devices
void * verify_devices()
Verify and update the gateway list according to the availability of the gateway devices connected to ...
Definition: idm_client.c:310
idm_client.h
This source file contains functions that will run as task for maintaining the device list.
getserialnum
gboolean getserialnum(GString *serial_num)
This function is used to get the serial number of the device from the vendor specific file.
Definition: xcal-device-library.c:227
_discovery_config_t
Definition: idm_client.h:56
xdiscovery.h
The header file provides xdiscovery APIs.
_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: idm_client.c:346
device_info_t
Definition: idm_client.h:49
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199
init_gwydata
gboolean init_gwydata(GwyDeviceData *gwydata)
Initializes gateway attributes such as serial number, IP details , MAC details, URL details etc.
Definition: idm_client.c:267
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: idm_client.c:280