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