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