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