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