Fix to appropriate variable for default connection
[platform/core/connectivity/stc-manager.git] / plugin / monitor / stc-plugin-monitor-connection.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <vconf/vconf.h>
18 #include <openssl/sha.h>
19
20 #include "stc-firewall.h"
21 #include "stc-manager-gdbus.h"
22 #include "stc-plugin-monitor.h"
23 #include "stc-plugin-monitor-connection.h"
24 #include "stc-manager-plugin-firewall.h"
25
26 /* connman service dbus details */
27 #define CONNMAN_SERVICE                          "net.connman"
28 #define CONNMAN_PATH                             "/net/connman"
29
30 #define CONNMAN_MANAGER_PATH                     "/"
31 #define CONNMAN_MANAGER_INTERFACE                CONNMAN_SERVICE ".Manager"
32 #define CONNMAN_SERVICE_INTERFACE                CONNMAN_SERVICE ".Service"
33
34 #define CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX  CONNMAN_PATH "/service/cellular_"
35 #define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX      CONNMAN_PATH "/service/wifi_"
36 #define CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX  CONNMAN_PATH "/service/ethernet_"
37 #define CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/bluetooth_"
38
39 #define CONNMAN_SIGNAL_PROPERTY_CHANGED          "PropertyChanged"
40
41 /* telephony service dbus details */
42 #define TELEPHONY_SERVICE                        "org.tizen.telephony"
43 #define TELEPHONY_DEFAULT_PATH                   "/org/tizen/telephony"
44
45 #define TELEPHONY_SERVICE_MANAGER                TELEPHONY_SERVICE".Manager"
46 #define TELEPHONY_SIM_INTERFACE                  TELEPHONY_SERVICE".Sim"
47
48 #define TELEPHONY_GET_MODEMS                     "GetModems"
49 #define TELEPHONY_GET_IMSI                       "GetIMSI"
50
51 #define SIM_SLOT_SINGLE 1
52
53 #define VCONF_TELEPHONY_DEFAULT_DATA_SERVICE     "db/telephony/dualsim/default_data_service"
54
55 stc_connection_s *g_default_connection = NULL;
56 GSList *g_connection_list = NULL;
57 guint g_connection_sub_id = 0;
58
59 static void __conn_list_free(gpointer value)
60 {
61         stc_connection_s *conn = (stc_connection_s *)value;
62
63         FREE(conn->path);
64         FREE(conn->ifname);
65         FREE(conn->tether_iface.ifname);
66         FREE(conn);
67 }
68
69 static gint __conn_list_comp(gconstpointer a, gconstpointer b)
70 {
71         stc_connection_s *conn = (stc_connection_s *)a;
72         char *path = (char *)b;
73
74         if (g_strcmp0(conn->path, path) == 0)
75                 return 0;
76
77         return -1;
78 }
79
80 static void __update_monitor_by_conn(gpointer data, gpointer user_data)
81 {
82         stc_connection_s *conn = (stc_connection_s *)data;
83
84         stc_monitor_update_by_connection(conn);
85 }
86
87 static int __telephony_get_current_sim(void)
88 {
89         int sim_slot_count = 0;
90         int current_sim = 0;
91
92         if (vconf_get_int(VCONFKEY_TELEPHONY_SIM_SLOT_COUNT, &sim_slot_count) != 0) {
93                 STC_LOGD("failed to get sim slot count"); //LCOV_EXCL_LINE
94                 return -1; //LCOV_EXCL_LINE
95         }
96
97         if (sim_slot_count == SIM_SLOT_SINGLE) {
98                STC_LOGD("It's single sim model"); //LCOV_EXCL_LINE
99                return current_sim; //LCOV_EXCL_LINE
100         }
101
102         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE, &current_sim) != 0) {
103                 STC_LOGD("failed to get default data service = %d\n", //LCOV_EXCL_LINE
104                          current_sim);
105                 return -1; //LCOV_EXCL_LINE
106         }
107
108         return current_sim;
109 }
110
111 static void __make_imsi_to_subscriber_id(stc_connection_s *conn, char *imsi)
112 {
113         int i = 0;
114         SHA256_CTX ctx;
115         unsigned char md[SHA256_DIGEST_LENGTH];
116
117         SHA256_Init(&ctx);
118         SHA256_Update(&ctx, imsi, strlen(imsi));
119         SHA256_Final(md, &ctx);
120
121         for (i = 0; i < SHA256_DIGEST_LENGTH; ++i)
122                 snprintf(conn->subscriber_id + (i * 2), 3, "%02x", md[i]);
123 }
124
125 static void __telephony_get_modem_subscriber_id(GDBusConnection *connection,
126                                 stc_connection_s *conn, const char *default_modem_name)
127 {
128         GVariant *message = NULL;
129         char tel_path[MAX_PATH_LENGTH];
130         char imsi[IMSI_LENGTH];
131         const char *plmn = NULL;
132         int plmn_len = 0;
133         const char *msin = NULL;
134         int msin_len = 0;
135
136         snprintf(tel_path, sizeof(tel_path), "%s/%s", TELEPHONY_DEFAULT_PATH,
137                  default_modem_name);
138         message = stc_manager_gdbus_call_sync(connection,
139                                               TELEPHONY_SERVICE,
140                                               tel_path,
141                                               TELEPHONY_SIM_INTERFACE,
142                                               TELEPHONY_GET_IMSI,
143                                               NULL);
144         if (message == NULL) {
145                 STC_LOGE("Failed to get services informations"); //LCOV_EXCL_LINE
146                 goto done; //LCOV_EXCL_LINE
147         }
148
149         DEBUG_PARAMS(message);
150         DEBUG_PARAM_TYPE(message);
151         g_variant_get(message, "(&s&s)", &plmn, &msin);
152         if (plmn)
153                 plmn_len = strlen(plmn);
154         if (msin)
155                 msin_len = strlen(msin);
156
157         if (msin_len + plmn_len >= IMSI_LENGTH) {
158                 STC_LOGD("Incorrect length of mobile subscriber identifier + net id"); //LCOV_EXCL_LINE
159                 goto done; //LCOV_EXCL_LINE
160         }
161
162         snprintf(imsi, IMSI_LENGTH, "%s%s", plmn, msin);
163         __make_imsi_to_subscriber_id(conn, imsi);
164
165 done:
166         g_variant_unref(message);
167         return;
168 }
169
170 static void __telephony_update_default_modem_subscriber_id(GDBusConnection *connection,
171                                 stc_connection_s *conn)
172 {
173         GVariant *message = NULL;
174         GVariantIter *iter = NULL;
175         gchar *default_modem_name = NULL;
176         gchar *modem_name = NULL;
177         int current_sim = __telephony_get_current_sim();
178
179         if (current_sim < 0) {
180                 STC_LOGI("Sim not found"); //LCOV_EXCL_LINE
181                 return; //LCOV_EXCL_LINE
182         }
183
184         message = stc_manager_gdbus_call_sync(connection,
185                                               TELEPHONY_SERVICE,
186                                               TELEPHONY_DEFAULT_PATH,
187                                               TELEPHONY_SERVICE_MANAGER,
188                                               TELEPHONY_GET_MODEMS,
189                                               NULL);
190         if (message == NULL) {
191                 STC_LOGE("Failed to get services informations"); //LCOV_EXCL_LINE
192                 return; //LCOV_EXCL_LINE
193         }
194
195         g_variant_get(message, "(as)", &iter);
196         DEBUG_PARAMS(message);
197         DEBUG_PARAM_TYPE(message);
198         while (g_variant_iter_loop(iter, "s", &modem_name)) {
199                 if (current_sim == 0) {
200                         default_modem_name = g_strdup(modem_name);
201                         FREE(modem_name);
202                         break;
203                 }
204                 current_sim--; //LCOV_EXCL_LINE
205         }
206
207         __telephony_get_modem_subscriber_id(connection, conn, default_modem_name);
208
209         FREE(default_modem_name);
210         g_variant_iter_free(iter);
211         g_variant_unref(message);
212         return;
213 }
214
215 static void __print_connection_info(stc_connection_s *conn)
216 {
217         STC_LOGI("============= connection info ============");
218         STC_LOGI("path    [%s]", conn->path);
219         STC_LOGI("type    [%d]", conn->type);
220         STC_LOGI("ifname  [%s]", conn->ifname);
221         STC_LOGI("roaming [%u]", conn->roaming ? TRUE : FALSE);
222         if (conn->type == STC_IFACE_DATACALL)
223                 STC_LOGI("sub_id  [%s]", conn->subscriber_id);
224         STC_LOGI("==================================================");
225 }
226
227 static void __print_tether_connection_info(void)
228 {
229         STC_LOGI("============= tethering connection info ============");
230         STC_LOGI("mode    [%u]", g_default_connection->tether_state ? TRUE : FALSE);
231         STC_LOGI("type    [%d]", g_default_connection->tether_iface.type);
232         STC_LOGI("ifname  [%s]", g_default_connection->tether_iface.ifname);
233         STC_LOGI("====================================================");
234 }
235
236 static gboolean __is_cellular_internet_profile(const char *profile)
237 {
238         const char internet_suffix[] = "_1";
239
240         if (profile == NULL)
241                 return FALSE;
242
243         if (g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX)
244             == TRUE) {
245                 char *suffix = strrchr(profile, '_');
246                 if (g_strcmp0(suffix, internet_suffix) == 0)
247                         return TRUE;
248         }
249
250         return FALSE;
251 }
252
253 static gboolean __is_cellular_profile(const char *profile)
254 {
255         if (profile == NULL)
256                 return FALSE;
257
258         return g_str_has_prefix(profile, //LCOV_EXCL_LINE
259                                 CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX);
260 }
261
262 static gboolean __is_wifi_profile(const char *profile)
263 {
264         if (profile == NULL)
265                 return FALSE;
266
267         return g_str_has_prefix(profile, //LCOV_EXCL_LINE
268                                 CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
269 }
270
271 static gboolean __is_ethernet_profile(const char *profile)
272 {
273         if (profile == NULL)
274                 return FALSE;
275
276         return g_str_has_prefix(profile, //LCOV_EXCL_LINE
277                                 CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX);
278 }
279
280 static gboolean __is_bluetooth_profile(const char *profile)
281 {
282         if (profile == NULL)
283                 return FALSE;
284
285         return g_str_has_prefix(profile, //LCOV_EXCL_LINE
286                                 CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX);
287 }
288
289 static gboolean __is_connected(GVariantIter *array)
290 {
291         gboolean is_connected = FALSE;
292         GVariant *variant = NULL;
293         gchar *key = NULL;
294
295         while (g_variant_iter_loop(array, "{sv}", &key, &variant)) {
296                 if (g_strcmp0(key, "State") != 0)
297                         continue;
298
299                 if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
300                         const gchar *state = NULL;
301
302                         state = g_variant_get_string(variant, NULL);
303                         if (g_strcmp0(state, "ready") == 0 ||
304                             g_strcmp0(state, "online") == 0)
305                                 is_connected = TRUE;
306                 }
307
308                 g_free(key);
309                 g_variant_unref(variant);
310                 break;
311         }
312
313         return is_connected;
314 }
315
316 static void __get_connection_info(GDBusConnection *connection,
317                                 stc_connection_s *conn, const char *object_path)
318 {
319         GVariant *message = NULL;
320         GVariantIter *iter = NULL;
321         GVariant *variant = NULL;
322         gchar *key = NULL;
323
324         if (object_path == NULL) {
325                 STC_LOGI("Object path is NULL, so information not available.");
326                 return;
327         }
328
329         message = stc_manager_gdbus_call_sync(connection,
330                                               CONNMAN_SERVICE,
331                                               object_path,
332                                               CONNMAN_SERVICE_INTERFACE,
333                                               "GetProperties", NULL);
334         if (message == NULL) {
335                 STC_LOGE("Failed to get services informations"); //LCOV_EXCL_LINE
336                 goto done; //LCOV_EXCL_LINE
337         }
338
339         g_variant_get(message, "(a{sv})", &iter);
340         if (iter == NULL) {
341                 STC_LOGE("Profile %s doesn't exist", object_path); //LCOV_EXCL_LINE
342                 goto done; //LCOV_EXCL_LINE
343         }
344
345         while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
346                 if (g_strcmp0(key, "Ethernet") == 0) {
347                         GVariantIter *iter1 = NULL;
348                         GVariant *variant1 = NULL;
349                         gchar *key1 = NULL;
350
351                         g_variant_get(variant, "a{sv}", &iter1);
352                         if (iter1 == NULL)
353                                 continue; //LCOV_EXCL_LINE
354
355                         while (g_variant_iter_loop(iter1, "{sv}", &key1,
356                                                    &variant1)) {
357                                 if (g_strcmp0(key1, "Interface") == 0) {
358                                         const gchar *value =
359                                                 g_variant_get_string(variant1,
360                                                                      NULL);
361                                         conn->ifname = g_strdup(value);
362                                 }
363                         }
364
365                         g_variant_iter_free(iter1);
366
367                 } else if (g_strcmp0(key, "Roaming") == 0) {
368                         gboolean roaming = 0;
369
370                         if (g_variant_is_of_type(variant,
371                                                  G_VARIANT_TYPE_BOOLEAN)) {
372                                 roaming = g_variant_get_boolean(variant);
373                                 conn->roaming = roaming;
374                         }
375                 }
376         }
377
378 done:
379         if (iter)
380                 g_variant_iter_free(iter);
381
382         if (message)
383                 g_variant_unref(message);
384
385         return;
386 }
387
388 static stc_error_e __get_connected_profiles(GDBusConnection *connection)
389 {
390         GVariant *message = NULL;
391         GVariantIter *iter = NULL;
392         GVariantIter *next;
393         gchar *object_path;
394         stc_connection_s *conn;
395         gboolean default_conn = TRUE;
396
397         message = stc_manager_gdbus_call_sync(connection,
398                                               CONNMAN_SERVICE,
399                                               CONNMAN_MANAGER_PATH,
400                                               CONNMAN_MANAGER_INTERFACE,
401                                               "GetServices", NULL);
402         if (message == NULL) {
403                 STC_LOGE("Failed to get profiles"); //LCOV_EXCL_LINE
404                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
405         }
406
407         g_slist_free_full(g_connection_list, __conn_list_free);
408
409         g_variant_get(message, "(a(oa{sv}))", &iter);
410         while (g_variant_iter_loop(iter, "(oa{sv})", &object_path, &next)) {
411                 if (object_path == NULL)
412                         continue; //LCOV_EXCL_LINE
413
414                 if (__is_cellular_profile(object_path) &&
415                     !__is_cellular_internet_profile(object_path))
416                         continue;
417
418                 if (__is_connected(next) == TRUE) {
419                         conn = MALLOC0(stc_connection_s, 1);
420                         if (conn == NULL)
421                                 continue;
422
423                         conn->path = g_strdup(object_path);
424                         conn->roaming = FALSE;
425
426                         if (__is_cellular_profile(conn->path)) {
427                                 conn->type = STC_IFACE_DATACALL;
428                                 __telephony_update_default_modem_subscriber_id(connection, conn);
429                         } else if (__is_wifi_profile(conn->path)) {
430                                 conn->type = STC_IFACE_WIFI;
431                         } else if (__is_ethernet_profile(conn->path)) {
432                                 conn->type = STC_IFACE_WIRED;
433                         } else if (__is_bluetooth_profile(conn->path)) {
434                                 conn->type = STC_IFACE_BLUETOOTH;
435                         } else {
436                                 conn->type = STC_IFACE_UNKNOWN;
437                         }
438
439                         __get_connection_info(connection, conn, conn->path);
440                         __print_connection_info(conn);
441
442                         if (default_conn == TRUE) {
443                                 g_default_connection = conn;
444                                 default_conn = FALSE;
445                         }
446
447                         g_connection_list = g_slist_append(g_connection_list, conn);
448                 }
449         }
450
451         g_variant_iter_free(iter);
452         g_variant_unref(message);
453
454         g_slist_foreach(g_connection_list, __update_monitor_by_conn, NULL);
455         stc_plugin_firewall_update();
456
457         return STC_ERROR_NONE;
458 }
459
460 static stc_error_e __get_default_connection(GDBusConnection *connection)
461 {
462         GVariant *message = NULL;
463         GVariantIter *iter = NULL;
464         GVariantIter *next;
465         gchar *object_path;
466
467         message = stc_manager_gdbus_call_sync(connection,
468                                               CONNMAN_SERVICE,
469                                               CONNMAN_MANAGER_PATH,
470                                               CONNMAN_MANAGER_INTERFACE,
471                                               "GetServices", NULL);
472         if (message == NULL) {
473                 STC_LOGE("Failed to get profiles"); //LCOV_EXCL_LINE
474                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
475         }
476
477         g_variant_get(message, "(a(oa{sv}))", &iter);
478         while (g_variant_iter_loop(iter, "(oa{sv})", &object_path, &next)) {
479                 if (object_path == NULL)
480                         continue; //LCOV_EXCL_LINE
481
482                 if (__is_cellular_profile(object_path) &&
483                     !__is_cellular_internet_profile(object_path))
484                         continue;
485
486                 if (__is_connected(next) == TRUE) {
487                         GSList *comp = g_slist_find_custom(g_connection_list,
488                                                                 object_path, __conn_list_comp);
489                         if (comp && comp->data)
490                                 g_default_connection = comp->data;
491
492                         break;
493                 }
494         }
495
496         g_variant_iter_free(iter);
497         g_variant_unref(message);
498
499         return STC_ERROR_NONE;
500 }
501
502 static void __append_connected_profile(GDBusConnection *connection,
503                                 const char *path)
504 {
505         stc_connection_s *conn;
506
507         conn = MALLOC0(stc_connection_s, 1);
508         if (conn == NULL)
509                 return;
510
511         conn->path = g_strdup(path);
512         conn->roaming = FALSE;
513
514         if (__is_cellular_profile(conn->path)) {
515                 conn->type = STC_IFACE_DATACALL;
516                 __telephony_update_default_modem_subscriber_id(connection, conn);
517         } else if (__is_wifi_profile(conn->path)) {
518                 conn->type = STC_IFACE_WIFI;
519         } else if (__is_ethernet_profile(conn->path)) {
520                 conn->type = STC_IFACE_WIRED;
521         } else if (__is_bluetooth_profile(conn->path)) {
522                 conn->type = STC_IFACE_BLUETOOTH;
523         } else {
524                 conn->type = STC_IFACE_UNKNOWN;
525         }
526
527         __get_connection_info(connection, conn, conn->path);
528         __print_connection_info(conn);
529
530         g_connection_list = g_slist_append(g_connection_list, conn);
531
532         stc_monitor_add_by_connection(conn);
533         stc_plugin_firewall_update();
534
535         __get_default_connection(connection);
536 }
537
538 static void __remove_disconnected_profile(GDBusConnection *connection,
539                                 stc_connection_s *conn)
540 {
541         __print_connection_info(conn);
542
543         stc_monitor_remove_by_connection(conn);
544
545         g_connection_list = g_slist_remove(g_connection_list, conn);
546
547         __get_default_connection(connection);
548
549         FREE(conn->path);
550         FREE(conn->ifname);
551         FREE(conn->tether_iface.ifname);
552         FREE(conn);
553 }
554
555 static void __vconf_key_callback(keynode_t *node, void *user_data)
556 {
557         int vconf_key;
558
559         if (node == NULL) {
560                 STC_LOGE("Invalid parameter");
561                 return;
562         }
563
564         if (g_default_connection == NULL)
565                 return;
566
567         if (vconf_keynode_get_type(node) != VCONF_TYPE_INT) {
568                 STC_LOGE("Invalid vconf key type");
569                 return;
570         }
571
572         vconf_key = vconf_keynode_get_int(node);
573
574         /* Check the tethering type */
575         switch (vconf_key) {
576         case VCONFKEY_MOBILE_HOTSPOT_MODE_USB:
577                 STC_LOGI("Hotspot mode USB type !");
578                 g_default_connection->tether_state = TRUE;
579                 g_default_connection->tether_iface.ifname = g_strdup(TETHERING_USB_IF);
580                 g_default_connection->tether_iface.type = STC_IFACE_USB;
581                 break;
582         case VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI:
583                 STC_LOGI("Hotspot mode Wi-Fi type !");
584                 g_default_connection->tether_state = TRUE;
585                 g_default_connection->tether_iface.ifname = g_strdup(TETHERING_WIFI_IF);
586                 g_default_connection->tether_iface.type = STC_IFACE_WIFI;
587                 break;
588         case VCONFKEY_MOBILE_HOTSPOT_MODE_BT:
589                 STC_LOGI("Hotspot mode Bluetooth type !");
590                 g_default_connection->tether_state = TRUE;
591                 g_default_connection->tether_iface.ifname = g_strdup(TETHERING_BT_IF);
592                 g_default_connection->tether_iface.type = STC_IFACE_BLUETOOTH;
593                 break;
594         case VCONFKEY_MOBILE_HOTSPOT_MODE_P2P:
595                 STC_LOGI("Hotspot mode P2P type !");
596                 g_default_connection->tether_state = TRUE;
597                 g_default_connection->tether_iface.ifname = g_strdup(TETHERING_P2P_IF);
598                 g_default_connection->tether_iface.type = STC_IFACE_P2P;
599                 break;
600         case VCONFKEY_MOBILE_HOTSPOT_MODE_NONE:
601                 STC_LOGI("Hotspot mode none");
602                 g_default_connection->tether_state = FALSE;
603                 break;
604         default:
605                 STC_LOGE("Unknown Hotspot mode type !");
606                 break;
607         }
608
609         /* add monitoring for tethering if active found */
610         if (g_default_connection->tether_state == TRUE && g_default_connection->tether_iface.ifname) {
611                 __print_tether_connection_info();
612                 stc_monitor_update_by_connection(g_default_connection);
613                 stc_plugin_firewall_update();
614                 STC_LOGI("Data monitoring started for tethering iface !");
615                 return;
616         }
617
618         /* remove monitoring for tethering if in-active found */
619         if (g_default_connection->tether_state == FALSE && g_default_connection->tether_iface.ifname) {
620                 stc_monitor_update_by_connection(g_default_connection);
621                 g_free(g_default_connection->tether_iface.ifname);
622                 g_default_connection->tether_iface.ifname = NULL;
623                 g_default_connection->tether_iface.type = STC_IFACE_UNKNOWN;
624                 STC_LOGI("Data monitoring stopped for tethering iface !");
625                 return;
626         }
627 }
628
629 static void _service_signal_cb(GDBusConnection *connection,
630                                const gchar *name, const gchar *path,
631                                const gchar *interface, const gchar *sig,
632                                GVariant *param, gpointer user_data)
633 {
634         gchar *sigvalue = NULL;
635         GVariant *variant = NULL;
636         stc_s *stc = (stc_s *)stc_get_manager();
637         ret_msg_if(stc == NULL, "failed to get stc data");
638
639         if (path == NULL || param == NULL)
640                 goto done;
641
642         g_variant_get(param, "(sv)", &sigvalue, &variant);
643         if (sigvalue == NULL)
644                 goto done;
645
646         if (g_strcmp0(sig, CONNMAN_SIGNAL_PROPERTY_CHANGED) != 0)
647                 goto done;
648
649         if (g_strcmp0(sigvalue, "State") == 0 &&
650             g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
651                 const gchar *state = NULL;
652
653                 state = g_variant_get_string(variant, NULL);
654                 if (g_strcmp0(state, "ready") == 0 ||
655                     g_strcmp0(state, "online") == 0) {
656                         GSList *comp = g_slist_find_custom(g_connection_list,
657                                                                 path, __conn_list_comp);
658                         if (!comp)
659                                 __append_connected_profile(stc->connection, path);
660                 } else if (g_strcmp0(state, "idle") == 0 ||
661                         g_strcmp0(state, "disconnect") == 0) {
662                         GSList *comp = g_slist_find_custom(g_connection_list,
663                                                                 path, __conn_list_comp);
664                         if (comp && comp->data)
665                                 __remove_disconnected_profile(stc->connection, comp->data);
666                 }
667         } else if (g_strcmp0(sigvalue, "Roaming") == 0) {
668                 //LCOV_EXCL_START
669                 GSList *comp = g_slist_find_custom(g_connection_list,
670                                                         path, __conn_list_comp);
671
672                 if (comp) {
673                         stc_connection_s *conn = comp->data;
674                         gboolean roaming = 0;
675
676                         if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) {
677                                 roaming = g_variant_get_boolean(variant);
678                                 conn->roaming = roaming;
679                         }
680                 }
681                 //LCOV_EXCL_STOP
682         } else {
683                 ;//Do nothing
684         }
685 done:
686         if (sigvalue)
687                 g_free(sigvalue);
688
689         if (variant)
690                 g_variant_unref(variant);
691
692         return;
693 }
694
695 stc_error_e stc_plugin_monitor_connection_init(stc_s *stc)
696 {
697         int ret;
698         ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
699
700         __get_connected_profiles(stc->connection);
701         g_connection_sub_id =
702                 stc_manager_gdbus_subscribe_signal(stc->connection,
703                                                    CONNMAN_SERVICE,
704                                                    CONNMAN_SERVICE_INTERFACE,
705                                                    CONNMAN_SIGNAL_PROPERTY_CHANGED,
706                                                    NULL, NULL,
707                                                    G_DBUS_SIGNAL_FLAGS_NONE,
708                                                    _service_signal_cb,
709                                                    NULL, NULL);
710
711         ret = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, __vconf_key_callback, NULL);
712         if (ret < 0)
713                 STC_LOGE("vconf_notify_key_changed failed: %d", ret);
714
715         STC_LOGI("Successfully subscribed connman [%s] signal", CONNMAN_SIGNAL_PROPERTY_CHANGED);
716         return STC_ERROR_NONE;
717 }
718
719 stc_error_e stc_plugin_monitor_connection_deinit(stc_s *stc)
720 {
721         ret_value_msg_if(stc == NULL, STC_ERROR_INVALID_PARAMETER, "failed to get stc data");
722
723         stc_manager_gdbus_unsubscribe_signal(stc->connection,
724                                              g_connection_sub_id);
725
726         g_slist_free_full(g_connection_list, __conn_list_free);
727
728         return STC_ERROR_NONE;
729 }
730
731 GSList *stc_get_connection_list(void)
732 {
733         return g_connection_list;
734 }