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