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