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