[capi-wifi]: Fixed CAPI's issue
[platform/core/api/wifi.git] / src / libnetwork.c
1 /*
2  * Copyright (c) 2012-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 <ctype.h>
20 #include <glib.h>
21 #include "net_wifi_private.h"
22
23 static __thread bool is_init = false;
24 static __thread GSList *ap_handle_list = NULL;
25
26 struct _wifi_cb_s {
27         wifi_device_state_changed_cb device_state_cb;
28         void *device_state_user_data;
29         wifi_scan_finished_cb bg_scan_cb;
30         void *bg_scan_user_data;
31         wifi_scan_finished_cb scan_request_cb;
32         void *scan_request_user_data;
33         wifi_scan_finished_cb scan_hidden_ap_cb;
34         void *scan_hidden_ap_user_data;
35         wifi_connection_state_changed_cb connection_state_cb;
36         void *connection_state_user_data;
37         wifi_activated_cb activated_cb;
38         void *activated_user_data;
39         wifi_deactivated_cb deactivated_cb;
40         void *deactivated_user_data;
41         wifi_connected_cb connected_cb;
42         void *connected_user_data;
43         wifi_disconnected_cb disconnected_cb;
44         void *disconnected_user_data;
45 };
46
47 struct _profile_list_s {
48         int count;
49         net_profile_info_t *profiles;
50 };
51
52 struct _wifi_state_notify {
53         net_profile_info_t *ap_info;
54         wifi_connection_state_e state;
55 };
56
57 struct managed_idle_data {
58         GSourceFunc func;
59         gpointer user_data;
60         guint id;
61 };
62
63 static __thread struct _wifi_cb_s wifi_callbacks = { 0, };
64 static __thread struct _profile_list_s profile_iterator = { 0, NULL };
65 static __thread GSList *managed_idler_list = NULL;
66 static __thread struct _profile_list_s hidden_profile_iterator = {0, NULL};
67
68 bool _wifi_is_init(void)
69 {
70         return is_init;
71 }
72
73 static void __wifi_set_init(bool tag)
74 {
75         is_init = tag;
76 }
77
78 static wifi_error_e __libnet_convert_to_ap_error_type(net_err_t err_type)
79 {
80         switch (err_type) {
81         case NET_ERR_NONE:
82                 return WIFI_ERROR_NONE;
83         case NET_ERR_APP_ALREADY_REGISTERED:
84                 return WIFI_ERROR_INVALID_OPERATION;
85         case NET_ERR_APP_NOT_REGISTERED:
86                 return WIFI_ERROR_INVALID_OPERATION;
87         case NET_ERR_NO_ACTIVE_CONNECTIONS:
88                 return WIFI_ERROR_NO_CONNECTION;
89         case NET_ERR_ACTIVE_CONNECTION_EXISTS:
90                 return WIFI_ERROR_ALREADY_EXISTS;
91         case NET_ERR_CONNECTION_DHCP_FAILED:
92                 return WIFI_ERROR_DHCP_FAILED;
93         case NET_ERR_CONNECTION_INVALID_KEY:
94                 return WIFI_ERROR_INVALID_KEY;
95         case NET_ERR_IN_PROGRESS:
96                 return WIFI_ERROR_NOW_IN_PROGRESS;
97         case NET_ERR_OPERATION_ABORTED:
98                 return WIFI_ERROR_OPERATION_ABORTED;
99         case NET_ERR_TIME_OUT:
100                 return WIFI_ERROR_NO_REPLY;
101         case NET_ERR_ACCESS_DENIED:
102                 return WIFI_ERROR_PERMISSION_DENIED;
103         default:
104                 return WIFI_ERROR_OPERATION_FAILED;
105         }
106 }
107
108 static const char *__libnet_convert_ap_error_type_to_string(wifi_error_e err_type)
109 {
110         switch (err_type) {
111         case WIFI_ERROR_NONE:
112                 return "NONE";
113         case WIFI_ERROR_INVALID_PARAMETER:
114                 return "INVALID_PARAMETER";
115         case WIFI_ERROR_OUT_OF_MEMORY:
116                 return "OUT_OF_MEMORY";
117         case WIFI_ERROR_INVALID_OPERATION:
118                 return "INVALID_OPERATION";
119         case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
120                 return "ADDRESS_FAMILY_NOT_SUPPORTED";
121         case WIFI_ERROR_OPERATION_FAILED:
122                 return "OPERATION_FAILED";
123         case WIFI_ERROR_NO_CONNECTION:
124                 return "NO_CONNECTION";
125         case WIFI_ERROR_NOW_IN_PROGRESS:
126                 return "NOW_IN_PROGRESS";
127         case WIFI_ERROR_ALREADY_EXISTS:
128                 return "ALREADY_EXISTS";
129         case WIFI_ERROR_OPERATION_ABORTED:
130                 return "OPERATION_ABORTED";
131         case WIFI_ERROR_DHCP_FAILED:
132                 return "DHCP_FAILED";
133         case WIFI_ERROR_INVALID_KEY:
134                 return "INVALID_KEY";
135         case WIFI_ERROR_NO_REPLY:
136                 return "NO_REPLY";
137         case WIFI_ERROR_SECURITY_RESTRICTED:
138                 return "SECURITY_RESTRICTED";
139         case WIFI_ERROR_PERMISSION_DENIED:
140                 return "PERMISSION_DENIED";
141         case WIFI_ERROR_NOT_SUPPORTED:
142                 return "NOT_SUPPROTED";
143         }
144
145         return "UNKNOWN";
146 }
147
148 static const char *__libnet_convert_ap_state_to_string(wifi_connection_state_e state)
149 {
150         switch (state) {
151         case WIFI_CONNECTION_STATE_FAILURE:
152                 return "FAILURE";
153         case WIFI_CONNECTION_STATE_DISCONNECTED:
154                 return "DISCONNECTED";
155         case WIFI_CONNECTION_STATE_ASSOCIATION:
156                 return "ASSOCIATION";
157         case WIFI_CONNECTION_STATE_CONFIGURATION:
158                 return "CONFIGURATION";
159         case WIFI_CONNECTION_STATE_CONNECTED:
160                 return "CONNECTED";
161         default:
162                 return "UNKNOWN";
163         }
164 }
165
166 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
167 {
168         if (profile_list->count > 0)
169                 g_free(profile_list->profiles);
170
171         profile_list->count = 0;
172         profile_list->profiles = NULL;
173 }
174
175 static int __libnet_update_profile_iterator(void)
176 {
177         int rv;
178         struct _profile_list_s wifi_profiles = { 0, NULL };
179
180         __libnet_clear_profile_list(&profile_iterator);
181
182         rv = net_get_profile_list(NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
183         WIFI_LOG(WIFI_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
184
185         if (rv == NET_ERR_ACCESS_DENIED) {
186                 WIFI_LOG(WIFI_ERROR, "Access denied");
187                 return WIFI_ERROR_PERMISSION_DENIED;
188         }
189
190         if (wifi_profiles.count == 0)
191                 return WIFI_ERROR_NONE;
192
193         profile_iterator.count = wifi_profiles.count;
194         profile_iterator.profiles = wifi_profiles.profiles;
195
196         return WIFI_ERROR_NONE;
197 }
198
199 static void __libnet_update_hidden_profile_iterator(GSList *ap_list)
200 {
201         int count;
202         GSList *list = ap_list;
203
204         for (count = 0; list; list = list->next)
205                 count++;
206
207         if (count == 0) {
208                 WIFI_LOG(WIFI_INFO, "No hidden AP found\n");
209                 return;
210         }
211
212         hidden_profile_iterator.count = count;
213         hidden_profile_iterator.profiles = g_try_new0(net_profile_info_t, count);
214
215         list = ap_list;
216         for (count = 0; list; list = list->next) {
217                 net_wifi_connection_info_t *ap = list->data;
218                 net_profile_info_t *profile = &hidden_profile_iterator.profiles[count];
219
220                 g_strlcpy(profile->ProfileInfo.Wlan.essid, ap->essid, NET_WLAN_ESSID_LEN+1);
221                 profile->ProfileInfo.Wlan.security_info.sec_mode = ap->security_info.sec_mode;
222                 count++;
223         }
224
225         WIFI_LOG(WIFI_INFO, "Hidden AP count : %d\n", count);
226 }
227
228 static void __libnet_convert_profile_info_to_wifi_info(net_wifi_connection_info_t *wifi_info,
229                                                                 net_profile_info_t *ap_info)
230 {
231         g_strlcpy(wifi_info->essid, ap_info->ProfileInfo.Wlan.essid, NET_WLAN_ESSID_LEN+1);
232         wifi_info->wlan_mode = ap_info->ProfileInfo.Wlan.wlan_mode;
233         memcpy(&wifi_info->security_info, &ap_info->ProfileInfo.Wlan.security_info, sizeof(wlan_security_info_t));
234 }
235
236 static int __libnet_connect_with_wifi_info(net_profile_info_t *ap_info)
237 {
238         int rv;
239         net_wifi_connection_info_t wifi_info;
240         memset(&wifi_info, 0, sizeof(net_wifi_connection_info_t));
241
242         __libnet_convert_profile_info_to_wifi_info(&wifi_info, ap_info);
243
244         rv = net_open_connection_with_wifi_info(&wifi_info);
245         if (rv == NET_ERR_ACCESS_DENIED) {
246                 WIFI_LOG(WIFI_ERROR, "Access denied");
247                 return WIFI_ERROR_PERMISSION_DENIED;
248         } else if (rv != NET_ERR_NONE)
249                 return WIFI_ERROR_OPERATION_FAILED;
250
251         return WIFI_ERROR_NONE;
252 }
253
254 static void __libnet_state_changed_cb(char *profile_name, net_profile_info_t *profile_info,
255                                                         wifi_connection_state_e state)
256 {
257         if (profile_name == NULL)
258                 return;
259
260         if (profile_info == NULL) {
261                 WIFI_LOG(WIFI_ERROR, "Error!! Profile info not found! : %s\n", profile_name);
262                 return;
263         }
264
265         ap_handle_list = g_slist_append(ap_handle_list, (wifi_ap_h)profile_info);
266
267         if (wifi_callbacks.connection_state_cb)
268                 wifi_callbacks.connection_state_cb(state, (wifi_ap_h)profile_info,
269                                         wifi_callbacks.connection_state_user_data);
270
271         ap_handle_list = g_slist_remove(ap_handle_list, (wifi_ap_h)profile_info);
272 }
273
274 static void __libnet_set_activated_cb(wifi_activated_cb user_cb, void *user_data)
275 {
276         if (user_cb) {
277                 wifi_callbacks.activated_cb = user_cb;
278                 wifi_callbacks.activated_user_data = user_data;
279         }
280 }
281
282 static void __libnet_activated_cb(wifi_error_e result)
283 {
284         if (wifi_callbacks.activated_cb)
285                 wifi_callbacks.activated_cb(result, wifi_callbacks.activated_user_data);
286
287         wifi_callbacks.activated_cb = NULL;
288         wifi_callbacks.activated_user_data = NULL;
289 }
290
291 static void __libnet_set_deactivated_cb(wifi_disconnected_cb user_cb, void *user_data)
292 {
293         if (user_cb != NULL) {
294                 wifi_callbacks.deactivated_cb = user_cb;
295                 wifi_callbacks.deactivated_user_data = user_data;
296         }
297 }
298
299 static void __libnet_deactivated_cb(wifi_error_e result)
300 {
301         if (wifi_callbacks.deactivated_cb)
302                 wifi_callbacks.deactivated_cb(result, wifi_callbacks.deactivated_user_data);
303
304         wifi_callbacks.deactivated_cb = NULL;
305         wifi_callbacks.deactivated_user_data = NULL;
306 }
307
308 static void __libnet_power_on_off_cb(net_event_info_t *event_cb, bool is_requested)
309 {
310         if (_wifi_is_init() != true) {
311                 WIFI_LOG(WIFI_ERROR, "Application is not registered"
312                                 "If multi-threaded, thread integrity be broken.");
313                 return;
314         }
315
316         if (wifi_callbacks.device_state_cb == NULL &&
317                         wifi_callbacks.activated_cb == NULL &&
318                         wifi_callbacks.deactivated_cb == NULL)
319                 return;
320
321         wifi_error_e error_code = WIFI_ERROR_NONE;
322         wifi_device_state_e state = WIFI_DEVICE_STATE_DEACTIVATED;
323         net_wifi_state_t *wifi_state = (net_wifi_state_t *)event_cb->Data;
324
325         if (event_cb->Error == NET_ERR_NONE &&
326                         event_cb->Datalength == sizeof(net_wifi_state_t)) {
327                 if (*wifi_state == WIFI_ON) {
328                         WIFI_LOG(WIFI_INFO, "Wi-Fi power on");
329                         state = WIFI_DEVICE_STATE_ACTIVATED;
330                 } else if (*wifi_state == WIFI_OFF) {
331                         WIFI_LOG(WIFI_INFO, "Wi-Fi power off");
332                         state = WIFI_DEVICE_STATE_DEACTIVATED;
333                         __libnet_clear_profile_list(&profile_iterator);
334                         __libnet_clear_profile_list(&hidden_profile_iterator);
335                 } else {
336                         WIFI_LOG(WIFI_ERROR, "Error Wi-Fi state %d", *wifi_state);
337                         error_code = WIFI_ERROR_OPERATION_FAILED;
338                         state = WIFI_DEVICE_STATE_DEACTIVATED;
339                 }
340         } else {
341                 WIFI_LOG(WIFI_ERROR, "Wi-Fi power request failed(%d)", event_cb->Error);
342
343                 if (event_cb->Error == NET_ERR_SECURITY_RESTRICTED)
344                         error_code = WIFI_ERROR_SECURITY_RESTRICTED;
345                 else
346                         error_code = WIFI_ERROR_OPERATION_FAILED;
347
348                 state = WIFI_DEVICE_STATE_DEACTIVATED;
349         }
350
351         __libnet_activated_cb(error_code);
352         __libnet_deactivated_cb(error_code);
353
354         if (wifi_callbacks.device_state_cb)
355                 wifi_callbacks.device_state_cb(state, wifi_callbacks.device_state_user_data);
356 }
357
358 static void __libnet_scan_cb(net_event_info_t *event_cb)
359 {
360         wifi_error_e error_code = WIFI_ERROR_NONE;
361
362         if (event_cb->Error != NET_ERR_NONE) {
363                 WIFI_LOG(WIFI_ERROR, "Scan failed!, Error [%d]\n", event_cb->Error);
364                 error_code = WIFI_ERROR_OPERATION_FAILED;
365         }
366
367         if (wifi_callbacks.scan_request_cb) {
368                 wifi_callbacks.scan_request_cb(error_code, wifi_callbacks.scan_request_user_data);
369                 wifi_callbacks.scan_request_cb = NULL;
370                 wifi_callbacks.scan_request_user_data = NULL;
371                 return;
372         }
373
374         if (wifi_callbacks.bg_scan_cb != NULL)
375                 wifi_callbacks.bg_scan_cb(error_code, wifi_callbacks.bg_scan_user_data);
376 }
377
378 static void __libnet_hidden_scan_cb(net_event_info_t *event_cb)
379 {
380         wifi_error_e error_code = WIFI_ERROR_NONE;
381
382         __libnet_clear_profile_list(&hidden_profile_iterator);
383
384         if (event_cb->Error != NET_ERR_NONE) {
385                 WIFI_LOG(WIFI_ERROR, "Hidden scan failed!, Error [%d]\n", event_cb->Error);
386                 error_code = WIFI_ERROR_OPERATION_FAILED;
387         } else if (event_cb->Data) {
388                 GSList *ap_list = event_cb->Data;
389                 __libnet_update_hidden_profile_iterator(ap_list);
390         }
391
392         if (wifi_callbacks.scan_hidden_ap_cb) {
393                 wifi_callbacks.scan_hidden_ap_cb(error_code, wifi_callbacks.scan_hidden_ap_user_data);
394                 wifi_callbacks.scan_hidden_ap_cb = NULL;
395                 wifi_callbacks.scan_hidden_ap_user_data = NULL;
396         }
397 }
398
399 static void __libnet_set_connected_cb(wifi_connected_cb user_cb, void *user_data)
400 {
401         if (user_cb) {
402                 wifi_callbacks.connected_cb = user_cb;
403                 wifi_callbacks.connected_user_data = user_data;
404         }
405 }
406
407 static void __libnet_connected_cb(wifi_error_e result)
408 {
409         if (wifi_callbacks.connected_cb)
410                 wifi_callbacks.connected_cb(result, wifi_callbacks.connected_user_data);
411
412         wifi_callbacks.connected_cb = NULL;
413         wifi_callbacks.connected_user_data = NULL;
414 }
415
416 static void __libnet_set_disconnected_cb(wifi_disconnected_cb user_cb, void *user_data)
417 {
418         if (user_cb) {
419                 wifi_callbacks.disconnected_cb = user_cb;
420                 wifi_callbacks.disconnected_user_data = user_data;
421         }
422 }
423
424 static void __libnet_disconnected_cb(wifi_error_e result)
425 {
426         if (wifi_callbacks.disconnected_cb)
427                 wifi_callbacks.disconnected_cb(result, wifi_callbacks.disconnected_user_data);
428
429         wifi_callbacks.disconnected_cb = NULL;
430         wifi_callbacks.disconnected_user_data = NULL;
431 }
432
433 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
434 {
435         bool is_requested = false;
436         net_profile_info_t *prof_info_p = NULL;
437         net_profile_info_t prof_info;
438         wifi_error_e result = WIFI_ERROR_NONE;
439
440         switch (event_cb->Event) {
441         case NET_EVENT_OPEN_RSP:
442         case NET_EVENT_WIFI_WPS_RSP:
443                 is_requested = true;
444                 /* fall through */
445         case NET_EVENT_OPEN_IND:
446                 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
447                         return;
448
449                 result = __libnet_convert_to_ap_error_type(event_cb->Error);
450                 WIFI_LOG(WIFI_INFO, "Got Open RSP/IND : %s\n",
451                         __libnet_convert_ap_error_type_to_string(result));
452
453                 if (is_requested)
454                         __libnet_connected_cb(result);
455
456                 switch (event_cb->Error) {
457                 case NET_ERR_NONE:
458                         if (event_cb->Datalength == sizeof(net_profile_info_t))
459                                 prof_info_p = (net_profile_info_t *)event_cb->Data;
460
461                         __libnet_state_changed_cb(event_cb->ProfileName, prof_info_p,
462                                                         WIFI_CONNECTION_STATE_CONNECTED);
463                         return;
464                 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
465                         return;
466                 default :
467                         break;
468                 }
469
470                 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
471                         __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
472                                                 WIFI_CONNECTION_STATE_DISCONNECTED);
473                 else
474                         __libnet_state_changed_cb(event_cb->ProfileName, NULL,
475                                                 WIFI_CONNECTION_STATE_DISCONNECTED);
476
477                 break;
478         case NET_EVENT_CLOSE_RSP:
479                 is_requested = true;
480                 /* fall through */
481         case NET_EVENT_CLOSE_IND:
482                 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
483                         return;
484
485                 result = __libnet_convert_to_ap_error_type(event_cb->Error);
486                 WIFI_LOG(WIFI_INFO, "Got Close RSP/IND : %s\n",
487                         __libnet_convert_ap_error_type_to_string(result));
488
489                 if (is_requested)
490                         __libnet_disconnected_cb(result);
491
492                 switch (event_cb->Error) {
493                 case NET_ERR_NONE:
494                         if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
495                                 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
496                                                 WIFI_CONNECTION_STATE_DISCONNECTED);
497                         else
498                                 __libnet_state_changed_cb(event_cb->ProfileName, NULL,
499                                                 WIFI_CONNECTION_STATE_DISCONNECTED);
500                         return;
501                 default:
502                         break;
503                 }
504
505                 break;
506         case NET_EVENT_NET_STATE_IND:
507                 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
508                         return;
509
510                 if (event_cb->Datalength != sizeof(net_state_type_t))
511                         return;
512
513                 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
514                 wifi_connection_state_e ap_state = _wifi_convert_to_ap_state(*profile_state);
515
516                 WIFI_LOG(WIFI_INFO,
517                         "Profile State : %s, profile name : %s\n",
518                         __libnet_convert_ap_state_to_string(ap_state),
519                         event_cb->ProfileName);
520
521                 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
522                         __libnet_state_changed_cb(event_cb->ProfileName, &prof_info, ap_state);
523                 else
524                         __libnet_state_changed_cb(event_cb->ProfileName, NULL, ap_state);
525
526                 break;
527         case NET_EVENT_WIFI_SCAN_RSP:
528         case NET_EVENT_WIFI_SCAN_IND:
529                 WIFI_LOG(WIFI_INFO, "Got Wi-Fi scan IND\n");
530                 __libnet_scan_cb(event_cb);
531                 break;
532         case NET_EVENT_SPECIFIC_SCAN_RSP:
533                 WIFI_LOG(WIFI_INFO, "Got Wi-Fi hidden scan RSP\n");
534                 break;
535         case NET_EVENT_SPECIFIC_SCAN_IND:
536                 WIFI_LOG(WIFI_INFO, "Got Wi-Fi hidden scan IND\n");
537                 __libnet_hidden_scan_cb(event_cb);
538                 break;
539         case NET_EVENT_WIFI_POWER_RSP:
540                 is_requested = true;
541                 /* fall through */
542         case NET_EVENT_WIFI_POWER_IND:
543                 __libnet_power_on_off_cb(event_cb, is_requested);
544                 break;
545         default :
546                 break;
547         }
548 }
549
550 int _wifi_libnet_init(void)
551 {
552         int rv;
553
554         rv = net_register_client_ext((net_event_cb_t)__libnet_evt_cb, NET_DEVICE_WIFI, NULL);
555         if (rv != NET_ERR_NONE)
556                 return rv;
557
558         __wifi_set_init(true);
559
560         return NET_ERR_NONE;
561 }
562
563 bool _wifi_libnet_deinit(void)
564 {
565         if (net_deregister_client_ext(NET_DEVICE_WIFI) != NET_ERR_NONE)
566                 return false;
567
568         __libnet_clear_profile_list(&profile_iterator);
569         __libnet_clear_profile_list(&hidden_profile_iterator);
570         g_slist_free_full(ap_handle_list, g_free);
571         ap_handle_list = NULL;
572         memset(&wifi_callbacks, 0, sizeof(struct _wifi_cb_s));
573
574         __wifi_set_init(false);
575
576         return true;
577 }
578
579 int _wifi_activate(wifi_activated_cb callback, gboolean wifi_picker_test,
580                                         void *user_data)
581 {
582         int rv = NET_ERR_NONE;
583
584         rv = net_wifi_power_on();
585         if (rv == NET_ERR_NONE) {
586                 __libnet_set_activated_cb(callback, user_data);
587                 return WIFI_ERROR_NONE;
588         } else if (rv == NET_ERR_ACCESS_DENIED) {
589                 WIFI_LOG(WIFI_ERROR, "Access denied");
590                 return WIFI_ERROR_PERMISSION_DENIED;
591         } else if (rv == NET_ERR_INVALID_OPERATION)
592                 return WIFI_ERROR_INVALID_OPERATION;
593         else if (rv == NET_ERR_ALREADY_EXISTS)
594                 return WIFI_ERROR_ALREADY_EXISTS;
595         else if (rv == NET_ERR_IN_PROGRESS)
596                 return WIFI_ERROR_NOW_IN_PROGRESS;
597         else if (rv == NET_ERR_SECURITY_RESTRICTED)
598                 return WIFI_ERROR_SECURITY_RESTRICTED;
599
600         return WIFI_ERROR_OPERATION_FAILED;
601 }
602
603 int _wifi_deactivate(wifi_deactivated_cb callback, void *user_data)
604 {
605         int rv = NET_ERR_NONE;
606
607         rv = net_wifi_power_off();
608         if (rv == NET_ERR_NONE) {
609                 __libnet_set_deactivated_cb(callback, user_data);
610                 return WIFI_ERROR_NONE;
611         } else if (rv == NET_ERR_ACCESS_DENIED) {
612                 WIFI_LOG(WIFI_ERROR, "Access denied");
613                 return WIFI_ERROR_PERMISSION_DENIED;
614         } else if (rv == NET_ERR_INVALID_OPERATION)
615                 return WIFI_ERROR_INVALID_OPERATION;
616         else if (rv == NET_ERR_ALREADY_EXISTS)
617                 return WIFI_ERROR_ALREADY_EXISTS;
618         else if (rv == NET_ERR_IN_PROGRESS)
619                 return WIFI_ERROR_NOW_IN_PROGRESS;
620         else if (rv == NET_ERR_SECURITY_RESTRICTED)
621                 return WIFI_ERROR_SECURITY_RESTRICTED;
622
623         return WIFI_ERROR_OPERATION_FAILED;
624 }
625
626 bool _wifi_libnet_check_ap_validity(wifi_ap_h ap_h)
627 {
628         int i;
629         GSList *list = NULL;
630
631         if (ap_h == NULL)
632                 return false;
633
634         for (list = ap_handle_list; list; list = list->next)
635                 if (ap_h == list->data) return true;
636
637         for (i = 0; i < profile_iterator.count; i++)
638                 if (ap_h == &profile_iterator.profiles[i]) return true;
639
640         for (i = 0; i < hidden_profile_iterator.count; i++)
641                 if (ap_h == &hidden_profile_iterator.profiles[i]) return true;
642
643         return false;
644 }
645
646 void _wifi_libnet_add_to_ap_list(wifi_ap_h ap_h)
647 {
648         ap_handle_list = g_slist_append(ap_handle_list, ap_h);
649 }
650
651 void _wifi_libnet_remove_from_ap_list(wifi_ap_h ap_h)
652 {
653         ap_handle_list = g_slist_remove(ap_handle_list, ap_h);
654         g_free(ap_h);
655 }
656
657 bool _wifi_libnet_check_profile_name_validity(const char *profile_name)
658 {
659         const char *profile_prefix = "/net/connman/service/wifi_";
660         int i = 0;
661
662         if (profile_name == NULL ||
663                         g_str_has_prefix(profile_name, profile_prefix) != TRUE) {
664                 WIFI_LOG(WIFI_INFO, "The profile is a hidden or not a regular Wi-Fi profile");
665                 return false;
666         }
667
668         while (profile_name[i] != '\0') {
669                 if (isgraph(profile_name[i]) == 0) {
670                         WIFI_LOG(WIFI_INFO, "Invalid format: %s", profile_name);
671                         return false;
672                 }
673                 i++;
674         }
675
676         return true;
677 }
678
679 int _wifi_libnet_get_wifi_device_state(wifi_device_state_e *device_state)
680 {
681         net_tech_info_t tech_info;
682
683         int rv = NET_ERR_NONE;
684         rv = net_get_technology_properties(NET_DEVICE_WIFI, &tech_info);
685         if (rv == NET_ERR_ACCESS_DENIED) {
686                 WIFI_LOG(WIFI_ERROR, "Access denied");
687                 return WIFI_ERROR_PERMISSION_DENIED;
688         } else if (rv != NET_ERR_NONE) {
689                 WIFI_LOG(WIFI_ERROR, "Failed to get technology properties");
690                 return WIFI_ERROR_OPERATION_FAILED;
691         }
692
693         if (tech_info.powered)
694                 *device_state = WIFI_DEVICE_STATE_ACTIVATED;
695         else
696                 *device_state = WIFI_DEVICE_STATE_DEACTIVATED;
697
698         return WIFI_ERROR_NONE;
699 }
700
701 int _wifi_libnet_get_wifi_state(wifi_connection_state_e* connection_state)
702 {
703         int rv;
704         net_wifi_state_t wlan_state = 0;
705         net_profile_name_t profile_name;
706
707         rv = net_get_wifi_state(&wlan_state, &profile_name);
708         if (rv == NET_ERR_ACCESS_DENIED) {
709                 WIFI_LOG(WIFI_ERROR, "Access denied");
710                 return WIFI_ERROR_PERMISSION_DENIED;
711         } else if (rv != NET_ERR_NONE) {
712                 WIFI_LOG(WIFI_ERROR, "Failed to get Wi-Fi state");
713                 return WIFI_ERROR_OPERATION_FAILED;
714         }
715
716         switch (wlan_state) {
717         case WIFI_OFF:
718         case WIFI_ON:
719                 *connection_state = WIFI_CONNECTION_STATE_DISCONNECTED;
720                 break;
721         case WIFI_CONNECTED:
722                 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
723                 break;
724         case WIFI_DISCONNECTING:
725                 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
726                 break;
727         default :
728                 WIFI_LOG(WIFI_ERROR, "Unknown state");
729                 return WIFI_ERROR_OPERATION_FAILED;
730         }
731
732         return WIFI_ERROR_NONE;
733 }
734
735 int _wifi_libnet_get_intf_name(char** name)
736 {
737         int rv;
738
739         if (profile_iterator.count == 0) {
740                 rv = __libnet_update_profile_iterator();
741                 if (rv == NET_ERR_ACCESS_DENIED) {
742                         WIFI_LOG(WIFI_ERROR, "Access denied");
743                         return WIFI_ERROR_PERMISSION_DENIED;
744                 }
745         }
746
747         if (profile_iterator.count == 0) {
748                 WIFI_LOG(WIFI_ERROR, "There is no AP");
749                 return WIFI_ERROR_OPERATION_FAILED;
750         }
751
752         *name = g_strdup(profile_iterator.profiles->ProfileInfo.Wlan.net_info.DevName);
753         if (*name == NULL)
754                 return WIFI_ERROR_OUT_OF_MEMORY;
755
756         return WIFI_ERROR_NONE;
757 }
758
759 int _wifi_libnet_scan_request(wifi_scan_finished_cb callback, void *user_data)
760 {
761         int rv;
762         rv = net_scan_wifi();
763
764         if (rv == NET_ERR_NONE) {
765                 wifi_callbacks.scan_request_cb = callback;
766                 wifi_callbacks.scan_request_user_data = user_data;
767                 return WIFI_ERROR_NONE;
768         } else if (rv == NET_ERR_ACCESS_DENIED) {
769                 WIFI_LOG(WIFI_ERROR, "Access denied");
770                 return WIFI_ERROR_PERMISSION_DENIED;
771         } else if (rv == NET_ERR_INVALID_OPERATION)
772                 return WIFI_ERROR_INVALID_OPERATION;
773
774         return WIFI_ERROR_OPERATION_FAILED;
775 }
776
777 int _wifi_libnet_scan_hidden_ap(const char *essid,
778                                         wifi_scan_finished_cb callback, void *user_data)
779 {
780         int rv;
781         rv = net_specific_scan_wifi(essid);
782
783         if (rv == NET_ERR_NONE) {
784                 wifi_callbacks.scan_hidden_ap_cb = callback;
785                 wifi_callbacks.scan_hidden_ap_user_data = user_data;
786                 return WIFI_ERROR_NONE;
787         } else if (rv == NET_ERR_INVALID_OPERATION)
788                 return WIFI_ERROR_INVALID_OPERATION;
789
790         return WIFI_ERROR_OPERATION_FAILED;
791 }
792
793 int _wifi_libnet_get_connected_profile(wifi_ap_h *ap)
794 {
795         int i, rv;
796         wifi_ap_h ap_h = NULL;
797
798         rv = __libnet_update_profile_iterator();
799         if (rv == NET_ERR_ACCESS_DENIED) {
800                 WIFI_LOG(WIFI_ERROR, "Access denied");
801                 return WIFI_ERROR_PERMISSION_DENIED;
802         }
803
804         for (i = 0; i < profile_iterator.count; i++) {
805                 if (profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
806                     profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_READY) {
807                         ap_h = (wifi_ap_h)(&profile_iterator.profiles[i]);
808                         break;
809                 }
810         }
811
812         if (ap_h == NULL) {
813                 WIFI_LOG(WIFI_ERROR, "There is no connected AP");
814                 return WIFI_ERROR_NO_CONNECTION;
815         }
816
817         *ap = g_try_malloc0(sizeof(net_profile_info_t));
818         if (*ap == NULL)
819                 return WIFI_ERROR_OUT_OF_MEMORY;
820
821         memcpy(*ap, ap_h, sizeof(net_profile_info_t));
822
823         _wifi_libnet_add_to_ap_list(*ap);
824
825         return WIFI_ERROR_NONE;
826 }
827
828 int _wifi_libnet_foreach_found_aps(wifi_found_ap_cb callback, void *user_data)
829 {
830         int i, rv;
831
832         rv = __libnet_update_profile_iterator();
833         if (rv == NET_ERR_ACCESS_DENIED) {
834                 WIFI_LOG(WIFI_ERROR, "Access denied");
835                 return WIFI_ERROR_PERMISSION_DENIED;
836         }
837
838         if (profile_iterator.count == 0) {
839                 WIFI_LOG(WIFI_WARN, "There is no AP");
840                 return WIFI_ERROR_NONE;
841         }
842
843         for (i = 0; i < profile_iterator.count; i++) {
844                 rv = callback((wifi_ap_h)(&profile_iterator.profiles[i]), user_data);
845                 if (rv == false) break;
846         }
847
848         return WIFI_ERROR_NONE;
849 }
850
851 int _wifi_libnet_foreach_found_hidden_aps(wifi_found_ap_cb callback, void *user_data)
852 {
853         int i, rv;
854
855         if (hidden_profile_iterator.count == 0) {
856                 WIFI_LOG(WIFI_INFO, "There is no hidden APs.");
857                 return WIFI_ERROR_NONE;
858         }
859
860         for (i =0; i < hidden_profile_iterator.count; i++) {
861                 rv = callback((wifi_ap_h)(&hidden_profile_iterator.profiles[i]), user_data);
862                 if (rv == false)
863                         break;
864         }
865
866         return WIFI_ERROR_NONE;
867 }
868
869 int _wifi_libnet_open_profile(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
870 {
871         int rv;
872         bool valid_profile;
873         net_profile_info_t *ap_info = ap_h;
874
875         valid_profile =
876                         _wifi_libnet_check_profile_name_validity(ap_info->ProfileName);
877
878         if (valid_profile == true && ap_info->Favourite)
879                 rv = net_open_connection_with_profile(ap_info->ProfileName);
880         else if (valid_profile == true &&
881                         ap_info->ProfileInfo.Wlan.security_info.sec_mode == WLAN_SEC_MODE_NONE)
882                 rv = net_open_connection_with_profile(ap_info->ProfileName);
883         else
884                 rv = __libnet_connect_with_wifi_info(ap_info);
885
886         rv = __libnet_convert_to_ap_error_type(rv);
887         if (rv == WIFI_ERROR_NONE)
888                 __libnet_set_connected_cb(callback, user_data);
889
890         return rv;
891 }
892
893 int _wifi_libnet_close_profile(wifi_ap_h ap_h, wifi_disconnected_cb callback, void *user_data)
894 {
895         int rv;
896         net_profile_info_t *ap_info = ap_h;
897
898         rv = net_close_connection(ap_info->ProfileName);
899         if (rv == NET_ERR_ACCESS_DENIED) {
900                 WIFI_LOG(WIFI_ERROR, "Access denied");
901                 return WIFI_ERROR_PERMISSION_DENIED;
902         } else if (rv != NET_ERR_NONE)
903                 return WIFI_ERROR_OPERATION_FAILED;
904
905         __libnet_set_disconnected_cb(callback, user_data);
906
907         return WIFI_ERROR_NONE;
908 }
909
910 int _wifi_libnet_connect_with_wps_pbc(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
911 {
912         int rv;
913         net_profile_info_t *ap_info = ap_h;
914         net_wifi_wps_info_t wps_info;
915         memset(&wps_info, 0, sizeof(net_wifi_wps_info_t));
916
917         wps_info.type = WIFI_WPS_PBC;
918
919         rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
920         if (rv == NET_ERR_ACCESS_DENIED) {
921                 WIFI_LOG(WIFI_ERROR, "Access denied");
922                 return WIFI_ERROR_PERMISSION_DENIED;
923         } else if (rv != NET_ERR_NONE)
924                 return WIFI_ERROR_OPERATION_FAILED;
925
926         __libnet_set_connected_cb(callback, user_data);
927
928         return WIFI_ERROR_NONE;
929 }
930
931 int _wifi_libnet_connect_with_wps_pin(wifi_ap_h ap_h, const char *pin,
932                 wifi_connected_cb callback, void *user_data)
933 {
934         int rv;
935         net_profile_info_t *ap_info = ap_h;
936         net_wifi_wps_info_t wps_info;
937
938         if (ap_info == NULL) {
939                 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
940                 return WIFI_ERROR_INVALID_PARAMETER;
941         }
942
943         wps_info.type = WIFI_WPS_PIN;
944         g_strlcpy(wps_info.pin, pin, NET_WLAN_MAX_WPSPIN_LEN + 1);
945
946         rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
947         if (rv == NET_ERR_ACCESS_DENIED) {
948                 WIFI_LOG(WIFI_ERROR, "Access denied");
949                 return WIFI_ERROR_PERMISSION_DENIED;
950         } else if (rv != NET_ERR_NONE)
951                 return WIFI_ERROR_OPERATION_FAILED;
952
953         __libnet_set_connected_cb(callback, user_data);
954
955         return WIFI_ERROR_NONE;
956 }
957
958 int _wifi_libnet_forget_ap(wifi_ap_h ap)
959 {
960         int rv = 0;
961         net_profile_info_t *ap_info = ap;
962
963         if (ap_info == NULL) {
964                 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
965                 return WIFI_ERROR_INVALID_PARAMETER;
966         }
967
968         rv = net_delete_profile(ap_info->ProfileName);
969         if (rv == NET_ERR_ACCESS_DENIED) {
970                 WIFI_LOG(WIFI_ERROR, "Access denied");
971                 return WIFI_ERROR_PERMISSION_DENIED;
972         } else if (rv != NET_ERR_NONE)
973                 return WIFI_ERROR_OPERATION_FAILED;
974
975         ap_info->Favourite = (char)FALSE;
976
977         return WIFI_ERROR_NONE;
978 }
979
980 int _wifi_set_power_on_off_cb(wifi_device_state_changed_cb callback, void *user_data)
981 {
982         if (wifi_callbacks.device_state_cb != NULL)
983                 return WIFI_ERROR_INVALID_OPERATION;
984
985         wifi_callbacks.device_state_cb = callback;
986         wifi_callbacks.device_state_user_data = user_data;
987
988         WIFI_LOG(WIFI_INFO, "Wi-Fi registered device state changed callback");
989
990         return WIFI_ERROR_NONE;
991 }
992
993 int _wifi_unset_power_on_off_cb(void)
994 {
995         if (wifi_callbacks.device_state_cb == NULL)
996                 return WIFI_ERROR_INVALID_OPERATION;
997
998         wifi_callbacks.device_state_cb = NULL;
999         wifi_callbacks.device_state_user_data = NULL;
1000
1001         return WIFI_ERROR_NONE;
1002 }
1003
1004 int _wifi_set_background_scan_cb(wifi_scan_finished_cb callback, void *user_data)
1005 {
1006         if (wifi_callbacks.bg_scan_cb != NULL)
1007                 return WIFI_ERROR_INVALID_OPERATION;
1008
1009         wifi_callbacks.bg_scan_cb = callback;
1010         wifi_callbacks.bg_scan_user_data = user_data;
1011
1012         return WIFI_ERROR_NONE;
1013 }
1014
1015 int _wifi_unset_background_scan_cb(void)
1016 {
1017         if (wifi_callbacks.bg_scan_cb == NULL)
1018                 return WIFI_ERROR_INVALID_OPERATION;
1019
1020         wifi_callbacks.bg_scan_cb = NULL;
1021         wifi_callbacks.bg_scan_user_data = NULL;
1022
1023         return WIFI_ERROR_NONE;
1024 }
1025
1026 int _wifi_set_connection_state_cb(wifi_connection_state_changed_cb callback, void *user_data)
1027 {
1028         if (wifi_callbacks.connection_state_cb != NULL)
1029                 return WIFI_ERROR_INVALID_OPERATION;
1030
1031         wifi_callbacks.connection_state_cb = callback;
1032         wifi_callbacks.connection_state_user_data = user_data;
1033
1034         return WIFI_ERROR_NONE;
1035 }
1036
1037 int _wifi_unset_connection_state_cb()
1038 {
1039         if (wifi_callbacks.connection_state_cb == NULL)
1040                 return WIFI_ERROR_INVALID_OPERATION;
1041
1042         wifi_callbacks.connection_state_cb = NULL;
1043         wifi_callbacks.connection_state_user_data = NULL;
1044
1045         return WIFI_ERROR_NONE;
1046 }
1047
1048 int _wifi_update_ap_info(net_profile_info_t *ap_info)
1049 {
1050         int rv = NET_ERR_NONE;
1051         rv = net_modify_profile(ap_info->ProfileName, ap_info);
1052
1053         if (rv == NET_ERR_ACCESS_DENIED) {
1054                 WIFI_LOG(WIFI_ERROR, "Access denied");
1055                 return WIFI_ERROR_PERMISSION_DENIED;
1056         } else if (rv != NET_ERR_NONE)
1057                 return WIFI_ERROR_OPERATION_FAILED;
1058
1059         return WIFI_ERROR_NONE;
1060 }
1061
1062 void _wifi_callback_cleanup(void)
1063 {
1064         GSList *cur = managed_idler_list;
1065         GSource *src;
1066         struct managed_idle_data *data;
1067
1068         while (cur) {
1069                 GSList *next = cur->next;
1070                 data = (struct managed_idle_data *)cur->data;
1071
1072                 src = g_main_context_find_source_by_id(g_main_context_default(), data->id);
1073                 if (src) {
1074                         g_source_destroy(src);
1075                         cur = managed_idler_list;
1076                 } else
1077                         cur = next;
1078         }
1079
1080         g_slist_free(managed_idler_list);
1081         managed_idler_list = NULL;
1082 }