64ef8391b76fc5c7884abb2cf25388c13ab1c4ad
[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 bool _connection_libnet_check_profile_validity(connection_profile_h profile)
619 {
620         GSList *list;
621         int i = 0;
622
623         if (profile == NULL)
624                 return false;
625
626         for (list = prof_handle_list; list; list = list->next)
627                 if (profile == list->data) return true;
628
629         for (; i < profile_iterator.count; i++)
630                 if (profile == &profile_iterator.profiles[i]) return true;
631
632         return false;
633 }
634
635 //LCOV_EXCL_START
636 bool _connection_libnet_check_profile_cb_validity(connection_profile_h profile)
637 {
638         struct _profile_cb_s *cb_info;
639         net_profile_info_t *profile_info = profile;
640
641         if (profile == NULL)
642                 return false;
643
644         cb_info = g_hash_table_lookup(profile_cb_table, profile_info->ProfileName);
645         if (cb_info != NULL)
646                 return true;
647
648         return false;
649 }
650 //LCOV_EXCL_STOP
651
652 int _connection_libnet_get_metered_state(bool* is_metered)
653 {
654         int rv = 0;
655         int status = 0;
656
657         rv = net_get_metered_state(&status);
658         if (rv == NET_ERR_ACCESS_DENIED) {
659                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
660                 return CONNECTION_ERROR_PERMISSION_DENIED;
661         } else if (rv != NET_ERR_NONE) {
662                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get metered state[%d]", rv);
663                 return CONNECTION_ERROR_OPERATION_FAILED;
664         }
665
666         if (status == 1)
667                 *is_metered = true;
668         else
669                 *is_metered = false;
670         return CONNECTION_ERROR_NONE;
671 }
672
673 int _connection_libnet_get_wifi_state(connection_wifi_state_e *state)
674 {
675         int rv;
676         net_wifi_state_t wlan_state;
677
678         rv = net_get_wifi_state(&wlan_state);
679         if (rv == NET_ERR_ACCESS_DENIED) {
680                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
681                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
682         } else if (rv != NET_ERR_NONE) {
683                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi state[%d]", rv); //LCOV_EXCL_LINE
684                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
685         }
686
687         switch (wlan_state) {
688         case WIFI_OFF:
689                 *state = CONNECTION_WIFI_STATE_DEACTIVATED;
690                 break;
691         case WIFI_ON:
692         case WIFI_ASSOCIATION:
693         case WIFI_CONFIGURATION:
694                 *state = CONNECTION_WIFI_STATE_DISCONNECTED;
695                 break;
696         case WIFI_CONNECTED:
697         case WIFI_DISCONNECTING:
698                 *state = CONNECTION_WIFI_STATE_CONNECTED;
699                 break;
700         default:
701                 CONNECTION_LOG(CONNECTION_ERROR, "Unknown Wi-Fi state"); //LCOV_EXCL_LINE
702                 return CONNECTION_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
703         }
704
705         return CONNECTION_ERROR_NONE;
706 }
707
708 void _connection_libnet_set_type_changed_cb(libnet_type_changed_cb callback)
709 {
710         libnet.type_changed_cb = callback;
711 }
712
713 void _connection_libnet_set_ip_changed_cb(libnet_ip_changed_cb callback)
714 {
715         libnet.ip_changed_cb = callback;
716 }
717
718 void _connection_libnet_set_proxy_changed_cb(libnet_proxy_changed_cb callback)
719 {
720         libnet.proxy_changed_cb = callback;
721 }
722
723 //LCOV_EXCL_START
724 int _connection_libnet_get_ethernet_state(connection_ethernet_state_e *state)
725 {
726         int rv;
727         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
728         rv = net_get_profile_list(NET_DEVICE_ETHERNET, &ethernet_profiles.profiles, &ethernet_profiles.count);
729         if (rv == NET_ERR_ACCESS_DENIED) {
730                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
731                 return CONNECTION_ERROR_PERMISSION_DENIED;
732         }
733
734         if (ethernet_profiles.count == 0) {
735                 *state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
736                 return CONNECTION_ERROR_NONE;
737         }
738
739         switch (ethernet_profiles.profiles->ProfileState) {
740         case NET_STATE_TYPE_ONLINE:
741         case NET_STATE_TYPE_READY:
742                 *state = CONNECTION_ETHERNET_STATE_CONNECTED;
743                 break;
744         case NET_STATE_TYPE_IDLE:
745         case NET_STATE_TYPE_FAILURE:
746         case NET_STATE_TYPE_ASSOCIATION:
747         case NET_STATE_TYPE_CONFIGURATION:
748         case NET_STATE_TYPE_DISCONNECT:
749                 *state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
750                 break;
751         default:
752                 __libnet_clear_profile_list(&ethernet_profiles);
753                 return CONNECTION_ERROR_OPERATION_FAILED;
754         }
755
756         __libnet_clear_profile_list(&ethernet_profiles);
757
758         return CONNECTION_ERROR_NONE;
759 }
760
761 int _connection_libnet_get_ethernet_cable_state(connection_ethernet_cable_state_e* state)
762 {
763         int rv = 0;
764         int status = 0;
765
766         rv = net_get_ethernet_cable_state(&status);
767         if (rv == NET_ERR_ACCESS_DENIED) {
768                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
769                 return CONNECTION_ERROR_PERMISSION_DENIED;
770         } else if (rv != NET_ERR_NONE) {
771                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
772                 return CONNECTION_ERROR_OPERATION_FAILED;
773         }
774
775         if (status == 1)
776                 *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
777         else
778                 *state = CONNECTION_ETHERNET_CABLE_DETACHED;
779         return CONNECTION_ERROR_NONE;
780 }
781
782 int _connection_libnet_set_ethernet_cable_state_changed_cb(
783                 libnet_ethernet_cable_state_changed_cb callback)
784 {
785         __libnet_set_ethernet_cable_state_changed_cb(callback);
786
787         return CONNECTION_ERROR_NONE;
788 }
789 //LCOV_EXCL_STOP
790
791 int _connection_libnet_get_bluetooth_state(connection_bt_state_e *state)
792 {
793         int i = 0;
794         int rv = 0;
795         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
796         rv = net_get_profile_list(NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles, &bluetooth_profiles.count);
797         if (rv == NET_ERR_ACCESS_DENIED) {
798                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
799                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
800         }
801
802         if (bluetooth_profiles.count == 0) {
803                 *state = CONNECTION_BT_STATE_DEACTIVATED;
804                 return CONNECTION_ERROR_NONE;
805         }
806
807         //LCOV_EXCL_START
808         for (; i < bluetooth_profiles.count; i++) {
809                 switch (bluetooth_profiles.profiles[i].ProfileState) {
810                 case NET_STATE_TYPE_ONLINE:
811                 case NET_STATE_TYPE_READY:
812                         *state = CONNECTION_BT_STATE_CONNECTED;
813                         goto done;
814                 case NET_STATE_TYPE_IDLE:
815                 case NET_STATE_TYPE_FAILURE:
816                 case NET_STATE_TYPE_ASSOCIATION:
817                 case NET_STATE_TYPE_CONFIGURATION:
818                 case NET_STATE_TYPE_DISCONNECT:
819                         *state = CONNECTION_BT_STATE_DISCONNECTED;
820                         break;
821                 default:
822                         __libnet_clear_profile_list(&bluetooth_profiles);
823                         return CONNECTION_ERROR_OPERATION_FAILED;
824                 }
825         }
826         //LCOV_EXCL_STOP
827
828 done:
829         __libnet_clear_profile_list(&bluetooth_profiles);
830
831         return CONNECTION_ERROR_NONE;
832 }
833
834 int _connection_libnet_get_profile_iterator(connection_iterator_type_e type, connection_profile_iterator_h* profile_iter_h)
835 {
836         int count = 0;
837         int rv1, rv2, rv3, rv4;
838         net_profile_info_t *profiles = NULL;
839
840         struct _profile_list_s wifi_profiles = {0, 0, NULL};
841         struct _profile_list_s cellular_profiles = {0, 0, NULL};
842         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
843         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
844
845         __libnet_clear_profile_list(&profile_iterator);
846
847         rv1 = net_get_profile_list(NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
848         if (rv1 == NET_ERR_ACCESS_DENIED) {
849                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
850                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
851         } else if (rv1 != NET_ERR_NO_SERVICE && rv1 != NET_ERR_NONE)
852                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
853
854         CONNECTION_LOG(CONNECTION_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
855
856         rv2 = net_get_profile_list(NET_DEVICE_CELLULAR, &cellular_profiles.profiles, &cellular_profiles.count);
857         if (rv2 == NET_ERR_ACCESS_DENIED) {
858                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
859                 __libnet_clear_profile_list(&wifi_profiles);
860                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
861         } else if (rv2 != NET_ERR_NO_SERVICE && rv2 != NET_ERR_NONE) {
862                 __libnet_clear_profile_list(&wifi_profiles);
863                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
864         }
865         CONNECTION_LOG(CONNECTION_INFO, "Cellular profile count: %d", cellular_profiles.count);
866
867         rv3 = net_get_profile_list(NET_DEVICE_ETHERNET, &ethernet_profiles.profiles, &ethernet_profiles.count);
868         if (rv3 == NET_ERR_ACCESS_DENIED) {
869                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
870                 __libnet_clear_profile_list(&wifi_profiles);
871                 __libnet_clear_profile_list(&cellular_profiles);
872                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
873         } else if (rv3 != NET_ERR_NO_SERVICE && rv3 != NET_ERR_NONE) {
874                 __libnet_clear_profile_list(&wifi_profiles);
875                 __libnet_clear_profile_list(&cellular_profiles);
876                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
877         }
878         CONNECTION_LOG(CONNECTION_INFO, "Ethernet profile count : %d", ethernet_profiles.count);
879
880         rv4 = net_get_profile_list(NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles, &bluetooth_profiles.count);
881         if (rv4 == NET_ERR_ACCESS_DENIED) {
882                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
883                 __libnet_clear_profile_list(&wifi_profiles);
884                 __libnet_clear_profile_list(&cellular_profiles);
885                 __libnet_clear_profile_list(&ethernet_profiles);
886                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
887         } else if (rv4 != NET_ERR_NO_SERVICE && rv4 != NET_ERR_NONE) {
888                 __libnet_clear_profile_list(&wifi_profiles);
889                 __libnet_clear_profile_list(&cellular_profiles);
890                 __libnet_clear_profile_list(&ethernet_profiles);
891                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
892         }
893         CONNECTION_LOG(CONNECTION_INFO, "Bluetooth profile count : %d", bluetooth_profiles.count);
894
895         *profile_iter_h = &profile_iterator;
896
897         switch (type) {
898         case CONNECTION_ITERATOR_TYPE_REGISTERED:
899                 count = wifi_profiles.count + cellular_profiles.count + ethernet_profiles.count + bluetooth_profiles.count;
900                 CONNECTION_LOG(CONNECTION_INFO, "Total profile count : %d", count);
901                 if (count == 0)
902                         return CONNECTION_ERROR_NONE;
903
904                 profiles = g_try_new0(net_profile_info_t, count);
905                 if (profiles == NULL) {
906                         __libnet_clear_profile_list(&wifi_profiles);
907                         __libnet_clear_profile_list(&cellular_profiles);
908                         __libnet_clear_profile_list(&ethernet_profiles);
909                         __libnet_clear_profile_list(&bluetooth_profiles);
910                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
911                 }
912
913                 profile_iterator.profiles = profiles;
914
915                 if (wifi_profiles.count > 0) {
916                         memcpy(profiles, wifi_profiles.profiles,
917                                         sizeof(net_profile_info_t) * wifi_profiles.count);
918                         profiles += wifi_profiles.count;
919                 }
920
921                 if (cellular_profiles.count > 0) {
922                         memcpy(profiles, cellular_profiles.profiles,
923                                         sizeof(net_profile_info_t) * cellular_profiles.count);
924                         profiles += cellular_profiles.count;
925                 }
926
927                 if (ethernet_profiles.count > 0) {
928                         memcpy(profiles, ethernet_profiles.profiles,
929                                         sizeof(net_profile_info_t) * ethernet_profiles.count);
930                         profiles += ethernet_profiles.count;
931                 }
932
933                 if (bluetooth_profiles.count > 0)
934                         memcpy(profiles, bluetooth_profiles.profiles,
935                                         sizeof(net_profile_info_t) * bluetooth_profiles.count);
936
937                 break;
938         case CONNECTION_ITERATOR_TYPE_CONNECTED:
939                 count = __libnet_get_connected_count(&wifi_profiles);
940                 count += __libnet_get_connected_count(&cellular_profiles);
941                 count += __libnet_get_connected_count(&ethernet_profiles);
942                 count += __libnet_get_connected_count(&bluetooth_profiles);
943                 CONNECTION_LOG(CONNECTION_INFO, "Total connected profile count : %d", count);
944                 if (count == 0)
945                         return CONNECTION_ERROR_NONE;
946
947                 profiles = g_try_new0(net_profile_info_t, count);
948                 if (profiles == NULL) {
949                         __libnet_clear_profile_list(&wifi_profiles);
950                         __libnet_clear_profile_list(&cellular_profiles);
951                         __libnet_clear_profile_list(&ethernet_profiles);
952                         __libnet_clear_profile_list(&bluetooth_profiles);
953                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
954                 }
955
956                 profile_iterator.profiles = profiles;
957
958                 if (wifi_profiles.count > 0)
959                         __libnet_copy_connected_profile(&profiles, &wifi_profiles);
960
961                 if (cellular_profiles.count > 0)
962                         __libnet_copy_connected_profile(&profiles, &cellular_profiles);
963
964                 if (ethernet_profiles.count > 0)
965                         __libnet_copy_connected_profile(&profiles, &ethernet_profiles);
966
967                 if (bluetooth_profiles.count > 0)
968                         __libnet_copy_connected_profile(&profiles, &bluetooth_profiles);
969
970                 break;
971         case CONNECTION_ITERATOR_TYPE_DEFAULT:
972                 count = __libnet_get_default_count(&cellular_profiles);
973                 CONNECTION_LOG(CONNECTION_INFO, "Total default profile count : %d", count); //LCOV_EXCL_LINE
974                 if (count == 0)
975                         return CONNECTION_ERROR_NONE;
976
977                 profiles = g_try_new0(net_profile_info_t, count);
978                 if (profiles == NULL) {
979                         __libnet_clear_profile_list(&wifi_profiles);
980                         __libnet_clear_profile_list(&cellular_profiles);
981                         __libnet_clear_profile_list(&ethernet_profiles);
982                         __libnet_clear_profile_list(&bluetooth_profiles);
983                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
984                 }
985
986                 profile_iterator.profiles = profiles;
987
988                 if (cellular_profiles.count > 0)
989                         __libnet_copy_default_profile(&profiles, &cellular_profiles);
990                 break;
991         }
992
993         __libnet_clear_profile_list(&wifi_profiles);
994         __libnet_clear_profile_list(&cellular_profiles);
995         __libnet_clear_profile_list(&ethernet_profiles);
996         __libnet_clear_profile_list(&bluetooth_profiles);
997
998         profile_iterator.count = count;
999
1000         return CONNECTION_ERROR_NONE;
1001 }
1002
1003 int _connection_libnet_get_iterator_next(connection_profile_iterator_h profile_iter_h, connection_profile_h *profile)
1004 {
1005         if (profile_iter_h != &profile_iterator)
1006                 return CONNECTION_ERROR_INVALID_PARAMETER;
1007
1008         if (profile_iterator.count <= profile_iterator.next)
1009                 return CONNECTION_ERROR_ITERATOR_END;
1010
1011         *profile = &profile_iterator.profiles[profile_iterator.next];
1012         profile_iterator.next++;
1013
1014         return CONNECTION_ERROR_NONE;
1015 }
1016
1017 bool _connection_libnet_iterator_has_next(connection_profile_iterator_h profile_iter_h)
1018 {
1019         if (profile_iter_h != &profile_iterator)
1020                 return false;
1021
1022         if (profile_iterator.count <= profile_iterator.next)
1023                 return false;
1024
1025         return true;
1026 }
1027
1028 int _connection_libnet_destroy_iterator(connection_profile_iterator_h profile_iter_h)
1029 {
1030         if (profile_iter_h != &profile_iterator)
1031                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1032
1033         __libnet_clear_profile_list(&profile_iterator);
1034
1035         return CONNECTION_ERROR_NONE;
1036 }
1037
1038 int _connection_libnet_get_current_profile(connection_profile_h *profile)
1039 {
1040         net_profile_info_t active_profile;
1041         int rv;
1042
1043         rv = net_get_active_net_info(&active_profile);
1044         if (rv == NET_ERR_NO_SERVICE)
1045                 return CONNECTION_ERROR_NO_CONNECTION; //LCOV_EXCL_LINE
1046         else if (rv == NET_ERR_ACCESS_DENIED) {
1047                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1048                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1049         } else if (rv != NET_ERR_NONE)
1050                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1051
1052         *profile = g_try_malloc0(sizeof(net_profile_info_t));
1053         if (*profile == NULL)
1054                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
1055
1056         memcpy(*profile, &active_profile, sizeof(net_profile_info_t));
1057         prof_handle_list = g_slist_append(prof_handle_list, *profile);
1058
1059         return CONNECTION_ERROR_NONE;
1060 }
1061
1062 int _connection_libnet_reset_profile(connection_reset_option_e type,
1063                 connection_cellular_subscriber_id_e id, connection_reset_cb callback, void *user_data)
1064 {
1065         int rv;
1066
1067         rv = net_reset_profile(type, id);
1068         if (rv == NET_ERR_ACCESS_DENIED) {
1069                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1070                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1071         } else if (rv != NET_ERR_NONE) {
1072                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to add profile[%d]", rv); //LCOV_EXCL_LINE
1073                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1074         }
1075
1076         __libnet_set_reset_profile_cb(callback, user_data);
1077
1078         return CONNECTION_ERROR_NONE;
1079 }
1080
1081 int _connection_libnet_open_profile(connection_profile_h profile,
1082                 connection_opened_cb callback, void* user_data)
1083 {
1084         int rv;
1085
1086         if (!(_connection_libnet_check_profile_validity(profile))) {
1087                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1088                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1089         }
1090
1091         net_profile_info_t *profile_info = profile;
1092
1093         rv = net_open_connection_with_profile(profile_info->ProfileName);
1094         if (rv == NET_ERR_ACCESS_DENIED) {
1095                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1096                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1097         } else if (rv != NET_ERR_NONE)
1098                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1099
1100         __libnet_set_opened_cb(callback, user_data);
1101
1102         return CONNECTION_ERROR_NONE;
1103 }
1104
1105 int _connection_libnet_get_cellular_service_profile(
1106                 connection_cellular_service_type_e type, connection_profile_h *profile)
1107 {
1108         int i = 0, j = 0;
1109         int rv = NET_ERR_NONE;
1110 #if defined TIZEN_DUALSIM_ENABLE
1111         int default_subscriber_id = 0;
1112         char subscriber_id[3];
1113 #endif
1114
1115         struct _profile_list_s cellular_profiles = { 0, 0, NULL };
1116         net_service_type_t service_type = _connection_profile_convert_to_libnet_cellular_service_type(type);
1117
1118         rv = net_get_profile_list(NET_DEVICE_CELLULAR, &cellular_profiles.profiles, &cellular_profiles.count);
1119         if (rv == NET_ERR_ACCESS_DENIED) {
1120                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1121                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1122         } else if (rv != NET_ERR_NONE) {
1123                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get profile list (%d)", rv); //LCOV_EXCL_LINE
1124                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1125         }
1126
1127 #if defined TIZEN_DUALSIM_ENABLE
1128         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE,
1129                                                 &default_subscriber_id) != 0) {
1130                 CONNECTION_LOG(CONNECTION_ERROR,
1131                                                 "Failed to get VCONF_TELEPHONY_DEFAULT_DATA_SERVICE");
1132                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1133                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1134         }
1135
1136         g_snprintf(subscriber_id, sizeof(subscriber_id), "%d", default_subscriber_id);
1137 #endif
1138
1139         for (i = 0; i < cellular_profiles.count; i++)
1140                 if (cellular_profiles.profiles[i].ProfileInfo.Pdp.ServiceType == service_type)
1141 #if defined TIZEN_DUALSIM_ENABLE
1142                         if (g_str_has_suffix(
1143                                         cellular_profiles.profiles[i].ProfileInfo.Pdp.PSModemPath,
1144                                         subscriber_id) == TRUE)
1145 #endif
1146                                 break;
1147
1148         if (i >= cellular_profiles.count) {
1149                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1150                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1151         }
1152
1153         *profile = g_try_malloc0(sizeof(net_profile_info_t));
1154         if (*profile == NULL) {
1155                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1156                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
1157         }
1158
1159         memcpy(*profile, &cellular_profiles.profiles[i], sizeof(net_profile_info_t));
1160
1161         if (cellular_profiles.profiles[i].ProfileInfo.Pdp.DefaultConn)
1162                 goto done;
1163
1164         //LCOV_EXCL_START
1165         if (type != CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET &&
1166             type != CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET)
1167                 goto done;
1168
1169         for (j = 0; j < cellular_profiles.count; j++) {
1170                 if (i == j)
1171                         continue;
1172
1173                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.ServiceType != service_type)
1174                         continue;
1175
1176                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.DefaultConn) {
1177                         memcpy(*profile, &cellular_profiles.profiles[j], sizeof(net_profile_info_t));
1178                         goto done;
1179                 }
1180         }
1181         //LCOV_EXCL_STOP
1182
1183 done:
1184         __libnet_clear_profile_list(&cellular_profiles);
1185         prof_handle_list = g_slist_append(prof_handle_list, *profile);
1186
1187         return CONNECTION_ERROR_NONE;
1188 }
1189
1190 int _connection_libnet_set_cellular_service_profile_sync(connection_cellular_service_type_e type, connection_profile_h profile)
1191 {
1192         int rv;
1193
1194         if (!(_connection_libnet_check_profile_validity(profile))) {
1195                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1196                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1197         }
1198
1199         net_profile_info_t *profile_info = profile;
1200         connection_cellular_service_type_e service_type;
1201
1202         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1203
1204         if (service_type != type)
1205                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1206
1207         rv = net_set_default_cellular_service_profile(profile_info->ProfileName);
1208         if (rv == NET_ERR_ACCESS_DENIED) {
1209                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1210                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1211         } else if (rv != NET_ERR_NONE)
1212                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1213
1214         return CONNECTION_ERROR_NONE;
1215 }
1216
1217 int _connection_libnet_set_cellular_service_profile_async(connection_cellular_service_type_e type,
1218                         connection_profile_h profile, connection_set_default_cb callback, void* user_data)
1219 {
1220         int rv;
1221
1222         if (!(_connection_libnet_check_profile_validity(profile))) {
1223                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1224                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1225         }
1226
1227         net_profile_info_t *profile_info = profile;
1228         connection_cellular_service_type_e service_type;
1229
1230         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1231
1232         if (service_type != type)
1233                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1234
1235         rv = net_set_default_cellular_service_profile_async(profile_info->ProfileName);
1236         if (rv == NET_ERR_ACCESS_DENIED) {
1237                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1238                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1239         } else if (rv != NET_ERR_NONE)
1240                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1241
1242         __libnet_set_default_cb(callback, user_data);
1243
1244         return CONNECTION_ERROR_NONE;
1245 }
1246
1247 int _connection_libnet_close_profile(connection_profile_h profile, connection_closed_cb callback, void *user_data)
1248 {
1249         int rv;
1250
1251         if (!(_connection_libnet_check_profile_validity(profile))) {
1252                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1253                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1254         }
1255
1256         net_profile_info_t *profile_info = profile;
1257
1258         rv = net_close_connection(profile_info->ProfileName);
1259         if (rv == NET_ERR_ACCESS_DENIED) {
1260                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1261                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1262         } else if (rv != NET_ERR_NONE)
1263                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1264
1265         __libnet_set_closed_cb(callback, user_data);
1266
1267         return CONNECTION_ERROR_NONE;
1268 }
1269
1270 int _connection_libnet_add_route(const char *interface_name, const char *host_address)
1271 {
1272         int rv;
1273         char *endstr = NULL;
1274         int address_family = 0;
1275
1276         address_family = AF_INET;
1277
1278         endstr = strrchr(host_address, '.');
1279         if (endstr == NULL ||
1280                         strcmp(endstr, ".0") == 0 ||
1281                         strncmp(host_address, "0.", 2) == 0 ||
1282                         strstr(host_address, "255") != NULL) {
1283                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1284                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1285         }
1286
1287         rv = net_add_route(host_address, interface_name, address_family);
1288         if (rv == NET_ERR_ACCESS_DENIED) {
1289                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1290                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1291         } else if (rv != NET_ERR_NONE)
1292                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1293
1294         return CONNECTION_ERROR_NONE;
1295 }
1296
1297 int _connection_libnet_remove_route(const char *interface_name, const char *host_address)
1298 {
1299         int rv;
1300         char *endstr = strrchr(host_address, '.');
1301         int address_family = 0;
1302
1303         address_family = AF_INET;
1304
1305         endstr = strrchr(host_address, '.');
1306         if (endstr == NULL ||
1307                 strcmp(endstr, ".0") == 0 ||
1308                 strncmp(host_address, "0.", 2) == 0 ||
1309                 strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1310                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1311                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1312         }
1313
1314         rv = net_remove_route(host_address, interface_name, address_family);
1315         if (rv == NET_ERR_ACCESS_DENIED) {
1316                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1317                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1318         } else if (rv != NET_ERR_NONE)
1319                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1320
1321         return CONNECTION_ERROR_NONE;
1322 }
1323
1324 int _connection_libnet_add_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
1325 {
1326         int rv;
1327         int address_family = 0;
1328
1329         address_family = AF_INET6;
1330
1331         if (strncmp(host_address, "fe80:", 5) == 0 ||
1332                 strncmp(host_address, "ff00:", 5) == 0 ||
1333                 strncmp(host_address, "::", 2) == 0) {
1334                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1335                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1336         }
1337
1338         rv = net_add_route_ipv6(host_address, interface_name, address_family, gateway);
1339         if (rv == NET_ERR_ACCESS_DENIED) {
1340                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1341                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1342         } else if (rv != NET_ERR_NONE)
1343                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1344
1345         return CONNECTION_ERROR_NONE;
1346 }
1347
1348 int _connection_libnet_remove_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
1349 {
1350         int rv;
1351         int address_family = 0;
1352
1353         address_family = AF_INET6;
1354
1355         if (strncmp(host_address, "fe80:", 5) == 0 ||
1356                 strncmp(host_address, "ff00:", 5) == 0 ||
1357                 strncmp(host_address, "::", 2) == 0) {
1358                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1359                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1360         }
1361
1362         rv = net_remove_route_ipv6(host_address, interface_name, address_family, gateway);
1363         if (rv == NET_ERR_ACCESS_DENIED) {
1364                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1365                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1366         } else if (rv != NET_ERR_NONE)
1367                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1368
1369         return CONNECTION_ERROR_NONE;
1370 }
1371
1372 int _connection_libnet_add_route_entry(connection_address_family_e address_family,
1373                 const char *interface_name, const char *host_address, const char *gateway)
1374 {
1375         int rv;
1376         char *endstr = NULL;
1377         int address_family_type = 0;
1378
1379         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1380                 address_family_type = AF_INET;
1381         else
1382                 address_family_type = AF_INET6;
1383
1384         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1385
1386                 endstr = strrchr(host_address, '.');
1387                 if (endstr == NULL ||
1388                                 strcmp(endstr, ".0") == 0 ||
1389                                 strncmp(host_address, "0.", 2) == 0 ||
1390                                 strstr(host_address, "255") != NULL) {
1391                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1392                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1393                 }
1394
1395                 rv = net_add_route_entry(host_address, interface_name, address_family_type, gateway);
1396                 if (rv == NET_ERR_ACCESS_DENIED) {
1397                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1398                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1399                 } else if (rv != NET_ERR_NONE)
1400                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1401
1402         } else {
1403
1404                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1405                         strncmp(host_address, "ff00:", 5) == 0 ||
1406                         strncmp(host_address, "::", 2) == 0) {
1407                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1408                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1409                 }
1410
1411                 rv = net_add_route_ipv6(host_address, interface_name, address_family_type, gateway);
1412                 if (rv == NET_ERR_ACCESS_DENIED) {
1413                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1414                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1415                 } else if (rv != NET_ERR_NONE)
1416                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1417         }
1418
1419         return CONNECTION_ERROR_NONE;
1420 }
1421
1422 int _connection_libnet_remove_route_entry(connection_address_family_e address_family,
1423                 const char *interface_name, const char *host_address, const char *gateway)
1424 {
1425         int rv;
1426         char *endstr = strrchr(host_address, '.');
1427         int address_family_type = 0;
1428
1429         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1430                 address_family_type = AF_INET;
1431         else
1432                 address_family_type = AF_INET6;
1433
1434         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1435                 endstr = strrchr(host_address, '.');
1436                 if (endstr == NULL ||
1437                         strcmp(endstr, ".0") == 0 ||
1438                         strncmp(host_address, "0.", 2) == 0 ||
1439                         strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1440                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1441                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1442                 }
1443
1444                 rv = net_remove_route_entry(host_address, interface_name, address_family_type, gateway);
1445                 if (rv == NET_ERR_ACCESS_DENIED) {
1446                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1447                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1448                 } else if (rv != NET_ERR_NONE)
1449                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1450
1451         } else {
1452
1453                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1454                         strncmp(host_address, "ff00:", 5) == 0 ||
1455                         strncmp(host_address, "::", 2) == 0) {
1456                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1457                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1458                 }
1459
1460                 rv = net_remove_route_ipv6(host_address, interface_name, address_family_type, gateway);
1461                 if (rv == NET_ERR_ACCESS_DENIED) {
1462                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1463                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1464                 } else if (rv != NET_ERR_NONE)
1465                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1466         }
1467
1468         return CONNECTION_ERROR_NONE;
1469 }
1470
1471 void _connection_libnet_add_to_profile_list(connection_profile_h profile)
1472 {
1473         prof_handle_list = g_slist_append(prof_handle_list, profile);
1474 }
1475
1476 void _connection_libnet_remove_from_profile_list(connection_profile_h profile)
1477 {
1478         prof_handle_list = g_slist_remove(prof_handle_list, profile);
1479         g_free(profile);
1480 }
1481
1482 bool _connection_libnet_add_to_profile_cb_list(connection_profile_h profile,
1483                 connection_profile_state_changed_cb callback, void *user_data)
1484 {
1485         net_profile_info_t *profile_info = profile;
1486         char *profile_name = g_strdup(profile_info->ProfileName);
1487
1488         struct _profile_cb_s *profile_cb_info = g_try_malloc0(sizeof(struct _profile_cb_s));
1489         if (profile_cb_info == NULL) {
1490                 g_free(profile_name); //LCOV_EXCL_LINE
1491                 return false; //LCOV_EXCL_LINE
1492         }
1493
1494         profile_cb_info->callback = callback;
1495         profile_cb_info->user_data = user_data;
1496         profile_cb_info->state = _profile_convert_to_cp_state(profile_info->ProfileState);
1497
1498         g_hash_table_replace(profile_cb_table, profile_name, profile_cb_info);
1499
1500         return true;
1501 }
1502
1503 bool _connection_libnet_remove_from_profile_cb_list(connection_profile_h profile)
1504 {
1505         net_profile_info_t *profile_info = profile;
1506
1507         if (g_hash_table_remove(profile_cb_table, profile_info->ProfileName) == TRUE)
1508                 return true;
1509
1510         return false; //LCOV_EXCL_LINE
1511 }
1512
1513 int _connection_libnet_set_statistics(net_device_t device_type, net_statistics_type_e statistics_type)
1514 {
1515         int rv;
1516         rv = net_set_statistics(device_type, statistics_type);
1517         if (rv == NET_ERR_ACCESS_DENIED) {
1518                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1519                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1520         } else if (rv != NET_ERR_NONE)
1521                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1522
1523         return CONNECTION_ERROR_NONE;
1524 }
1525
1526 int _connection_libnet_get_statistics(net_statistics_type_e statistics_type, unsigned long long *size)
1527 {
1528         int rv;
1529         rv = net_get_statistics(NET_DEVICE_WIFI, statistics_type, size);
1530         if (rv == NET_ERR_ACCESS_DENIED) {
1531                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1532                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1533         } else if (rv != NET_ERR_NONE)
1534                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1535
1536         return CONNECTION_ERROR_NONE;
1537 }
1538
1539 int _connection_libnet_set_cellular_subscriber_id(connection_profile_h profile,
1540                 connection_cellular_subscriber_id_e sim_id)
1541 {
1542         char *modem_path = NULL;
1543         net_profile_info_t *profile_info = (net_profile_info_t *)profile;
1544
1545         if (net_get_cellular_modem_object_path(&modem_path, sim_id) != NET_ERR_NONE) {
1546                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get subscriber[%d]", sim_id); //LCOV_EXCL_LINE
1547                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1548         }
1549
1550         if (!modem_path) {
1551                 CONNECTION_LOG(CONNECTION_ERROR, "NULL modem object path"); //LCOV_EXCL_LINE
1552                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1553         }
1554
1555         g_strlcpy(profile_info->ProfileInfo.Pdp.PSModemPath, modem_path,
1556                                 NET_PROFILE_NAME_LEN_MAX);
1557         g_free(modem_path);
1558
1559         return CONNECTION_ERROR_NONE;
1560 }
1561
1562 static void __connection_idle_destroy_cb(gpointer data)
1563 {
1564         if (!data)
1565                 return;
1566
1567         managed_idler_list = g_slist_remove(managed_idler_list, data);
1568         g_free(data);
1569 }
1570
1571 static gboolean __connection_idle_cb(gpointer user_data)
1572 {
1573         struct managed_idle_data *data = (struct managed_idle_data *)user_data;
1574
1575         if (!data)
1576                 return FALSE;
1577
1578         return data->func(data->user_data);
1579 }
1580
1581 guint _connection_callback_add(GSourceFunc func, gpointer user_data)
1582 {
1583         guint id;
1584         struct managed_idle_data *data;
1585         GMainContext *context;
1586         GSource *src;
1587
1588         if (!func)
1589                 return 0;
1590
1591         data = g_try_new0(struct managed_idle_data, 1);
1592         if (!data)
1593                 return 0;
1594
1595         data->func = func;
1596         data->user_data = user_data;
1597
1598         context = g_main_context_get_thread_default();
1599         src = g_idle_source_new();
1600         g_source_set_callback(src, __connection_idle_cb, data,
1601                 __connection_idle_destroy_cb);
1602         id = g_source_attach(src, context);
1603         g_source_unref(src);
1604         if (!id) {
1605                 g_free(data);
1606                 return id;
1607         }
1608
1609         data->id = id;
1610
1611         managed_idler_list = g_slist_append(managed_idler_list, data);
1612
1613         return id;
1614 }
1615
1616 void _connection_callback_cleanup(void)
1617 {
1618         GSList *cur = managed_idler_list;
1619         GSource *src;
1620         struct managed_idle_data *data;
1621
1622         while (cur) {
1623                 //LCOV_EXCL_START
1624                 GSList *next = cur->next;
1625                 data = (struct managed_idle_data *)cur->data;
1626
1627                 src = g_main_context_find_source_by_id(g_main_context_default(), data->id);
1628                 if (src) {
1629                         g_source_destroy(src);
1630                         cur = managed_idler_list;
1631                 } else
1632                         cur = next;
1633                 //LCOV_EXCL_STOP
1634         }
1635
1636         g_slist_free(managed_idler_list);
1637         managed_idler_list = NULL;
1638 }
1639
1640 int _connection_libnet_check_get_privilege()
1641 {
1642         int rv;
1643
1644         rv = net_check_get_privilege();
1645         if (rv == NET_ERR_ACCESS_DENIED) {
1646                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1647                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1648         } else if (rv != NET_ERR_NONE)
1649                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1650
1651         return CONNECTION_ERROR_NONE;
1652 }
1653
1654 int _connection_libnet_check_profile_privilege()
1655 {
1656         int rv;
1657
1658         rv = net_check_profile_privilege();
1659         if (rv == NET_ERR_ACCESS_DENIED) {
1660                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1661                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1662         } else if (rv != NET_ERR_NONE)
1663                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1664
1665         return CONNECTION_ERROR_NONE;
1666 }
1667
1668 bool __libnet_check_feature_supported(const char *key, connection_supported_feature_e feature)
1669 {
1670         if (!connection_is_feature_checked[feature]) {
1671                 if (system_info_get_platform_bool(key, &connection_feature_supported[feature]) < 0) {
1672                         CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature getting from System Info"); //LCOV_EXCL_LINE
1673                         set_last_result(CONNECTION_ERROR_OPERATION_FAILED); //LCOV_EXCL_LINE
1674                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1675                 }
1676                 connection_is_feature_checked[feature] = true;
1677         }
1678         return connection_feature_supported[feature];
1679 }
1680
1681 int _connection_check_feature_supported(const char *feature_name, ...)
1682 {
1683         va_list list;
1684         const char *key;
1685         bool value = false;
1686         bool feature_supported = false;
1687
1688         va_start(list, feature_name);
1689         key = feature_name;
1690         while (1) {
1691                 if (strcmp(key, TELEPHONY_FEATURE) == 0)
1692                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TELEPHONY);
1693                 if (strcmp(key, WIFI_FEATURE) == 0)
1694                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_WIFI);
1695                 if (strcmp(key, TETHERING_BLUETOOTH_FEATURE) == 0)
1696                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TETHERING_BLUETOOTH);
1697                 if (strcmp(key, ETHERNET_FEATURE) == 0)
1698                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_ETHERNET);
1699
1700                 feature_supported |= value;
1701                 key = va_arg(list, const char *);
1702                 if (!key) break;
1703         }
1704         if (!feature_supported) {
1705                 CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature is not supported");
1706                 set_last_result(CONNECTION_ERROR_NOT_SUPPORTED);
1707                 va_end(list);
1708                 return CONNECTION_ERROR_NOT_SUPPORTED;
1709         }
1710
1711         va_end(list);
1712         set_last_result(CONNECTION_ERROR_NONE);
1713         return CONNECTION_ERROR_NONE;
1714 }
1715
1716 int _connection_libnet_start_tcpdump(void)
1717 {
1718         connection_error_e result = CONNECTION_ERROR_NONE;
1719         net_err_t ret = NET_ERR_NONE;
1720
1721         ret = net_start_tcpdump();
1722         result = __libnet_convert_to_cp_error_type(ret);
1723
1724         return result;
1725 }
1726
1727 int _connection_libnet_stop_tcpdump(void)
1728 {
1729         connection_error_e result = CONNECTION_ERROR_NONE;
1730         net_err_t ret = NET_ERR_NONE;
1731
1732         ret = net_stop_tcpdump();
1733         result = __libnet_convert_to_cp_error_type(ret);
1734
1735         return result;
1736 }
1737
1738 int _connection_libnet_get_tcpdump_state(gboolean *tcpdump_state)
1739 {
1740         connection_error_e result = CONNECTION_ERROR_NONE;
1741         net_err_t ret = NET_ERR_NONE;
1742
1743         ret = net_get_tcpdump_state(tcpdump_state);
1744         result = __libnet_convert_to_cp_error_type(ret);
1745
1746         return result;
1747 }