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