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