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