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