[MPTCP] Add connection_mptcp_is_supported()
[platform/core/api/connection.git] / src / libnetwork.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
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 <glib.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <vconf/vconf.h>
22 #include <system_info.h>
23 #include <arpa/inet.h>
24
25 #include "net_connection_private.h"
26
27 static __thread GSList *prof_handle_list = NULL;
28 static __thread GHashTable *profile_cb_table = NULL;
29
30 struct _profile_cb_s {
31         connection_profile_state_changed_cb callback;
32         connection_profile_state_e state;
33         void *user_data;
34 };
35
36 struct _profile_list_s {
37         int count;
38         int next;
39         net_profile_info_t *profiles;
40 };
41
42 struct _libnet_s {
43         connection_opened_cb opened_cb;
44         connection_closed_cb closed_cb;
45         connection_set_default_cb set_default_cb;
46         connection_reset_cb reset_profile_cb;
47         libnet_ethernet_cable_state_changed_cb ethernet_cable_state_changed_cb;
48         libnet_type_changed_cb type_changed_cb;
49         libnet_ip_changed_cb ip_changed_cb;
50         libnet_proxy_changed_cb proxy_changed_cb;
51         void *opened_user_data;
52         void *closed_user_data;
53         void *set_default_user_data;
54         void *reset_profile_user_data;
55         bool is_created;
56 };
57
58 struct _state_notify {
59         connection_profile_state_changed_cb callback;
60         connection_profile_state_e state;
61         void *user_data;
62 };
63
64 struct managed_idle_data {
65         GSourceFunc func;
66         gpointer user_data;
67         guint id;
68 };
69
70 static __thread struct _profile_list_s profile_iterator = {0, 0, NULL};
71 static __thread struct _libnet_s libnet = {NULL, NULL, NULL, NULL, NULL, NULL,
72                                         NULL, NULL, NULL, NULL, NULL, NULL, false};
73 static __thread GSList *managed_idler_list = NULL;
74 static __thread bool connection_is_feature_checked[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
75 static __thread bool connection_feature_supported[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
76
77 bool _connection_is_created(void)
78 {
79         return libnet.is_created;
80 }
81
82 static void __connection_set_created(bool tag)
83 {
84         libnet.is_created = tag;
85 }
86
87 //LCOV_EXCL_START
88 static connection_error_e __libnet_convert_to_cp_error_type(net_err_t err_type)
89 {
90         switch (err_type) {
91         case NET_ERR_NONE:
92                 return CONNECTION_ERROR_NONE;
93         case NET_ERR_APP_ALREADY_REGISTERED:
94                 return CONNECTION_ERROR_INVALID_OPERATION;
95         case NET_ERR_APP_NOT_REGISTERED:
96                 return CONNECTION_ERROR_INVALID_OPERATION;
97         case NET_ERR_NO_ACTIVE_CONNECTIONS:
98                 return CONNECTION_ERROR_NO_CONNECTION;
99         case NET_ERR_ACTIVE_CONNECTION_EXISTS:
100                 return CONNECTION_ERROR_ALREADY_EXISTS;
101         case NET_ERR_CONNECTION_DHCP_FAILED:
102                 return CONNECTION_ERROR_DHCP_FAILED;
103         case NET_ERR_CONNECTION_INVALID_KEY:
104                 return CONNECTION_ERROR_INVALID_KEY;
105         case NET_ERR_IN_PROGRESS:
106                 return CONNECTION_ERROR_NOW_IN_PROGRESS;
107         case NET_ERR_OPERATION_ABORTED:
108                 return CONNECTION_ERROR_OPERATION_ABORTED;
109         case NET_ERR_TIME_OUT:
110                 return CONNECTION_ERROR_NO_REPLY;
111         case NET_ERR_ACCESS_DENIED:
112                 return CONNECTION_ERROR_PERMISSION_DENIED;
113         default:
114                 return CONNECTION_ERROR_OPERATION_FAILED;
115         }
116 }
117
118 static const char *__libnet_convert_cp_error_type_to_string(connection_error_e err_type)
119 {
120         switch (err_type) {
121         case CONNECTION_ERROR_NONE:
122                 return "NONE";
123         case CONNECTION_ERROR_INVALID_PARAMETER:
124                 return "INVALID_PARAMETER";
125         case CONNECTION_ERROR_OUT_OF_MEMORY:
126                 return "OUT_OF_MEMORY";
127         case CONNECTION_ERROR_INVALID_OPERATION:
128                 return "INVALID_OPERATION";
129         case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
130                 return "ADDRESS_FAMILY_NOT_SUPPORTED";
131         case CONNECTION_ERROR_OPERATION_FAILED:
132                 return "OPERATION_FAILED";
133         case CONNECTION_ERROR_ITERATOR_END:
134                 return "ITERATOR_END";
135         case CONNECTION_ERROR_NO_CONNECTION:
136                 return "NO_CONNECTION";
137         case CONNECTION_ERROR_NOW_IN_PROGRESS:
138                 return "NOW_IN_PROGRESS";
139         case CONNECTION_ERROR_ALREADY_EXISTS:
140                 return "ALREADY_EXISTS";
141         case CONNECTION_ERROR_OPERATION_ABORTED:
142                 return "OPERATION_ABORTED";
143         case CONNECTION_ERROR_DHCP_FAILED:
144                 return "DHCP_FAILED";
145         case CONNECTION_ERROR_INVALID_KEY:
146                 return "INVALID_KEY";
147         case CONNECTION_ERROR_NO_REPLY:
148                 return "NO_REPLY";
149         case CONNECTION_ERROR_PERMISSION_DENIED:
150                 return "PERMISSION_DENIED";
151         case CONNECTION_ERROR_NOT_SUPPORTED:
152                 return "NOT_SUPPORTED";
153         }
154
155         return "UNKNOWN";
156 }
157
158 static const char *__libnet_convert_cp_state_to_string(connection_profile_state_e state)
159 {
160         switch (state) {
161         case CONNECTION_PROFILE_STATE_DISCONNECTED:
162                 return "DISCONNECTED";
163         case CONNECTION_PROFILE_STATE_ASSOCIATION:
164                 return "ASSOCIATION";
165         case CONNECTION_PROFILE_STATE_CONFIGURATION:
166                 return "CONFIGURATION";
167         case CONNECTION_PROFILE_STATE_CONNECTED:
168                 return "CONNECTED";
169         default:
170                 return "UNKNOWN";
171         }
172 }
173
174 static void __libnet_set_reset_profile_cb(connection_opened_cb user_cb, void *user_data)
175 {
176         if (user_cb != NULL) {
177                 libnet.reset_profile_cb = user_cb;
178                 libnet.reset_profile_user_data = user_data;
179         }
180 }
181
182 static gboolean __libnet_reset_profile_cb_idle(gpointer data)
183 {
184         connection_error_e result = (connection_error_e)data;
185
186         if (libnet.reset_profile_cb != NULL)
187                 libnet.reset_profile_cb(result, libnet.reset_profile_user_data);
188
189         libnet.reset_profile_cb = NULL;
190         libnet.reset_profile_user_data = NULL;
191
192         return FALSE;
193 }
194
195 static void __libnet_reset_profile_cb(connection_error_e result)
196 {
197         if (_connection_is_created() != true) {
198                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
199                                 "If multi-threaded, thread integrity be broken.");
200                 return;
201         }
202
203         if (libnet.reset_profile_cb != NULL)
204                 _connection_callback_add(__libnet_reset_profile_cb_idle, (gpointer)result);
205 }
206
207 static void __libnet_set_opened_cb(connection_opened_cb user_cb, void *user_data)
208 {
209         if (user_cb != NULL) {
210                 libnet.opened_cb = user_cb;
211                 libnet.opened_user_data = user_data;
212         }
213 }
214
215 static gboolean __libnet_opened_cb_idle(gpointer data)
216 {
217         connection_error_e result = (connection_error_e)data;
218
219         if (libnet.opened_cb != NULL)
220                 libnet.opened_cb(result, libnet.opened_user_data);
221
222         libnet.opened_cb = NULL;
223         libnet.opened_user_data = NULL;
224
225         return FALSE;
226 }
227
228 static void __libnet_opened_cb(connection_error_e result)
229 {
230         if (_connection_is_created() != true) {
231                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
232                                 "If multi-threaded, thread integrity be broken.");
233                 return;
234         }
235
236         if (libnet.opened_cb != NULL)
237                 _connection_callback_add(__libnet_opened_cb_idle, (gpointer)result);
238 }
239
240 static void __libnet_set_closed_cb(connection_closed_cb user_cb, void *user_data)
241 {
242         if (user_cb != NULL) {
243                 libnet.closed_cb = user_cb;
244                 libnet.closed_user_data = user_data;
245         }
246 }
247
248 static gboolean __libnet_closed_cb_idle(gpointer data)
249 {
250         connection_error_e result = (connection_error_e)data;
251
252         if (libnet.closed_cb != NULL)
253                 libnet.closed_cb(result, libnet.closed_user_data);
254
255         libnet.closed_cb = NULL;
256         libnet.closed_user_data = NULL;
257
258         return FALSE;
259 }
260
261 static void __libnet_closed_cb(connection_error_e result)
262 {
263         if (_connection_is_created() != true) {
264                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
265                                 "If multi-threaded, thread integrity be broken.");
266                 return;
267         }
268
269         if (libnet.closed_cb != NULL)
270                 _connection_callback_add(__libnet_closed_cb_idle, (gpointer)result);
271 }
272
273 static void __libnet_set_default_cb(connection_set_default_cb user_cb, void *user_data)
274 {
275         if (user_cb != NULL) {
276                 libnet.set_default_cb = user_cb;
277                 libnet.set_default_user_data = user_data;
278         }
279 }
280
281 static gboolean __libnet_default_cb_idle(gpointer data)
282 {
283         connection_error_e result = (connection_error_e)data;
284
285         if (libnet.set_default_cb != NULL)
286                 libnet.set_default_cb(result, libnet.set_default_user_data);
287
288         libnet.set_default_cb = NULL;
289         libnet.set_default_user_data = NULL;
290
291         return FALSE;
292 }
293
294 static void __libnet_default_cb(connection_error_e result)
295 {
296         if (_connection_is_created() != true) {
297                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
298                                 "If multi-threaded, thread integrity be broken.");
299                 return;
300         }
301
302         if (libnet.set_default_cb != NULL)
303                 _connection_callback_add(__libnet_default_cb_idle, (gpointer)result);
304 }
305
306 static void __libnet_set_ethernet_cable_state_changed_cb(
307                 libnet_ethernet_cable_state_changed_cb user_cb)
308 {
309         libnet.ethernet_cable_state_changed_cb = user_cb;
310 }
311
312 static void __libnet_ethernet_cable_state_changed_cb(
313                 connection_ethernet_cable_state_e state)
314 {
315         if (libnet.ethernet_cable_state_changed_cb)
316                 libnet.ethernet_cable_state_changed_cb(state);
317 }
318
319 static void __libnet_type_changed_cb(int type)
320 {
321         if (libnet.type_changed_cb)
322                 libnet.type_changed_cb(type);
323 }
324
325 static void __libnet_ip_changed_cb(connection_address_family_e addr_family,
326                                                                    char *ip_addr)
327 {
328         if (libnet.ip_changed_cb)
329                 libnet.ip_changed_cb(addr_family, ip_addr);
330 }
331
332 static void __libnet_proxy_changed_cb(char *proxy_addr)
333 {
334         if (libnet.proxy_changed_cb)
335                 libnet.proxy_changed_cb(proxy_addr);
336 }
337
338 static gboolean __libnet_state_changed_cb_idle(gpointer data)
339 {
340         struct _state_notify *notify = (struct _state_notify *)data;
341
342         if (notify == NULL)
343                 return FALSE;
344
345         if (notify->callback != NULL)
346                 notify->callback(notify->state, notify->user_data);
347
348         g_free(notify);
349
350         return FALSE;
351 }
352
353 static void __libnet_state_changed_cb(char *profile_name, connection_profile_state_e state)
354 {
355         guint id;
356         struct _state_notify *notify;
357         struct _profile_cb_s *cb_info;
358
359         if (_connection_is_created() != true) {
360                 CONNECTION_LOG(CONNECTION_ERROR, "Application is not registered"
361                                 "If multi-threaded, thread integrity be broken.");
362                 return;
363         }
364
365         if (profile_name == NULL)
366                 return;
367
368         cb_info = g_hash_table_lookup(profile_cb_table, profile_name);
369         if (cb_info == NULL)
370                 return;
371
372         if (cb_info->state == state)
373                 return;
374
375         cb_info->state = state;
376
377         if (state < 0 || cb_info->callback == NULL)
378                 return;
379
380         notify = g_try_new0(struct _state_notify, 1);
381         if (notify == NULL)
382                 return;
383
384         notify->callback = cb_info->callback;
385         notify->state = state;
386         notify->user_data = cb_info->user_data;
387
388         id = _connection_callback_add(__libnet_state_changed_cb_idle,
389                         (gpointer)notify);
390         if (!id)
391                 g_free(notify);
392 }
393
394 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
395 {
396         if (profile_list->count > 0)
397                 g_free(profile_list->profiles);
398
399         profile_list->count = 0;
400         profile_list->next = 0;
401         profile_list->profiles = NULL;
402 }
403
404 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
405 {
406         bool is_requested = false;
407         connection_error_e result = CONNECTION_ERROR_NONE;
408
409         switch (event_cb->Event) {
410         case NET_EVENT_OPEN_RSP:
411                 is_requested = true;
412                 /* fall through */
413         case NET_EVENT_OPEN_IND:
414                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
415                 CONNECTION_LOG(CONNECTION_INFO, "Connection opened %s[%s]",
416                                         (is_requested) ? "RSP" : "IND",
417                                         __libnet_convert_cp_error_type_to_string(result));
418
419                 if (is_requested)
420                         __libnet_opened_cb(result);
421
422                 switch (event_cb->Error) {
423                 case NET_ERR_NONE:
424                 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
425                         CONNECTION_LOG(CONNECTION_INFO, "Successfully open connection");
426
427                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_CONNECTED);
428                         return;
429                 default:
430                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open connection[%s]",
431                                                 __libnet_convert_cp_error_type_to_string(result));
432                 }
433
434                 __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
435
436                 break;
437         case NET_EVENT_CLOSE_RSP:
438                 is_requested = true;
439                 /* fall through */
440         case NET_EVENT_CLOSE_IND:
441                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
442                 CONNECTION_LOG(CONNECTION_INFO, "Connection closed %s[%s]",
443                                         (is_requested) ? "RSP" : "IND",
444                                         __libnet_convert_cp_error_type_to_string(result));
445
446                 if (is_requested)
447                         __libnet_closed_cb(result);
448
449                 switch (event_cb->Error) {
450                 case NET_ERR_NONE:
451                         CONNECTION_LOG(CONNECTION_INFO, "Successfully closed connection");
452
453                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
454                         return;
455                 default:
456                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to close connection[%s]",
457                                                         __libnet_convert_cp_error_type_to_string(result));
458                 }
459
460                 break;
461         case NET_EVENT_NET_STATE_IND:
462                 CONNECTION_LOG(CONNECTION_INFO, "State changed IND");
463
464                 if (event_cb->Datalength != sizeof(net_state_type_t))
465                         return;
466
467                 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
468                 connection_profile_state_e cp_state = _profile_convert_to_cp_state(*profile_state);
469
470                 CONNECTION_LOG(CONNECTION_INFO, "state: %s", __libnet_convert_cp_state_to_string(cp_state));
471                 SECURE_CONNECTION_LOG(CONNECTION_INFO, "profile name: %s", event_cb->ProfileName);
472
473                 __libnet_state_changed_cb(event_cb->ProfileName, cp_state);
474
475                 break;
476         case NET_EVENT_CELLULAR_SET_DEFAULT_RSP:
477                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
478                 CONNECTION_LOG(CONNECTION_INFO, "Got set default profile RSP %d", result);
479                 __libnet_default_cb(result);
480                 break;
481
482         case NET_EVENT_CELLULAR_RESET_DEFAULT_RSP:
483                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
484                 CONNECTION_LOG(CONNECTION_INFO, "Got reset default profile RSP %d", result);
485                 __libnet_reset_profile_cb(result);
486                 break;
487         case NET_EVENT_ETHERNET_CABLE_ATTACHED:
488                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable Attached Indication\n");
489                 __libnet_ethernet_cable_state_changed_cb(CONNECTION_ETHERNET_CABLE_ATTACHED);
490                 break;
491         case NET_EVENT_ETHERNET_CABLE_DETACHED:
492                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable detached Indication\n");
493                 __libnet_ethernet_cable_state_changed_cb(CONNECTION_ETHERNET_CABLE_DETACHED);
494                 break;
495         case NET_EVENT_NETWORK_TYPE_CHANGED:
496                 CONNECTION_LOG(CONNECTION_INFO, "Got Network Type Changed Indication");
497                 int *state = (int *) event_cb->Data;
498                 __libnet_type_changed_cb(*state);
499                 break;
500         case NET_EVENT_IPV4_ADDRESS_CHANGED:
501                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv4 Address Changed Indication");
502                 char *ipv4_addr = (char *)event_cb->Data;
503                 __libnet_ip_changed_cb(CONNECTION_ADDRESS_FAMILY_IPV4, ipv4_addr);
504                 break;
505         case NET_EVENT_IPV6_ADDRESS_CHANGED:
506                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv6 Address Changed Indication");
507                 char *ipv6_addr = (char *)event_cb->Data;
508                 __libnet_ip_changed_cb(CONNECTION_ADDRESS_FAMILY_IPV6, ipv6_addr);
509                 break;
510         case NET_EVENT_PROXY_ADDRESS_CHANGED:
511                 CONNECTION_LOG(CONNECTION_INFO, "Got Proxy Changed Indication");
512                 char *proxy_addr = (char *)event_cb->Data;
513                 __libnet_proxy_changed_cb(proxy_addr);
514                 break;
515
516         default:
517                 break;
518         }
519 }
520 //LCOV_EXCL_STOP
521
522 int __libnet_get_connected_count(struct _profile_list_s *profile_list)
523 {
524         int count = 0;
525         int i = 0;
526
527         for (; i < profile_list->count; i++) {
528                 if (profile_list->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
529                     profile_list->profiles[i].ProfileState == NET_STATE_TYPE_READY)
530                         count++;
531         }
532
533         return count;
534 }
535
536 void __libnet_copy_connected_profile(net_profile_info_t **dest, struct _profile_list_s *source)
537 {
538         int i = 0;
539
540         for (; i < source->count; i++) {
541                 if (source->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
542                     source->profiles[i].ProfileState == NET_STATE_TYPE_READY) {
543                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
544                         (*dest)++;
545                 }
546         }
547 }
548
549 //LCOV_EXCL_START
550 int __libnet_get_default_count(struct _profile_list_s *profile_list)
551 {
552         int count = 0;
553         int i = 0;
554
555         for (; i < profile_list->count; i++) {
556                 if (profile_list->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE)
557                         count++;
558         }
559
560         return count;
561 }
562
563 void __libnet_copy_default_profile(net_profile_info_t **dest, struct _profile_list_s *source)
564 {
565         int i = 0;
566
567         for (; i < source->count; i++) {
568                 if (source->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE) {
569                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
570                         (*dest)++;
571                 }
572         }
573 }
574 //LCOV_EXCL_STOP
575
576 int _connection_libnet_init(void)
577 {
578         int rv;
579
580         if (_connection_is_created() != true) {
581                 rv = net_register_client_ext((net_event_cb_t)__libnet_evt_cb, NET_DEVICE_DEFAULT, NULL);
582                 if (rv != NET_ERR_NONE)
583                         return rv;
584
585                 __connection_set_created(true);
586
587                 if (profile_cb_table == NULL)
588                         profile_cb_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
589         }
590
591         return NET_ERR_NONE;
592 }
593
594 bool _connection_libnet_deinit(void)
595 {
596         if (_connection_is_created() == true) {
597                 if (net_deregister_client_ext(NET_DEVICE_DEFAULT) != NET_ERR_NONE)
598                         return false;
599
600                 __connection_set_created(false);
601
602                 if (profile_cb_table) {
603                         g_hash_table_destroy(profile_cb_table);
604                         profile_cb_table = NULL;
605                 }
606
607                 __libnet_clear_profile_list(&profile_iterator);
608
609                 if (prof_handle_list) {
610                         g_slist_free_full(prof_handle_list, g_free);
611                         prof_handle_list = NULL;
612                 }
613         }
614
615         return true;
616 }
617
618 void _connection_set_cs_tid(int tid)
619 {
620         net_set_cs_tid(tid);
621 }
622
623 void _connection_unset_cs_tid(int tid)
624 {
625         net_unset_cs_tid(tid);
626 }
627
628 bool _connection_libnet_check_profile_validity(connection_profile_h profile)
629 {
630         GSList *list;
631         int i = 0;
632
633         if (profile == NULL)
634                 return false;
635
636         for (list = prof_handle_list; list; list = list->next)
637                 if (profile == list->data) return true;
638
639         for (; i < profile_iterator.count; i++)
640                 if (profile == &profile_iterator.profiles[i]) return true;
641
642         return false;
643 }
644
645 //LCOV_EXCL_START
646 bool _connection_libnet_check_profile_cb_validity(connection_profile_h profile)
647 {
648         struct _profile_cb_s *cb_info;
649         net_profile_info_t *profile_info = profile;
650
651         if (profile == NULL)
652                 return false;
653
654         cb_info = g_hash_table_lookup(profile_cb_table, profile_info->ProfileName);
655         if (cb_info != NULL)
656                 return true;
657
658         return false;
659 }
660 //LCOV_EXCL_STOP
661
662 int _connection_libnet_get_metered_state(bool* is_metered)
663 {
664         int rv = 0;
665         int status = 0;
666
667         rv = net_get_metered_state(&status);
668         if (rv == NET_ERR_ACCESS_DENIED) {
669                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
670                 return CONNECTION_ERROR_PERMISSION_DENIED;
671         } else if (rv != NET_ERR_NONE) {
672                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get metered state[%d]", rv);
673                 return CONNECTION_ERROR_OPERATION_FAILED;
674         }
675
676         if (status == 1)
677                 *is_metered = true;
678         else
679                 *is_metered = false;
680         return CONNECTION_ERROR_NONE;
681 }
682
683 int _connection_libnet_get_wifi_state(connection_wifi_state_e *state)
684 {
685         int rv;
686         net_wifi_state_t wlan_state;
687
688         rv = net_get_wifi_state(&wlan_state);
689         if (rv == NET_ERR_ACCESS_DENIED) {
690                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
691                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
692         } else if (rv != NET_ERR_NONE) {
693                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi state[%d]", rv); //LCOV_EXCL_LINE
694                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
695         }
696
697         switch (wlan_state) {
698         case WIFI_OFF:
699                 *state = CONNECTION_WIFI_STATE_DEACTIVATED;
700                 break;
701         case WIFI_ON:
702         case WIFI_ASSOCIATION:
703         case WIFI_CONFIGURATION:
704                 *state = CONNECTION_WIFI_STATE_DISCONNECTED;
705                 break;
706         case WIFI_CONNECTED:
707         case WIFI_DISCONNECTING:
708                 *state = CONNECTION_WIFI_STATE_CONNECTED;
709                 break;
710         default:
711                 CONNECTION_LOG(CONNECTION_ERROR, "Unknown Wi-Fi state"); //LCOV_EXCL_LINE
712                 return CONNECTION_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
713         }
714
715         return CONNECTION_ERROR_NONE;
716 }
717
718 void _connection_libnet_set_type_changed_cb(libnet_type_changed_cb callback)
719 {
720         libnet.type_changed_cb = callback;
721 }
722
723 void _connection_libnet_set_ip_changed_cb(libnet_ip_changed_cb callback)
724 {
725         libnet.ip_changed_cb = callback;
726 }
727
728 void _connection_libnet_set_proxy_changed_cb(libnet_proxy_changed_cb callback)
729 {
730         libnet.proxy_changed_cb = callback;
731 }
732
733 //LCOV_EXCL_START
734 int _connection_libnet_get_ethernet_state(connection_ethernet_state_e *state)
735 {
736         int rv;
737         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
738         rv = net_get_profile_list(NET_DEVICE_ETHERNET, &ethernet_profiles.profiles, &ethernet_profiles.count);
739         if (rv == NET_ERR_ACCESS_DENIED) {
740                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
741                 return CONNECTION_ERROR_PERMISSION_DENIED;
742         }
743
744         if (ethernet_profiles.count == 0) {
745                 *state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
746                 return CONNECTION_ERROR_NONE;
747         }
748
749         switch (ethernet_profiles.profiles->ProfileState) {
750         case NET_STATE_TYPE_ONLINE:
751         case NET_STATE_TYPE_READY:
752                 *state = CONNECTION_ETHERNET_STATE_CONNECTED;
753                 break;
754         case NET_STATE_TYPE_IDLE:
755         case NET_STATE_TYPE_FAILURE:
756         case NET_STATE_TYPE_ASSOCIATION:
757         case NET_STATE_TYPE_CONFIGURATION:
758         case NET_STATE_TYPE_DISCONNECT:
759                 *state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
760                 break;
761         default:
762                 __libnet_clear_profile_list(&ethernet_profiles);
763                 return CONNECTION_ERROR_OPERATION_FAILED;
764         }
765
766         __libnet_clear_profile_list(&ethernet_profiles);
767
768         return CONNECTION_ERROR_NONE;
769 }
770
771 int _connection_libnet_get_ethernet_cable_state(connection_ethernet_cable_state_e* state)
772 {
773         int rv = 0;
774         int status = 0;
775
776         rv = net_get_ethernet_cable_state(&status);
777         if (rv == NET_ERR_ACCESS_DENIED) {
778                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
779                 return CONNECTION_ERROR_PERMISSION_DENIED;
780         } else if (rv != NET_ERR_NONE) {
781                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
782                 return CONNECTION_ERROR_OPERATION_FAILED;
783         }
784
785         if (status == 1)
786                 *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
787         else
788                 *state = CONNECTION_ETHERNET_CABLE_DETACHED;
789         return CONNECTION_ERROR_NONE;
790 }
791
792 int _connection_libnet_set_ethernet_cable_state_changed_cb(
793                 libnet_ethernet_cable_state_changed_cb callback)
794 {
795         __libnet_set_ethernet_cable_state_changed_cb(callback);
796
797         return CONNECTION_ERROR_NONE;
798 }
799 //LCOV_EXCL_STOP
800
801 int _connection_libnet_get_bluetooth_state(connection_bt_state_e *state)
802 {
803         int i = 0;
804         int rv = 0;
805         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
806         rv = net_get_profile_list(NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles, &bluetooth_profiles.count);
807         if (rv == NET_ERR_ACCESS_DENIED) {
808                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
809                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
810         }
811
812         if (bluetooth_profiles.count == 0) {
813                 *state = CONNECTION_BT_STATE_DEACTIVATED;
814                 return CONNECTION_ERROR_NONE;
815         }
816
817         //LCOV_EXCL_START
818         for (; i < bluetooth_profiles.count; i++) {
819                 switch (bluetooth_profiles.profiles[i].ProfileState) {
820                 case NET_STATE_TYPE_ONLINE:
821                 case NET_STATE_TYPE_READY:
822                         *state = CONNECTION_BT_STATE_CONNECTED;
823                         goto done;
824                 case NET_STATE_TYPE_IDLE:
825                 case NET_STATE_TYPE_FAILURE:
826                 case NET_STATE_TYPE_ASSOCIATION:
827                 case NET_STATE_TYPE_CONFIGURATION:
828                 case NET_STATE_TYPE_DISCONNECT:
829                         *state = CONNECTION_BT_STATE_DISCONNECTED;
830                         break;
831                 default:
832                         __libnet_clear_profile_list(&bluetooth_profiles);
833                         return CONNECTION_ERROR_OPERATION_FAILED;
834                 }
835         }
836         //LCOV_EXCL_STOP
837
838 done:
839         __libnet_clear_profile_list(&bluetooth_profiles);
840
841         return CONNECTION_ERROR_NONE;
842 }
843
844 int _connection_libnet_get_profile_iterator(connection_iterator_type_e type, connection_profile_iterator_h* profile_iter_h)
845 {
846         int count = 0;
847         int rv1, rv2, rv3, rv4;
848         net_profile_info_t *profiles = NULL;
849
850         struct _profile_list_s wifi_profiles = {0, 0, NULL};
851         struct _profile_list_s cellular_profiles = {0, 0, NULL};
852         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
853         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
854
855         __libnet_clear_profile_list(&profile_iterator);
856
857         rv1 = net_get_profile_list(NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
858         if (rv1 == NET_ERR_ACCESS_DENIED) {
859                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
860                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
861         } else if (rv1 != NET_ERR_NO_SERVICE && rv1 != NET_ERR_NONE)
862                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
863
864         CONNECTION_LOG(CONNECTION_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
865
866         rv2 = net_get_profile_list(NET_DEVICE_CELLULAR, &cellular_profiles.profiles, &cellular_profiles.count);
867         if (rv2 == NET_ERR_ACCESS_DENIED) {
868                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
869                 __libnet_clear_profile_list(&wifi_profiles);
870                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
871         } else if (rv2 != NET_ERR_NO_SERVICE && rv2 != NET_ERR_NONE) {
872                 __libnet_clear_profile_list(&wifi_profiles);
873                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
874         }
875         CONNECTION_LOG(CONNECTION_INFO, "Cellular profile count: %d", cellular_profiles.count);
876
877         rv3 = net_get_profile_list(NET_DEVICE_ETHERNET, &ethernet_profiles.profiles, &ethernet_profiles.count);
878         if (rv3 == NET_ERR_ACCESS_DENIED) {
879                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
880                 __libnet_clear_profile_list(&wifi_profiles);
881                 __libnet_clear_profile_list(&cellular_profiles);
882                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
883         } else if (rv3 != NET_ERR_NO_SERVICE && rv3 != NET_ERR_NONE) {
884                 __libnet_clear_profile_list(&wifi_profiles);
885                 __libnet_clear_profile_list(&cellular_profiles);
886                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
887         }
888         CONNECTION_LOG(CONNECTION_INFO, "Ethernet profile count : %d", ethernet_profiles.count);
889
890         rv4 = net_get_profile_list(NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles, &bluetooth_profiles.count);
891         if (rv4 == NET_ERR_ACCESS_DENIED) {
892                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
893                 __libnet_clear_profile_list(&wifi_profiles);
894                 __libnet_clear_profile_list(&cellular_profiles);
895                 __libnet_clear_profile_list(&ethernet_profiles);
896                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
897         } else if (rv4 != NET_ERR_NO_SERVICE && rv4 != NET_ERR_NONE) {
898                 __libnet_clear_profile_list(&wifi_profiles);
899                 __libnet_clear_profile_list(&cellular_profiles);
900                 __libnet_clear_profile_list(&ethernet_profiles);
901                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
902         }
903         CONNECTION_LOG(CONNECTION_INFO, "Bluetooth profile count : %d", bluetooth_profiles.count);
904
905         *profile_iter_h = &profile_iterator;
906
907         switch (type) {
908         case CONNECTION_ITERATOR_TYPE_REGISTERED:
909                 count = wifi_profiles.count + cellular_profiles.count + ethernet_profiles.count + bluetooth_profiles.count;
910                 CONNECTION_LOG(CONNECTION_INFO, "Total profile count : %d", count);
911                 if (count == 0)
912                         return CONNECTION_ERROR_NONE;
913
914                 profiles = g_try_new0(net_profile_info_t, count);
915                 if (profiles == NULL) {
916                         __libnet_clear_profile_list(&wifi_profiles);
917                         __libnet_clear_profile_list(&cellular_profiles);
918                         __libnet_clear_profile_list(&ethernet_profiles);
919                         __libnet_clear_profile_list(&bluetooth_profiles);
920                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
921                 }
922
923                 profile_iterator.profiles = profiles;
924
925                 if (wifi_profiles.count > 0) {
926                         memcpy(profiles, wifi_profiles.profiles,
927                                         sizeof(net_profile_info_t) * wifi_profiles.count);
928                         profiles += wifi_profiles.count;
929                 }
930
931                 if (cellular_profiles.count > 0) {
932                         memcpy(profiles, cellular_profiles.profiles,
933                                         sizeof(net_profile_info_t) * cellular_profiles.count);
934                         profiles += cellular_profiles.count;
935                 }
936
937                 if (ethernet_profiles.count > 0) {
938                         memcpy(profiles, ethernet_profiles.profiles,
939                                         sizeof(net_profile_info_t) * ethernet_profiles.count);
940                         profiles += ethernet_profiles.count;
941                 }
942
943                 if (bluetooth_profiles.count > 0)
944                         memcpy(profiles, bluetooth_profiles.profiles,
945                                         sizeof(net_profile_info_t) * bluetooth_profiles.count);
946
947                 break;
948         case CONNECTION_ITERATOR_TYPE_CONNECTED:
949                 count = __libnet_get_connected_count(&wifi_profiles);
950                 count += __libnet_get_connected_count(&cellular_profiles);
951                 count += __libnet_get_connected_count(&ethernet_profiles);
952                 count += __libnet_get_connected_count(&bluetooth_profiles);
953                 CONNECTION_LOG(CONNECTION_INFO, "Total connected profile count : %d", count);
954                 if (count == 0)
955                         return CONNECTION_ERROR_NONE;
956
957                 profiles = g_try_new0(net_profile_info_t, count);
958                 if (profiles == NULL) {
959                         __libnet_clear_profile_list(&wifi_profiles);
960                         __libnet_clear_profile_list(&cellular_profiles);
961                         __libnet_clear_profile_list(&ethernet_profiles);
962                         __libnet_clear_profile_list(&bluetooth_profiles);
963                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
964                 }
965
966                 profile_iterator.profiles = profiles;
967
968                 if (wifi_profiles.count > 0)
969                         __libnet_copy_connected_profile(&profiles, &wifi_profiles);
970
971                 if (cellular_profiles.count > 0)
972                         __libnet_copy_connected_profile(&profiles, &cellular_profiles);
973
974                 if (ethernet_profiles.count > 0)
975                         __libnet_copy_connected_profile(&profiles, &ethernet_profiles);
976
977                 if (bluetooth_profiles.count > 0)
978                         __libnet_copy_connected_profile(&profiles, &bluetooth_profiles);
979
980                 break;
981         case CONNECTION_ITERATOR_TYPE_DEFAULT:
982                 count = __libnet_get_default_count(&cellular_profiles);
983                 CONNECTION_LOG(CONNECTION_INFO, "Total default profile count : %d", count); //LCOV_EXCL_LINE
984                 if (count == 0)
985                         return CONNECTION_ERROR_NONE;
986
987                 profiles = g_try_new0(net_profile_info_t, count);
988                 if (profiles == NULL) {
989                         __libnet_clear_profile_list(&wifi_profiles);
990                         __libnet_clear_profile_list(&cellular_profiles);
991                         __libnet_clear_profile_list(&ethernet_profiles);
992                         __libnet_clear_profile_list(&bluetooth_profiles);
993                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
994                 }
995
996                 profile_iterator.profiles = profiles;
997
998                 if (cellular_profiles.count > 0)
999                         __libnet_copy_default_profile(&profiles, &cellular_profiles);
1000                 break;
1001         }
1002
1003         __libnet_clear_profile_list(&wifi_profiles);
1004         __libnet_clear_profile_list(&cellular_profiles);
1005         __libnet_clear_profile_list(&ethernet_profiles);
1006         __libnet_clear_profile_list(&bluetooth_profiles);
1007
1008         profile_iterator.count = count;
1009
1010         return CONNECTION_ERROR_NONE;
1011 }
1012
1013 int _connection_libnet_get_iterator_next(connection_profile_iterator_h profile_iter_h, connection_profile_h *profile)
1014 {
1015         if (profile_iter_h != &profile_iterator)
1016                 return CONNECTION_ERROR_INVALID_PARAMETER;
1017
1018         if (profile_iterator.count <= profile_iterator.next)
1019                 return CONNECTION_ERROR_ITERATOR_END;
1020
1021         *profile = &profile_iterator.profiles[profile_iterator.next];
1022         profile_iterator.next++;
1023
1024         return CONNECTION_ERROR_NONE;
1025 }
1026
1027 bool _connection_libnet_iterator_has_next(connection_profile_iterator_h profile_iter_h)
1028 {
1029         if (profile_iter_h != &profile_iterator)
1030                 return false;
1031
1032         if (profile_iterator.count <= profile_iterator.next)
1033                 return false;
1034
1035         return true;
1036 }
1037
1038 int _connection_libnet_destroy_iterator(connection_profile_iterator_h profile_iter_h)
1039 {
1040         if (profile_iter_h != &profile_iterator)
1041                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1042
1043         __libnet_clear_profile_list(&profile_iterator);
1044
1045         return CONNECTION_ERROR_NONE;
1046 }
1047
1048 int _connection_libnet_get_current_profile(connection_profile_h *profile)
1049 {
1050         net_profile_info_t active_profile;
1051         int rv;
1052
1053         rv = net_get_active_net_info(&active_profile);
1054         if (rv == NET_ERR_NO_SERVICE)
1055                 return CONNECTION_ERROR_NO_CONNECTION; //LCOV_EXCL_LINE
1056         else if (rv == NET_ERR_ACCESS_DENIED) {
1057                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1058                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1059         } else if (rv != NET_ERR_NONE)
1060                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1061
1062         *profile = g_try_malloc0(sizeof(net_profile_info_t));
1063         if (*profile == NULL)
1064                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
1065
1066         memcpy(*profile, &active_profile, sizeof(net_profile_info_t));
1067         prof_handle_list = g_slist_append(prof_handle_list, *profile);
1068
1069         return CONNECTION_ERROR_NONE;
1070 }
1071
1072 int _connection_libnet_reset_profile(connection_reset_option_e type,
1073                 connection_cellular_subscriber_id_e id, connection_reset_cb callback, void *user_data)
1074 {
1075         int rv;
1076
1077         rv = net_reset_profile(type, id);
1078         if (rv == NET_ERR_ACCESS_DENIED) {
1079                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1080                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1081         } else if (rv != NET_ERR_NONE) {
1082                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv); //LCOV_EXCL_LINE
1083                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1084         }
1085
1086         __libnet_set_reset_profile_cb(callback, user_data);
1087
1088         return CONNECTION_ERROR_NONE;
1089 }
1090
1091 int _connection_libnet_open_profile(connection_profile_h profile,
1092                 connection_opened_cb callback, void* user_data)
1093 {
1094         int rv;
1095
1096         if (!(_connection_libnet_check_profile_validity(profile))) {
1097                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1098                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1099         }
1100
1101         net_profile_info_t *profile_info = profile;
1102
1103         rv = net_open_connection_with_profile(profile_info->ProfileName);
1104         if (rv == NET_ERR_ACCESS_DENIED) {
1105                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1106                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1107         } else if (rv != NET_ERR_NONE)
1108                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1109
1110         __libnet_set_opened_cb(callback, user_data);
1111
1112         return CONNECTION_ERROR_NONE;
1113 }
1114
1115 int _connection_libnet_get_cellular_service_profile(
1116                 connection_cellular_service_type_e type, connection_profile_h *profile)
1117 {
1118         int i = 0, j = 0;
1119         int rv = NET_ERR_NONE;
1120 #if defined TIZEN_DUALSIM_ENABLE
1121         int default_subscriber_id = 0;
1122         char subscriber_id[3];
1123 #endif
1124
1125         struct _profile_list_s cellular_profiles = { 0, 0, NULL };
1126         net_service_type_t service_type = _connection_profile_convert_to_libnet_cellular_service_type(type);
1127
1128         rv = net_get_profile_list(NET_DEVICE_CELLULAR, &cellular_profiles.profiles, &cellular_profiles.count);
1129         if (rv == NET_ERR_ACCESS_DENIED) {
1130                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1131                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1132         } else if (rv != NET_ERR_NONE) {
1133                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get profile list (%d)", rv); //LCOV_EXCL_LINE
1134                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1135         }
1136
1137 #if defined TIZEN_DUALSIM_ENABLE
1138         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE,
1139                                                 &default_subscriber_id) != 0) {
1140                 CONNECTION_LOG(CONNECTION_ERROR,
1141                                                 "Failed to get VCONF_TELEPHONY_DEFAULT_DATA_SERVICE");
1142                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1143                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1144         }
1145
1146         g_snprintf(subscriber_id, sizeof(subscriber_id), "%d", default_subscriber_id);
1147 #endif
1148
1149         for (i = 0; i < cellular_profiles.count; i++)
1150                 if (cellular_profiles.profiles[i].ProfileInfo.Pdp.ServiceType == service_type)
1151 #if defined TIZEN_DUALSIM_ENABLE
1152                         if (g_str_has_suffix(
1153                                         cellular_profiles.profiles[i].ProfileInfo.Pdp.PSModemPath,
1154                                         subscriber_id) == TRUE)
1155 #endif
1156                                 break;
1157
1158         if (i >= cellular_profiles.count) {
1159                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1160                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1161         }
1162
1163         *profile = g_try_malloc0(sizeof(net_profile_info_t));
1164         if (*profile == NULL) {
1165                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1166                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
1167         }
1168
1169         memcpy(*profile, &cellular_profiles.profiles[i], sizeof(net_profile_info_t));
1170
1171         if (cellular_profiles.profiles[i].ProfileInfo.Pdp.DefaultConn)
1172                 goto done;
1173
1174         //LCOV_EXCL_START
1175         if (type != CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET &&
1176             type != CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET)
1177                 goto done;
1178
1179         for (j = 0; j < cellular_profiles.count; j++) {
1180                 if (i == j)
1181                         continue;
1182
1183                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.ServiceType != service_type)
1184                         continue;
1185
1186                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.DefaultConn) {
1187                         memcpy(*profile, &cellular_profiles.profiles[j], sizeof(net_profile_info_t));
1188                         goto done;
1189                 }
1190         }
1191         //LCOV_EXCL_STOP
1192
1193 done:
1194         __libnet_clear_profile_list(&cellular_profiles);
1195         prof_handle_list = g_slist_append(prof_handle_list, *profile);
1196
1197         return CONNECTION_ERROR_NONE;
1198 }
1199
1200 int _connection_libnet_set_cellular_service_profile_sync(connection_cellular_service_type_e type, connection_profile_h profile)
1201 {
1202         int rv;
1203
1204         if (!(_connection_libnet_check_profile_validity(profile))) {
1205                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1206                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1207         }
1208
1209         net_profile_info_t *profile_info = profile;
1210         connection_cellular_service_type_e service_type;
1211
1212         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1213
1214         if (service_type != type)
1215                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1216
1217         rv = net_set_default_cellular_service_profile(profile_info->ProfileName);
1218         if (rv == NET_ERR_ACCESS_DENIED) {
1219                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1220                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1221         } else if (rv != NET_ERR_NONE)
1222                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1223
1224         return CONNECTION_ERROR_NONE;
1225 }
1226
1227 int _connection_libnet_set_cellular_service_profile_async(connection_cellular_service_type_e type,
1228                         connection_profile_h profile, connection_set_default_cb callback, void* user_data)
1229 {
1230         int rv;
1231
1232         if (!(_connection_libnet_check_profile_validity(profile))) {
1233                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1234                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1235         }
1236
1237         net_profile_info_t *profile_info = profile;
1238         connection_cellular_service_type_e service_type;
1239
1240         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1241
1242         if (service_type != type)
1243                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1244
1245         rv = net_set_default_cellular_service_profile_async(profile_info->ProfileName);
1246         if (rv == NET_ERR_ACCESS_DENIED) {
1247                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1248                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1249         } else if (rv != NET_ERR_NONE)
1250                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1251
1252         __libnet_set_default_cb(callback, user_data);
1253
1254         return CONNECTION_ERROR_NONE;
1255 }
1256
1257 int _connection_libnet_close_profile(connection_profile_h profile, connection_closed_cb callback, void *user_data)
1258 {
1259         int rv;
1260
1261         if (!(_connection_libnet_check_profile_validity(profile))) {
1262                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1263                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1264         }
1265
1266         net_profile_info_t *profile_info = profile;
1267
1268         rv = net_close_connection(profile_info->ProfileName);
1269         if (rv == NET_ERR_ACCESS_DENIED) {
1270                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1271                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1272         } else if (rv != NET_ERR_NONE)
1273                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1274
1275         __libnet_set_closed_cb(callback, user_data);
1276
1277         return CONNECTION_ERROR_NONE;
1278 }
1279
1280 int _connection_libnet_add_route(const char *interface_name, const char *host_address)
1281 {
1282         int rv;
1283         char *endstr = NULL;
1284         int address_family = 0;
1285
1286         address_family = AF_INET;
1287
1288         endstr = strrchr(host_address, '.');
1289         if (endstr == NULL ||
1290                         strcmp(endstr, ".0") == 0 ||
1291                         strncmp(host_address, "0.", 2) == 0 ||
1292                         strstr(host_address, "255") != NULL) {
1293                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1294                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1295         }
1296
1297         rv = net_add_route(host_address, interface_name, address_family);
1298         if (rv == NET_ERR_ACCESS_DENIED) {
1299                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1300                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1301         } else if (rv != NET_ERR_NONE)
1302                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1303
1304         return CONNECTION_ERROR_NONE;
1305 }
1306
1307 int _connection_libnet_remove_route(const char *interface_name, const char *host_address)
1308 {
1309         int rv;
1310         char *endstr = strrchr(host_address, '.');
1311         int address_family = 0;
1312
1313         address_family = AF_INET;
1314
1315         endstr = strrchr(host_address, '.');
1316         if (endstr == NULL ||
1317                 strcmp(endstr, ".0") == 0 ||
1318                 strncmp(host_address, "0.", 2) == 0 ||
1319                 strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1320                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1321                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1322         }
1323
1324         rv = net_remove_route(host_address, interface_name, address_family);
1325         if (rv == NET_ERR_ACCESS_DENIED) {
1326                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1327                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1328         } else if (rv != NET_ERR_NONE)
1329                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1330
1331         return CONNECTION_ERROR_NONE;
1332 }
1333
1334 int _connection_libnet_add_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
1335 {
1336         int rv;
1337         int address_family = 0;
1338
1339         address_family = AF_INET6;
1340
1341         if (strncmp(host_address, "fe80:", 5) == 0 ||
1342                 strncmp(host_address, "ff00:", 5) == 0 ||
1343                 strncmp(host_address, "::", 2) == 0) {
1344                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1345                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1346         }
1347
1348         rv = net_add_route_ipv6(host_address, interface_name, address_family, gateway);
1349         if (rv == NET_ERR_ACCESS_DENIED) {
1350                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1351                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1352         } else if (rv != NET_ERR_NONE)
1353                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1354
1355         return CONNECTION_ERROR_NONE;
1356 }
1357
1358 int _connection_libnet_remove_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
1359 {
1360         int rv;
1361         int address_family = 0;
1362
1363         address_family = AF_INET6;
1364
1365         if (strncmp(host_address, "fe80:", 5) == 0 ||
1366                 strncmp(host_address, "ff00:", 5) == 0 ||
1367                 strncmp(host_address, "::", 2) == 0) {
1368                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1369                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1370         }
1371
1372         rv = net_remove_route_ipv6(host_address, interface_name, address_family, gateway);
1373         if (rv == NET_ERR_ACCESS_DENIED) {
1374                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1375                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1376         } else if (rv != NET_ERR_NONE)
1377                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1378
1379         return CONNECTION_ERROR_NONE;
1380 }
1381
1382 int _connection_libnet_add_route_entry(connection_address_family_e address_family,
1383                 const char *interface_name, const char *host_address, const char *gateway)
1384 {
1385         int rv;
1386         char *endstr = NULL;
1387         int address_family_type = 0;
1388
1389         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1390                 address_family_type = AF_INET;
1391         else
1392                 address_family_type = AF_INET6;
1393
1394         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1395
1396                 endstr = strrchr(host_address, '.');
1397                 if (endstr == NULL ||
1398                                 strcmp(endstr, ".0") == 0 ||
1399                                 strncmp(host_address, "0.", 2) == 0 ||
1400                                 strstr(host_address, "255") != NULL) {
1401                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1402                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1403                 }
1404
1405                 rv = net_add_route_entry(host_address, interface_name, address_family_type, gateway);
1406                 if (rv == NET_ERR_ACCESS_DENIED) {
1407                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1408                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1409                 } else if (rv != NET_ERR_NONE)
1410                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1411
1412         } else {
1413
1414                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1415                         strncmp(host_address, "ff00:", 5) == 0 ||
1416                         strncmp(host_address, "::", 2) == 0) {
1417                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1418                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1419                 }
1420
1421                 rv = net_add_route_ipv6(host_address, interface_name, address_family_type, gateway);
1422                 if (rv == NET_ERR_ACCESS_DENIED) {
1423                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1424                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1425                 } else if (rv != NET_ERR_NONE)
1426                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1427         }
1428
1429         return CONNECTION_ERROR_NONE;
1430 }
1431
1432 int _connection_libnet_remove_route_entry(connection_address_family_e address_family,
1433                 const char *interface_name, const char *host_address, const char *gateway)
1434 {
1435         int rv;
1436         char *endstr = strrchr(host_address, '.');
1437         int address_family_type = 0;
1438
1439         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1440                 address_family_type = AF_INET;
1441         else
1442                 address_family_type = AF_INET6;
1443
1444         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1445                 endstr = strrchr(host_address, '.');
1446                 if (endstr == NULL ||
1447                         strcmp(endstr, ".0") == 0 ||
1448                         strncmp(host_address, "0.", 2) == 0 ||
1449                         strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1450                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1451                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1452                 }
1453
1454                 rv = net_remove_route_entry(host_address, interface_name, address_family_type, gateway);
1455                 if (rv == NET_ERR_ACCESS_DENIED) {
1456                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1457                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1458                 } else if (rv != NET_ERR_NONE)
1459                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1460
1461         } else {
1462
1463                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1464                         strncmp(host_address, "ff00:", 5) == 0 ||
1465                         strncmp(host_address, "::", 2) == 0) {
1466                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1467                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1468                 }
1469
1470                 rv = net_remove_route_ipv6(host_address, interface_name, address_family_type, gateway);
1471                 if (rv == NET_ERR_ACCESS_DENIED) {
1472                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1473                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1474                 } else if (rv != NET_ERR_NONE)
1475                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1476         }
1477
1478         return CONNECTION_ERROR_NONE;
1479 }
1480
1481 void _connection_libnet_add_to_profile_list(connection_profile_h profile)
1482 {
1483         prof_handle_list = g_slist_append(prof_handle_list, profile);
1484 }
1485
1486 void _connection_libnet_remove_from_profile_list(connection_profile_h profile)
1487 {
1488         prof_handle_list = g_slist_remove(prof_handle_list, profile);
1489         g_free(profile);
1490 }
1491
1492 bool _connection_libnet_add_to_profile_cb_list(connection_profile_h profile,
1493                 connection_profile_state_changed_cb callback, void *user_data)
1494 {
1495         net_profile_info_t *profile_info = profile;
1496         char *profile_name = g_strdup(profile_info->ProfileName);
1497
1498         struct _profile_cb_s *profile_cb_info = g_try_malloc0(sizeof(struct _profile_cb_s));
1499         if (profile_cb_info == NULL) {
1500                 g_free(profile_name); //LCOV_EXCL_LINE
1501                 return false; //LCOV_EXCL_LINE
1502         }
1503
1504         profile_cb_info->callback = callback;
1505         profile_cb_info->user_data = user_data;
1506         profile_cb_info->state = _profile_convert_to_cp_state(profile_info->ProfileState);
1507
1508         g_hash_table_replace(profile_cb_table, profile_name, profile_cb_info);
1509
1510         return true;
1511 }
1512
1513 bool _connection_libnet_remove_from_profile_cb_list(connection_profile_h profile)
1514 {
1515         net_profile_info_t *profile_info = profile;
1516
1517         if (g_hash_table_remove(profile_cb_table, profile_info->ProfileName) == TRUE)
1518                 return true;
1519
1520         return false; //LCOV_EXCL_LINE
1521 }
1522
1523 int _connection_libnet_set_statistics(net_device_t device_type, net_statistics_type_e statistics_type)
1524 {
1525         int rv;
1526         rv = net_set_statistics(device_type, statistics_type);
1527         if (rv == NET_ERR_ACCESS_DENIED) {
1528                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1529                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1530         } else if (rv != NET_ERR_NONE)
1531                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1532
1533         return CONNECTION_ERROR_NONE;
1534 }
1535
1536 int _connection_libnet_get_statistics(net_statistics_type_e statistics_type, unsigned long long *size)
1537 {
1538         int rv;
1539         rv = net_get_statistics(NET_DEVICE_WIFI, statistics_type, size);
1540         if (rv == NET_ERR_ACCESS_DENIED) {
1541                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1542                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1543         } else if (rv != NET_ERR_NONE)
1544                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1545
1546         return CONNECTION_ERROR_NONE;
1547 }
1548
1549 int _connection_libnet_set_cellular_subscriber_id(connection_profile_h profile,
1550                 connection_cellular_subscriber_id_e sim_id)
1551 {
1552         char *modem_path = NULL;
1553         net_profile_info_t *profile_info = (net_profile_info_t *)profile;
1554
1555         if (net_get_cellular_modem_object_path(&modem_path, sim_id) != NET_ERR_NONE) {
1556                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get subscriber[%d]", sim_id); //LCOV_EXCL_LINE
1557                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1558         }
1559
1560         if (!modem_path) {
1561                 CONNECTION_LOG(CONNECTION_ERROR, "NULL modem object path"); //LCOV_EXCL_LINE
1562                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1563         }
1564
1565         g_strlcpy(profile_info->ProfileInfo.Pdp.PSModemPath, modem_path,
1566                                 NET_PROFILE_NAME_LEN_MAX);
1567         g_free(modem_path);
1568
1569         return CONNECTION_ERROR_NONE;
1570 }
1571
1572 static void __connection_idle_destroy_cb(gpointer data)
1573 {
1574         if (!data)
1575                 return;
1576
1577         managed_idler_list = g_slist_remove(managed_idler_list, data);
1578         g_free(data);
1579 }
1580
1581 static gboolean __connection_idle_cb(gpointer user_data)
1582 {
1583         struct managed_idle_data *data = (struct managed_idle_data *)user_data;
1584
1585         if (!data)
1586                 return FALSE;
1587
1588         return data->func(data->user_data);
1589 }
1590
1591 guint _connection_callback_add(GSourceFunc func, gpointer user_data)
1592 {
1593         guint id;
1594         struct managed_idle_data *data;
1595         GMainContext *context;
1596         GSource *src;
1597
1598         if (!func)
1599                 return 0;
1600
1601         data = g_try_new0(struct managed_idle_data, 1);
1602         if (!data)
1603                 return 0;
1604
1605         data->func = func;
1606         data->user_data = user_data;
1607
1608         context = g_main_context_get_thread_default();
1609         src = g_idle_source_new();
1610         g_source_set_callback(src, __connection_idle_cb, data,
1611                 __connection_idle_destroy_cb);
1612         id = g_source_attach(src, context);
1613         g_source_unref(src);
1614         if (!id) {
1615                 g_free(data);
1616                 return id;
1617         }
1618
1619         data->id = id;
1620
1621         managed_idler_list = g_slist_append(managed_idler_list, data);
1622
1623         return id;
1624 }
1625
1626 void _connection_callback_cleanup(void)
1627 {
1628         GSList *cur = managed_idler_list;
1629         GSource *src;
1630         struct managed_idle_data *data;
1631
1632         while (cur) {
1633                 //LCOV_EXCL_START
1634                 GSList *next = cur->next;
1635                 data = (struct managed_idle_data *)cur->data;
1636
1637                 src = g_main_context_find_source_by_id(g_main_context_default(), data->id);
1638                 if (src) {
1639                         g_source_destroy(src);
1640                         cur = managed_idler_list;
1641                 } else
1642                         cur = next;
1643                 //LCOV_EXCL_STOP
1644         }
1645
1646         g_slist_free(managed_idler_list);
1647         managed_idler_list = NULL;
1648 }
1649
1650 int _connection_libnet_check_get_privilege()
1651 {
1652         int rv;
1653
1654         rv = net_check_get_privilege();
1655         if (rv == NET_ERR_ACCESS_DENIED) {
1656                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1657                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1658         } else if (rv != NET_ERR_NONE)
1659                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1660
1661         return CONNECTION_ERROR_NONE;
1662 }
1663
1664 int _connection_libnet_check_profile_privilege()
1665 {
1666         int rv;
1667
1668         rv = net_check_profile_privilege();
1669         if (rv == NET_ERR_ACCESS_DENIED) {
1670                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1671                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1672         } else if (rv != NET_ERR_NONE)
1673                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1674
1675         return CONNECTION_ERROR_NONE;
1676 }
1677
1678 bool __libnet_check_feature_supported(const char *key, connection_supported_feature_e feature)
1679 {
1680         if (!connection_is_feature_checked[feature]) {
1681                 if (system_info_get_platform_bool(key, &connection_feature_supported[feature]) < 0) {
1682                         CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature getting from System Info"); //LCOV_EXCL_LINE
1683                         set_last_result(CONNECTION_ERROR_OPERATION_FAILED); //LCOV_EXCL_LINE
1684                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1685                 }
1686                 connection_is_feature_checked[feature] = true;
1687         }
1688         return connection_feature_supported[feature];
1689 }
1690
1691 int _connection_check_feature_supported(const char *feature_name, ...)
1692 {
1693         va_list list;
1694         const char *key;
1695         bool value = false;
1696         bool feature_supported = false;
1697
1698         va_start(list, feature_name);
1699         key = feature_name;
1700         while (1) {
1701                 if (strcmp(key, TELEPHONY_FEATURE) == 0)
1702                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TELEPHONY);
1703                 if (strcmp(key, WIFI_FEATURE) == 0)
1704                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_WIFI);
1705                 if (strcmp(key, TETHERING_BLUETOOTH_FEATURE) == 0)
1706                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TETHERING_BLUETOOTH);
1707                 if (strcmp(key, ETHERNET_FEATURE) == 0)
1708                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_ETHERNET);
1709
1710                 feature_supported |= value;
1711                 key = va_arg(list, const char *);
1712                 if (!key) break;
1713         }
1714         if (!feature_supported) {
1715                 CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature is not supported");
1716                 set_last_result(CONNECTION_ERROR_NOT_SUPPORTED);
1717                 va_end(list);
1718                 return CONNECTION_ERROR_NOT_SUPPORTED;
1719         }
1720
1721         va_end(list);
1722         set_last_result(CONNECTION_ERROR_NONE);
1723         return CONNECTION_ERROR_NONE;
1724 }
1725
1726 int _connection_libnet_start_tcpdump(void)
1727 {
1728         connection_error_e result = CONNECTION_ERROR_NONE;
1729         net_err_t ret = NET_ERR_NONE;
1730
1731         ret = net_start_tcpdump();
1732         result = __libnet_convert_to_cp_error_type(ret);
1733
1734         return result;
1735 }
1736
1737 int _connection_libnet_stop_tcpdump(void)
1738 {
1739         connection_error_e result = CONNECTION_ERROR_NONE;
1740         net_err_t ret = NET_ERR_NONE;
1741
1742         ret = net_stop_tcpdump();
1743         result = __libnet_convert_to_cp_error_type(ret);
1744
1745         return result;
1746 }
1747
1748 int _connection_libnet_get_tcpdump_state(gboolean *tcpdump_state)
1749 {
1750         connection_error_e result = CONNECTION_ERROR_NONE;
1751         net_err_t ret = NET_ERR_NONE;
1752
1753         ret = net_get_tcpdump_state(tcpdump_state);
1754         result = __libnet_convert_to_cp_error_type(ret);
1755
1756         return result;
1757 }