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