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