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