2 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include "net_wifi_private.h"
24 static __thread bool is_init = false;
25 static __thread GSList *ap_handle_list = NULL;
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;
48 struct _profile_list_s {
50 net_profile_info_t *profiles;
53 struct _wifi_state_notify {
54 net_profile_info_t *ap_info;
55 wifi_connection_state_e state;
58 struct managed_idle_data {
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 bool is_feature_checked = false;
69 static __thread bool feature_supported = false;
70 static __thread GSList *managed_idler_list = NULL;
72 bool _wifi_is_init(void)
77 static void __wifi_set_init(bool tag)
82 static wifi_error_e __libnet_convert_to_ap_error_type(net_err_t err_type)
86 return WIFI_ERROR_NONE;
87 case NET_ERR_APP_ALREADY_REGISTERED:
88 return WIFI_ERROR_INVALID_OPERATION;
89 case NET_ERR_APP_NOT_REGISTERED:
90 return WIFI_ERROR_INVALID_OPERATION;
91 case NET_ERR_NO_ACTIVE_CONNECTIONS:
92 return WIFI_ERROR_NO_CONNECTION;
93 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
94 return WIFI_ERROR_ALREADY_EXISTS;
95 case NET_ERR_CONNECTION_DHCP_FAILED:
96 return WIFI_ERROR_DHCP_FAILED;
97 case NET_ERR_CONNECTION_INVALID_KEY:
98 return WIFI_ERROR_INVALID_KEY;
99 case NET_ERR_IN_PROGRESS:
100 return WIFI_ERROR_NOW_IN_PROGRESS;
101 case NET_ERR_OPERATION_ABORTED:
102 return WIFI_ERROR_OPERATION_ABORTED;
103 case NET_ERR_TIME_OUT:
104 return WIFI_ERROR_NO_REPLY;
105 case NET_ERR_ACCESS_DENIED:
106 return WIFI_ERROR_PERMISSION_DENIED;
108 return WIFI_ERROR_OPERATION_FAILED;
112 static const char *__libnet_convert_ap_error_type_to_string(wifi_error_e err_type)
115 case WIFI_ERROR_NONE:
117 case WIFI_ERROR_INVALID_PARAMETER:
118 return "INVALID_PARAMETER";
119 case WIFI_ERROR_OUT_OF_MEMORY:
120 return "OUT_OF_MEMORY";
121 case WIFI_ERROR_INVALID_OPERATION:
122 return "INVALID_OPERATION";
123 case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
124 return "ADDRESS_FAMILY_NOT_SUPPORTED";
125 case WIFI_ERROR_OPERATION_FAILED:
126 return "OPERATION_FAILED";
127 case WIFI_ERROR_NO_CONNECTION:
128 return "NO_CONNECTION";
129 case WIFI_ERROR_NOW_IN_PROGRESS:
130 return "NOW_IN_PROGRESS";
131 case WIFI_ERROR_ALREADY_EXISTS:
132 return "ALREADY_EXISTS";
133 case WIFI_ERROR_OPERATION_ABORTED:
134 return "OPERATION_ABORTED";
135 case WIFI_ERROR_DHCP_FAILED:
136 return "DHCP_FAILED";
137 case WIFI_ERROR_INVALID_KEY:
138 return "INVALID_KEY";
139 case WIFI_ERROR_NO_REPLY:
141 case WIFI_ERROR_SECURITY_RESTRICTED:
142 return "SECURITY_RESTRICTED";
143 case WIFI_ERROR_PERMISSION_DENIED:
144 return "PERMISSION_DENIED";
145 case WIFI_ERROR_NOT_SUPPORTED:
146 return "NOT_SUPPROTED";
152 static const char *__libnet_convert_ap_state_to_string(wifi_connection_state_e state)
155 case WIFI_CONNECTION_STATE_FAILURE:
157 case WIFI_CONNECTION_STATE_DISCONNECTED:
158 return "DISCONNECTED";
159 case WIFI_CONNECTION_STATE_ASSOCIATION:
160 return "ASSOCIATION";
161 case WIFI_CONNECTION_STATE_CONFIGURATION:
162 return "CONFIGURATION";
163 case WIFI_CONNECTION_STATE_CONNECTED:
170 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
172 if (profile_list->count > 0)
173 g_free(profile_list->profiles);
175 profile_list->count = 0;
176 profile_list->profiles = NULL;
179 static int __libnet_update_profile_iterator(void)
182 struct _profile_list_s wifi_profiles = { 0, NULL };
184 __libnet_clear_profile_list(&profile_iterator);
186 rv = net_get_profile_list(NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
187 WIFI_LOG(WIFI_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
189 if (rv == NET_ERR_ACCESS_DENIED) {
190 WIFI_LOG(WIFI_ERROR, "Access denied");
191 return WIFI_ERROR_PERMISSION_DENIED;
194 if (wifi_profiles.count == 0)
195 return WIFI_ERROR_NONE;
197 profile_iterator.count = wifi_profiles.count;
198 profile_iterator.profiles = wifi_profiles.profiles;
200 return WIFI_ERROR_NONE;
203 static void __libnet_update_specific_profile_iterator(GSList *ap_list)
206 GSList *list = ap_list;
208 for (count = 0; list; list = list->next) {
213 WIFI_LOG(WIFI_INFO, "No hidden AP found\n");
217 specific_profile_iterator.count = count;
218 specific_profile_iterator.profiles = g_try_new0(net_profile_info_t, count);
221 for (count = 0; list; list = list->next) {
222 struct ssid_scan_bss_info_t *ap = (struct ssid_scan_bss_info_t *)list->data;
223 net_profile_info_t *profile = &specific_profile_iterator.profiles[count];
225 g_strlcpy(profile->ProfileInfo.Wlan.essid, ap->ssid, NET_WLAN_ESSID_LEN+1);
226 profile->ProfileInfo.Wlan.security_info.sec_mode = ap->security;
231 WIFI_LOG(WIFI_INFO, "Specific AP count : %d\n", count);
234 static void __libnet_convert_profile_info_to_wifi_info(net_wifi_connection_info_t *wifi_info,
235 net_profile_info_t *ap_info)
237 g_strlcpy(wifi_info->essid, ap_info->ProfileInfo.Wlan.essid, NET_WLAN_ESSID_LEN+1);
238 wifi_info->wlan_mode = ap_info->ProfileInfo.Wlan.wlan_mode;
239 memcpy(&wifi_info->security_info, &ap_info->ProfileInfo.Wlan.security_info, sizeof(wlan_security_info_t));
240 wifi_info->is_hidden = ap_info->ProfileInfo.Wlan.is_hidden;
243 static int __libnet_connect_with_wifi_info(net_profile_info_t *ap_info)
246 net_wifi_connection_info_t wifi_info;
247 memset(&wifi_info, 0, sizeof(net_wifi_connection_info_t));
249 __libnet_convert_profile_info_to_wifi_info(&wifi_info, ap_info);
251 rv = net_open_connection_with_wifi_info(&wifi_info);
252 if (rv == NET_ERR_ACCESS_DENIED) {
253 WIFI_LOG(WIFI_ERROR, "Access denied");
254 return WIFI_ERROR_PERMISSION_DENIED;
255 } else if (rv != NET_ERR_NONE)
256 return WIFI_ERROR_OPERATION_FAILED;
258 return WIFI_ERROR_NONE;
261 static gboolean __wifi_state_changed_cb(gpointer data)
264 struct _wifi_state_notify *notify = (struct _wifi_state_notify *)data;
269 if (notify->ap_info == NULL) {
274 ap_info = (wifi_ap_h)notify->ap_info;
276 _wifi_libnet_add_to_ap_list(ap_info);
278 if (wifi_callbacks.connection_state_cb != NULL)
279 wifi_callbacks.connection_state_cb(notify->state, ap_info,
280 wifi_callbacks.connection_state_user_data);
282 _wifi_libnet_remove_from_ap_list(ap_info);
289 static void __libnet_state_changed_cb(char *profile_name, net_profile_info_t *profile_info,
290 wifi_connection_state_e state)
293 net_profile_info_t *ap_info = NULL;
294 struct _wifi_state_notify *notify = NULL;
296 if (_wifi_is_init() != true) {
297 WIFI_LOG(WIFI_ERROR, "Application is not registered"
298 "If multi-threaded, thread integrity be broken.");
302 if (wifi_callbacks.connection_state_cb == NULL)
305 if (profile_name == NULL)
308 if (profile_info == NULL) {
309 SECURE_WIFI_LOG(WIFI_ERROR, "Failed to find: %s", profile_name);
313 ap_info = g_try_malloc0(sizeof(net_profile_info_t));
314 if (ap_info == NULL) {
315 WIFI_LOG(WIFI_ERROR, "Memory allocation error");
319 memcpy(ap_info, profile_info, sizeof(net_profile_info_t));
321 notify = g_try_new0(struct _wifi_state_notify, 1);
322 if (notify == NULL) {
327 notify->ap_info = ap_info;
328 notify->state = state;
330 id = _wifi_callback_add(__wifi_state_changed_cb, (gpointer)notify);
335 static void __libnet_set_activated_cb(wifi_activated_cb user_cb, void *user_data)
337 if (user_cb != NULL) {
338 wifi_callbacks.activated_cb = user_cb;
339 wifi_callbacks.activated_user_data = user_data;
343 static gboolean __activated_cb_idle(gpointer data)
345 wifi_error_e result = (wifi_error_e)data;
347 if (wifi_callbacks.activated_cb != NULL)
348 wifi_callbacks.activated_cb(result, wifi_callbacks.activated_user_data);
350 wifi_callbacks.activated_cb = NULL;
351 wifi_callbacks.activated_user_data = NULL;
356 static void __libnet_set_deactivated_cb(wifi_deactivated_cb user_cb, void *user_data)
358 if (user_cb != NULL) {
359 wifi_callbacks.deactivated_cb = user_cb;
360 wifi_callbacks.deactivated_user_data = user_data;
364 static gboolean __deactivated_cb_idle(gpointer data)
366 wifi_error_e result = (wifi_error_e)data;
368 if (wifi_callbacks.deactivated_cb != NULL)
369 wifi_callbacks.deactivated_cb(result, wifi_callbacks.deactivated_user_data);
371 wifi_callbacks.deactivated_cb = NULL;
372 wifi_callbacks.deactivated_user_data = NULL;
377 static gboolean __device_state_cb_idle(gpointer data)
379 wifi_device_state_e state = (wifi_device_state_e)data;
381 if (wifi_callbacks.device_state_cb != NULL)
382 wifi_callbacks.device_state_cb(state, wifi_callbacks.device_state_user_data);
387 static void __libnet_power_on_off_cb(net_event_info_t *event_cb, bool is_requested)
389 if (_wifi_is_init() != true) {
390 WIFI_LOG(WIFI_ERROR, "Application is not registered"
391 "If multi-threaded, thread integrity be broken.");
395 if (wifi_callbacks.device_state_cb == NULL &&
396 wifi_callbacks.activated_cb == NULL &&
397 wifi_callbacks.deactivated_cb == NULL)
400 wifi_error_e error_code = WIFI_ERROR_NONE;
401 wifi_device_state_e state = WIFI_DEVICE_STATE_DEACTIVATED;
402 net_wifi_state_t *wifi_state = (net_wifi_state_t *)event_cb->Data;
404 if (event_cb->Error == NET_ERR_NONE &&
405 event_cb->Datalength == sizeof(net_wifi_state_t)) {
406 if (*wifi_state == WIFI_ON) {
407 WIFI_LOG(WIFI_INFO, "Wi-Fi power on");
408 state = WIFI_DEVICE_STATE_ACTIVATED;
409 } else if (*wifi_state == WIFI_OFF) {
410 WIFI_LOG(WIFI_INFO, "Wi-Fi power off");
411 state = WIFI_DEVICE_STATE_DEACTIVATED;
412 __libnet_clear_profile_list(&profile_iterator);
414 WIFI_LOG(WIFI_ERROR, "Error Wi-Fi state %d", *wifi_state);
415 error_code = WIFI_ERROR_OPERATION_FAILED;
416 state = WIFI_DEVICE_STATE_DEACTIVATED;
419 WIFI_LOG(WIFI_ERROR, "Wi-Fi power request failed(%d)", event_cb->Error);
421 if (event_cb->Error == NET_ERR_SECURITY_RESTRICTED)
422 error_code = WIFI_ERROR_SECURITY_RESTRICTED;
424 error_code = WIFI_ERROR_OPERATION_FAILED;
426 state = WIFI_DEVICE_STATE_DEACTIVATED;
429 if (wifi_callbacks.activated_cb != NULL)
430 _wifi_callback_add(__activated_cb_idle, (gpointer)error_code);
432 if (wifi_callbacks.deactivated_cb != NULL)
433 _wifi_callback_add(__deactivated_cb_idle, (gpointer)error_code);
435 if (wifi_callbacks.device_state_cb != NULL)
436 _wifi_callback_add(__device_state_cb_idle, (gpointer)state);
439 static gboolean __scan_request_cb_idle(gpointer data)
441 wifi_error_e error_code = (wifi_error_e)data;
443 if (wifi_callbacks.scan_request_cb != NULL)
444 wifi_callbacks.scan_request_cb(error_code, wifi_callbacks.scan_request_user_data);
446 wifi_callbacks.scan_request_cb = NULL;
447 wifi_callbacks.scan_request_user_data = NULL;
452 static void __libnet_set_specific_scan_cb(wifi_scan_finished_cb user_cb, void *user_data)
454 if (user_cb != NULL) {
455 wifi_callbacks.specific_scan_cb = user_cb;
456 wifi_callbacks.specific_scan_user_data = user_data;
460 static gboolean __specific_scan_cb_idle(gpointer data)
462 wifi_error_e error_code = (wifi_error_e)data;
464 if (wifi_callbacks.specific_scan_cb != NULL)
465 wifi_callbacks.specific_scan_cb(error_code, wifi_callbacks.specific_scan_user_data);
467 wifi_callbacks.specific_scan_cb = NULL;
468 wifi_callbacks.specific_scan_user_data = NULL;
473 static gboolean __bgscan_cb_idle(gpointer data)
475 wifi_error_e error_code = (wifi_error_e)data;
477 if (wifi_callbacks.bg_scan_cb != NULL)
478 wifi_callbacks.bg_scan_cb(error_code, wifi_callbacks.bg_scan_user_data);
483 static void __libnet_scan_cb(net_event_info_t *event_cb, bool is_requested)
485 wifi_error_e error_code = WIFI_ERROR_NONE;
487 if (_wifi_is_init() != true) {
488 WIFI_LOG(WIFI_ERROR, "Application is not registered"
489 "If multi-threaded, thread integrity be broken.");
493 if (event_cb->Error != NET_ERR_NONE) {
494 WIFI_LOG(WIFI_ERROR, "Scan failed[%d]", event_cb->Error);
495 error_code = WIFI_ERROR_OPERATION_FAILED;
498 if (wifi_callbacks.scan_request_cb != NULL) {
499 _wifi_callback_add(__scan_request_cb_idle, (gpointer)error_code);
503 if (wifi_callbacks.bg_scan_cb != NULL)
504 _wifi_callback_add(__bgscan_cb_idle, (gpointer)error_code);
507 static void __libnet_specific_scan_cb(net_event_info_t *event_cb)
509 wifi_error_e error_code = WIFI_ERROR_NONE;
511 __libnet_clear_profile_list(&specific_profile_iterator);
513 if (event_cb->Error != NET_ERR_NONE) {
514 WIFI_LOG(WIFI_ERROR, "Specific scan failed!, Error [%d]\n", event_cb->Error);
515 error_code = WIFI_ERROR_OPERATION_FAILED;
516 } else if (event_cb->Data) {
517 GSList *ap_list = (GSList *)event_cb->Data;
518 __libnet_update_specific_profile_iterator(ap_list);
521 if (wifi_callbacks.specific_scan_cb != NULL)
522 _wifi_callback_add(__specific_scan_cb_idle, (gpointer)error_code);
525 static void __libnet_set_connected_cb(wifi_connected_cb user_cb, void *user_data)
527 if (user_cb != NULL) {
528 wifi_callbacks.connected_cb = user_cb;
529 wifi_callbacks.connected_user_data = user_data;
533 static gboolean __connected_cb_idle(gpointer data)
535 wifi_error_e result = (wifi_error_e)data;
537 if (wifi_callbacks.connected_cb != NULL)
538 wifi_callbacks.connected_cb(result, wifi_callbacks.connected_user_data);
540 wifi_callbacks.connected_cb = NULL;
541 wifi_callbacks.connected_user_data = NULL;
546 static void __libnet_connected_cb(wifi_error_e result)
548 if (_wifi_is_init() != true) {
549 WIFI_LOG(WIFI_ERROR, "Application is not registered"
550 "If multi-threaded, thread integrity be broken.");
554 if (wifi_callbacks.connected_cb != NULL)
555 _wifi_callback_add(__connected_cb_idle, (gpointer)result);
558 static void __libnet_set_disconnected_cb(wifi_disconnected_cb user_cb, void *user_data)
560 if (user_cb != NULL) {
561 wifi_callbacks.disconnected_cb = user_cb;
562 wifi_callbacks.disconnected_user_data = user_data;
566 static gboolean __disconnected_cb_idle(gpointer data)
568 wifi_error_e result = (wifi_error_e)data;
570 if (wifi_callbacks.disconnected_cb != NULL)
571 wifi_callbacks.disconnected_cb(result, wifi_callbacks.disconnected_user_data);
573 wifi_callbacks.disconnected_cb = NULL;
574 wifi_callbacks.disconnected_user_data = NULL;
579 static void __libnet_disconnected_cb(wifi_error_e result)
581 if (_wifi_is_init() != true) {
582 WIFI_LOG(WIFI_ERROR, "Application is not registered"
583 "If multi-threaded, thread integrity be broken.");
587 if (wifi_callbacks.disconnected_cb != NULL)
588 _wifi_callback_add(__disconnected_cb_idle, (gpointer)result);
591 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
593 bool is_requested = false;
594 net_profile_info_t *prof_info_p = NULL;
595 net_profile_info_t prof_info;
596 wifi_error_e result = WIFI_ERROR_NONE;
598 bool is_profile_exists = false;
600 switch (event_cb->Event) {
601 case NET_EVENT_OPEN_RSP:
602 case NET_EVENT_WIFI_WPS_RSP:
605 case NET_EVENT_OPEN_IND:
606 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
609 result = __libnet_convert_to_ap_error_type(event_cb->Error);
610 WIFI_LOG(WIFI_INFO, "Connection open error %s",
611 __libnet_convert_ap_error_type_to_string(result));
614 __libnet_connected_cb(result);
616 switch (event_cb->Error) {
618 if (event_cb->Datalength == sizeof(net_profile_info_t))
619 prof_info_p = (net_profile_info_t *)event_cb->Data;
621 __libnet_state_changed_cb(event_cb->ProfileName, prof_info_p,
622 WIFI_CONNECTION_STATE_CONNECTED);
624 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
630 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
631 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
632 WIFI_CONNECTION_STATE_DISCONNECTED);
634 __libnet_state_changed_cb(event_cb->ProfileName, NULL,
635 WIFI_CONNECTION_STATE_DISCONNECTED);
638 case NET_EVENT_CLOSE_RSP:
641 case NET_EVENT_CLOSE_IND:
642 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
645 result = __libnet_convert_to_ap_error_type(event_cb->Error);
646 WIFI_LOG(WIFI_ERROR, "Connection close error %s",
647 __libnet_convert_ap_error_type_to_string(result));
650 __libnet_disconnected_cb(result);
652 switch (event_cb->Error) {
654 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
655 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
656 WIFI_CONNECTION_STATE_DISCONNECTED);
658 __libnet_state_changed_cb(event_cb->ProfileName, NULL,
659 WIFI_CONNECTION_STATE_DISCONNECTED);
666 case NET_EVENT_NET_STATE_IND:
667 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
670 if (event_cb->Datalength != sizeof(net_state_type_t))
673 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
674 wifi_connection_state_e ap_state = _wifi_convert_to_ap_state(*profile_state);
676 WIFI_LOG(WIFI_INFO, "state: %s", __libnet_convert_ap_state_to_string(ap_state));
677 SECURE_WIFI_LOG(WIFI_INFO, "profile name: %s", event_cb->ProfileName);
679 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
680 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info, ap_state);
681 else if (ap_state == WIFI_CONNECTION_STATE_DISCONNECTED) {
682 for (i = 0; i < profile_iterator.count; i++) {
683 if (!g_strcmp0(event_cb->ProfileName,
684 profile_iterator.profiles[i].ProfileName)) {
685 is_profile_exists = true;
690 if (is_profile_exists == true) {
691 profile_iterator.profiles[i].ProfileState = *profile_state;
692 __libnet_state_changed_cb(event_cb->ProfileName,
693 &profile_iterator.profiles[i], ap_state);
695 __libnet_state_changed_cb(event_cb->ProfileName,
698 __libnet_state_changed_cb(event_cb->ProfileName, NULL, ap_state);
701 case NET_EVENT_WIFI_SCAN_RSP:
702 case NET_EVENT_WIFI_SCAN_IND:
703 __libnet_scan_cb(event_cb, is_requested);
705 case NET_EVENT_SPECIFIC_SCAN_RSP:
706 WIFI_LOG(WIFI_INFO, "Got Wi-Fi specific scan RSP\n");
708 case NET_EVENT_SPECIFIC_SCAN_IND:
709 WIFI_LOG(WIFI_INFO, "Got Wi-Fi specific scan IND\n");
710 __libnet_specific_scan_cb(event_cb);
712 case NET_EVENT_WIFI_POWER_RSP:
715 case NET_EVENT_WIFI_POWER_IND:
716 __libnet_power_on_off_cb(event_cb, is_requested);
723 int _wifi_libnet_init(void)
727 rv = net_register_client_ext((net_event_cb_t)__libnet_evt_cb, NET_DEVICE_WIFI, NULL);
728 if (rv != NET_ERR_NONE)
731 __wifi_set_init(true);
736 bool _wifi_libnet_deinit(void)
738 if (net_deregister_client_ext(NET_DEVICE_WIFI) != NET_ERR_NONE)
741 __libnet_clear_profile_list(&profile_iterator);
742 g_slist_free_full(ap_handle_list, g_free);
743 ap_handle_list = NULL;
744 memset(&wifi_callbacks, 0, sizeof(struct _wifi_cb_s));
746 __wifi_set_init(false);
751 int _wifi_activate(wifi_activated_cb callback, gboolean wifi_picker_test,
754 int rv = NET_ERR_NONE;
756 rv = net_wifi_power_on(wifi_picker_test);
757 if (rv == NET_ERR_NONE) {
758 __libnet_set_activated_cb(callback, user_data);
759 return WIFI_ERROR_NONE;
760 } else if (rv == NET_ERR_ACCESS_DENIED) {
761 WIFI_LOG(WIFI_ERROR, "Access denied");
762 return WIFI_ERROR_PERMISSION_DENIED;
763 } else if (rv == NET_ERR_INVALID_OPERATION)
764 return WIFI_ERROR_INVALID_OPERATION;
765 else if (rv == NET_ERR_ALREADY_EXISTS)
766 return WIFI_ERROR_ALREADY_EXISTS;
767 else if (rv == NET_ERR_IN_PROGRESS)
768 return WIFI_ERROR_NOW_IN_PROGRESS;
769 else if (rv == NET_ERR_SECURITY_RESTRICTED)
770 return WIFI_ERROR_SECURITY_RESTRICTED;
772 return WIFI_ERROR_OPERATION_FAILED;
775 int _wifi_deactivate(wifi_deactivated_cb callback, void *user_data)
777 int rv = NET_ERR_NONE;
779 rv = net_wifi_power_off();
780 if (rv == NET_ERR_NONE) {
781 __libnet_set_deactivated_cb(callback, user_data);
782 return WIFI_ERROR_NONE;
783 } else if (rv == NET_ERR_ACCESS_DENIED) {
784 WIFI_LOG(WIFI_ERROR, "Access denied");
785 return WIFI_ERROR_PERMISSION_DENIED;
786 } else if (rv == NET_ERR_INVALID_OPERATION)
787 return WIFI_ERROR_INVALID_OPERATION;
788 else if (rv == NET_ERR_ALREADY_EXISTS)
789 return WIFI_ERROR_ALREADY_EXISTS;
790 else if (rv == NET_ERR_IN_PROGRESS)
791 return WIFI_ERROR_NOW_IN_PROGRESS;
792 else if (rv == NET_ERR_SECURITY_RESTRICTED)
793 return WIFI_ERROR_SECURITY_RESTRICTED;
795 return WIFI_ERROR_OPERATION_FAILED;
798 bool _wifi_libnet_check_ap_validity(wifi_ap_h ap_h)
806 for (list = ap_handle_list; list; list = list->next)
807 if (ap_h == list->data) return true;
809 for (i = 0; i < profile_iterator.count; i++)
810 if (ap_h == &profile_iterator.profiles[i]) return true;
812 for (i = 0; i < specific_profile_iterator.count; i++)
813 if (ap_h == &specific_profile_iterator.profiles[i]) return true;
818 void _wifi_libnet_add_to_ap_list(wifi_ap_h ap_h)
820 ap_handle_list = g_slist_append(ap_handle_list, ap_h);
823 void _wifi_libnet_remove_from_ap_list(wifi_ap_h ap_h)
825 ap_handle_list = g_slist_remove(ap_handle_list, ap_h);
829 bool _wifi_libnet_check_profile_name_validity(const char *profile_name)
831 const char *profile_prefix = "/net/connman/service/wifi_";
834 if (profile_name == NULL ||
835 g_str_has_prefix(profile_name, profile_prefix) != TRUE) {
836 WIFI_LOG(WIFI_INFO, "The profile is a hidden or not a regular Wi-Fi profile");
840 while (profile_name[i] != '\0') {
841 if (isgraph(profile_name[i]) == 0) {
842 WIFI_LOG(WIFI_INFO, "Invalid format: %s", profile_name);
851 int _wifi_libnet_get_wifi_device_state(wifi_device_state_e *device_state)
853 net_tech_info_t tech_info;
855 int rv = NET_ERR_NONE;
856 rv = net_get_technology_properties(NET_DEVICE_WIFI, &tech_info);
857 if (rv == NET_ERR_ACCESS_DENIED) {
858 WIFI_LOG(WIFI_ERROR, "Access denied");
859 return WIFI_ERROR_PERMISSION_DENIED;
860 } else if (rv != NET_ERR_NONE) {
861 WIFI_LOG(WIFI_ERROR, "Failed to get technology properties");
862 return WIFI_ERROR_OPERATION_FAILED;
865 if (tech_info.powered)
866 *device_state = WIFI_DEVICE_STATE_ACTIVATED;
868 *device_state = WIFI_DEVICE_STATE_DEACTIVATED;
870 return WIFI_ERROR_NONE;
873 int _wifi_libnet_get_wifi_state(wifi_connection_state_e* connection_state)
876 net_wifi_state_t wlan_state = 0;
877 net_profile_name_t profile_name;
879 rv = net_get_wifi_state(&wlan_state, &profile_name);
880 if (rv == NET_ERR_ACCESS_DENIED) {
881 WIFI_LOG(WIFI_ERROR, "Access denied");
882 return WIFI_ERROR_PERMISSION_DENIED;
883 } else if (rv != NET_ERR_NONE) {
884 WIFI_LOG(WIFI_ERROR, "Failed to get Wi-Fi state");
885 return WIFI_ERROR_OPERATION_FAILED;
888 switch (wlan_state) {
891 *connection_state = WIFI_CONNECTION_STATE_DISCONNECTED;
893 case WIFI_ASSOCIATION:
894 *connection_state = WIFI_CONNECTION_STATE_ASSOCIATION;
896 case WIFI_CONFIGURATION:
897 *connection_state = WIFI_CONNECTION_STATE_CONFIGURATION;
900 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
902 case WIFI_DISCONNECTING:
903 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
906 WIFI_LOG(WIFI_ERROR, "Unknown state");
907 return WIFI_ERROR_OPERATION_FAILED;
910 return WIFI_ERROR_NONE;
913 int _wifi_libnet_get_intf_name(char** name)
917 if (profile_iterator.count == 0) {
918 rv = __libnet_update_profile_iterator();
919 if (rv == NET_ERR_ACCESS_DENIED) {
920 WIFI_LOG(WIFI_ERROR, "Access denied");
921 return WIFI_ERROR_PERMISSION_DENIED;
925 if (profile_iterator.count == 0) {
926 WIFI_LOG(WIFI_ERROR, "There is no AP");
927 return WIFI_ERROR_OPERATION_FAILED;
930 *name = g_strdup(profile_iterator.profiles->ProfileInfo.Wlan.net_info.DevName);
932 return WIFI_ERROR_OUT_OF_MEMORY;
934 return WIFI_ERROR_NONE;
937 int _wifi_libnet_scan_request(wifi_scan_finished_cb callback, void *user_data)
940 rv = net_scan_wifi();
942 if (rv == NET_ERR_NONE) {
943 wifi_callbacks.scan_request_cb = callback;
944 wifi_callbacks.scan_request_user_data = user_data;
945 return WIFI_ERROR_NONE;
946 } else if (rv == NET_ERR_ACCESS_DENIED) {
947 WIFI_LOG(WIFI_ERROR, "Access denied");
948 return WIFI_ERROR_PERMISSION_DENIED;
949 } else if (rv == NET_ERR_INVALID_OPERATION)
950 return WIFI_ERROR_INVALID_OPERATION;
952 return WIFI_ERROR_OPERATION_FAILED;
955 int _wifi_libnet_scan_specific_ap(const char *essid,
956 wifi_scan_finished_cb callback, void *user_data)
959 rv = net_specific_scan_wifi(essid);
961 if (rv == NET_ERR_NONE) {
962 g_strlcpy(specific_profile_essid, essid, NET_WLAN_ESSID_LEN+1);
963 __libnet_set_specific_scan_cb(callback, user_data);
964 return WIFI_ERROR_NONE;
965 } else if (rv == NET_ERR_ACCESS_DENIED) {
966 WIFI_LOG(WIFI_ERROR, "Access denied");
967 return WIFI_ERROR_PERMISSION_DENIED;
968 } else if (rv == NET_ERR_INVALID_OPERATION)
969 return WIFI_ERROR_INVALID_OPERATION;
971 return WIFI_ERROR_OPERATION_FAILED;
974 int _wifi_libnet_get_connected_profile(wifi_ap_h *ap)
977 wifi_ap_h ap_h = NULL;
979 rv = __libnet_update_profile_iterator();
980 if (rv == NET_ERR_ACCESS_DENIED) {
981 WIFI_LOG(WIFI_ERROR, "Access denied");
982 return WIFI_ERROR_PERMISSION_DENIED;
985 for (i = 0; i < profile_iterator.count; i++) {
986 if (profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
987 profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_READY) {
988 ap_h = (wifi_ap_h)(&profile_iterator.profiles[i]);
994 WIFI_LOG(WIFI_ERROR, "There is no connected AP");
995 return WIFI_ERROR_NO_CONNECTION;
998 *ap = g_try_malloc0(sizeof(net_profile_info_t));
1000 return WIFI_ERROR_OUT_OF_MEMORY;
1002 memcpy(*ap, ap_h, sizeof(net_profile_info_t));
1004 _wifi_libnet_add_to_ap_list(*ap);
1006 return WIFI_ERROR_NONE;
1009 int _wifi_libnet_foreach_found_aps(wifi_found_ap_cb callback, void *user_data)
1013 rv = __libnet_update_profile_iterator();
1014 if (rv == NET_ERR_ACCESS_DENIED) {
1015 WIFI_LOG(WIFI_ERROR, "Access denied");
1016 return WIFI_ERROR_PERMISSION_DENIED;
1019 if (profile_iterator.count == 0) {
1020 WIFI_LOG(WIFI_WARN, "There is no AP");
1021 return WIFI_ERROR_NONE;
1024 for (i = 0; i < profile_iterator.count; i++) {
1025 if (profile_iterator.profiles[i].ProfileInfo.Wlan.is_hidden == TRUE)
1028 rv = callback((wifi_ap_h)(&profile_iterator.profiles[i]), user_data);
1029 if (rv == false) break;
1032 return WIFI_ERROR_NONE;
1035 int _wifi_libnet_foreach_found_specific_aps(wifi_found_ap_cb callback, void *user_data)
1039 if (specific_profile_iterator.count == 0) {
1040 WIFI_LOG(WIFI_WARN, "There is no specific APs");
1042 rv = __libnet_update_profile_iterator();
1043 if (rv == NET_ERR_ACCESS_DENIED) {
1044 WIFI_LOG(WIFI_ERROR, "Access denied");
1045 return WIFI_ERROR_PERMISSION_DENIED;
1048 if (profile_iterator.count == 0) {
1049 WIFI_LOG(WIFI_WARN, "There is no APs");
1050 return WIFI_ERROR_NONE;
1053 for (i = 0; i < profile_iterator.count; i++) {
1054 if (!g_strcmp0(specific_profile_essid,
1055 profile_iterator.profiles[i].ProfileInfo.Wlan.essid)) {
1056 rv = callback((wifi_ap_h)(&profile_iterator.profiles[i]), user_data);
1057 if (rv == false) break;
1060 return WIFI_ERROR_NONE;
1063 for (i = 0; i < specific_profile_iterator.count; i++) {
1064 rv = callback((wifi_ap_h)(&specific_profile_iterator.profiles[i]), user_data);
1065 if (rv == false) break;
1068 return WIFI_ERROR_NONE;
1071 int _wifi_libnet_open_profile(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
1075 net_profile_info_t *ap_info = ap_h;
1078 _wifi_libnet_check_profile_name_validity(ap_info->ProfileName);
1080 if (valid_profile == true && ap_info->Favourite)
1081 rv = net_open_connection_with_profile(ap_info->ProfileName);
1082 else if (valid_profile == true &&
1083 ap_info->ProfileInfo.Wlan.is_hidden != TRUE &&
1084 ap_info->ProfileInfo.Wlan.security_info.sec_mode ==
1086 rv = net_open_connection_with_profile(ap_info->ProfileName);
1088 rv = __libnet_connect_with_wifi_info(ap_info);
1090 rv = __libnet_convert_to_ap_error_type(rv);
1091 if (rv == WIFI_ERROR_NONE)
1092 __libnet_set_connected_cb(callback, user_data);
1097 int _wifi_libnet_close_profile(wifi_ap_h ap_h, wifi_disconnected_cb callback, void *user_data)
1100 net_profile_info_t *ap_info = ap_h;
1102 rv = net_close_connection(ap_info->ProfileName);
1103 if (rv == NET_ERR_ACCESS_DENIED) {
1104 WIFI_LOG(WIFI_ERROR, "Access denied");
1105 return WIFI_ERROR_PERMISSION_DENIED;
1106 } else if (rv != NET_ERR_NONE)
1107 return WIFI_ERROR_OPERATION_FAILED;
1109 __libnet_set_disconnected_cb(callback, user_data);
1111 return WIFI_ERROR_NONE;
1114 int _wifi_libnet_connect_with_wps_pbc(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
1117 net_profile_info_t *ap_info = ap_h;
1118 net_wifi_wps_info_t wps_info;
1119 memset(&wps_info, 0, sizeof(net_wifi_wps_info_t));
1121 wps_info.type = WIFI_WPS_PBC;
1123 rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
1124 if (rv == NET_ERR_ACCESS_DENIED) {
1125 WIFI_LOG(WIFI_ERROR, "Access denied");
1126 return WIFI_ERROR_PERMISSION_DENIED;
1127 } else if (rv != NET_ERR_NONE)
1128 return WIFI_ERROR_OPERATION_FAILED;
1130 __libnet_set_connected_cb(callback, user_data);
1132 return WIFI_ERROR_NONE;
1135 int _wifi_libnet_connect_with_wps_pin(wifi_ap_h ap_h, const char *pin,
1136 wifi_connected_cb callback, void *user_data)
1139 net_profile_info_t *ap_info = ap_h;
1140 net_wifi_wps_info_t wps_info;
1142 if (ap_info == NULL) {
1143 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
1144 return WIFI_ERROR_INVALID_PARAMETER;
1147 wps_info.type = WIFI_WPS_PIN;
1148 g_strlcpy(wps_info.pin, pin, NET_WLAN_MAX_WPSPIN_LEN + 1);
1150 rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
1151 if (rv == NET_ERR_ACCESS_DENIED) {
1152 WIFI_LOG(WIFI_ERROR, "Access denied");
1153 return WIFI_ERROR_PERMISSION_DENIED;
1154 } else if (rv != NET_ERR_NONE)
1155 return WIFI_ERROR_OPERATION_FAILED;
1157 __libnet_set_connected_cb(callback, user_data);
1159 return WIFI_ERROR_NONE;
1162 int _wifi_libnet_forget_ap(wifi_ap_h ap)
1165 net_profile_info_t *ap_info = ap;
1167 if (ap_info == NULL) {
1168 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
1169 return WIFI_ERROR_INVALID_PARAMETER;
1172 rv = net_delete_profile(ap_info->ProfileName);
1173 if (rv == NET_ERR_ACCESS_DENIED) {
1174 WIFI_LOG(WIFI_ERROR, "Access denied");
1175 return WIFI_ERROR_PERMISSION_DENIED;
1176 } else if (rv != NET_ERR_NONE)
1177 return WIFI_ERROR_OPERATION_FAILED;
1179 ap_info->Favourite = (char)FALSE;
1181 return WIFI_ERROR_NONE;
1184 int _wifi_set_power_on_off_cb(wifi_device_state_changed_cb callback, void *user_data)
1186 if (wifi_callbacks.device_state_cb != NULL)
1187 return WIFI_ERROR_INVALID_OPERATION;
1189 wifi_callbacks.device_state_cb = callback;
1190 wifi_callbacks.device_state_user_data = user_data;
1192 WIFI_LOG(WIFI_INFO, "Wi-Fi registered device state changed callback");
1194 return WIFI_ERROR_NONE;
1197 int _wifi_unset_power_on_off_cb(void)
1199 if (wifi_callbacks.device_state_cb == NULL)
1200 return WIFI_ERROR_INVALID_OPERATION;
1202 wifi_callbacks.device_state_cb = NULL;
1203 wifi_callbacks.device_state_user_data = NULL;
1205 return WIFI_ERROR_NONE;
1208 int _wifi_set_background_scan_cb(wifi_scan_finished_cb callback, void *user_data)
1210 if (wifi_callbacks.bg_scan_cb != NULL)
1211 return WIFI_ERROR_INVALID_OPERATION;
1213 wifi_callbacks.bg_scan_cb = callback;
1214 wifi_callbacks.bg_scan_user_data = user_data;
1216 return WIFI_ERROR_NONE;
1219 int _wifi_unset_background_scan_cb(void)
1221 if (wifi_callbacks.bg_scan_cb == NULL)
1222 return WIFI_ERROR_INVALID_OPERATION;
1224 wifi_callbacks.bg_scan_cb = NULL;
1225 wifi_callbacks.bg_scan_user_data = NULL;
1227 return WIFI_ERROR_NONE;
1230 int _wifi_set_connection_state_cb(wifi_connection_state_changed_cb callback, void *user_data)
1232 if (wifi_callbacks.connection_state_cb != NULL)
1233 return WIFI_ERROR_INVALID_OPERATION;
1235 wifi_callbacks.connection_state_cb = callback;
1236 wifi_callbacks.connection_state_user_data = user_data;
1238 return WIFI_ERROR_NONE;
1241 int _wifi_unset_connection_state_cb()
1243 if (wifi_callbacks.connection_state_cb == NULL)
1244 return WIFI_ERROR_INVALID_OPERATION;
1246 wifi_callbacks.connection_state_cb = NULL;
1247 wifi_callbacks.connection_state_user_data = NULL;
1249 return WIFI_ERROR_NONE;
1252 int _wifi_update_ap_info(net_profile_info_t *ap_info)
1254 int rv = NET_ERR_NONE;
1255 rv = net_modify_profile(ap_info->ProfileName, ap_info);
1257 if (rv == NET_ERR_ACCESS_DENIED) {
1258 WIFI_LOG(WIFI_ERROR, "Access denied");
1259 return WIFI_ERROR_PERMISSION_DENIED;
1260 } else if (rv != NET_ERR_NONE)
1261 return WIFI_ERROR_OPERATION_FAILED;
1263 return WIFI_ERROR_NONE;
1266 static void __wifi_idle_destroy_cb(gpointer data)
1271 managed_idler_list = g_slist_remove(managed_idler_list, data);
1275 static gboolean __wifi_idle_cb(gpointer user_data)
1277 struct managed_idle_data *data = (struct managed_idle_data *)user_data;
1282 return data->func(data->user_data);
1285 guint _wifi_callback_add(GSourceFunc func, gpointer user_data)
1288 struct managed_idle_data *data;
1293 data = g_try_new0(struct managed_idle_data, 1);
1298 data->user_data = user_data;
1300 id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __wifi_idle_cb, data,
1301 __wifi_idle_destroy_cb);
1309 managed_idler_list = g_slist_append(managed_idler_list, data);
1314 void _wifi_callback_cleanup(void)
1316 GSList *cur = managed_idler_list;
1318 struct managed_idle_data *data;
1321 GSList *next = cur->next;
1322 data = (struct managed_idle_data *)cur->data;
1324 src = g_main_context_find_source_by_id(g_main_context_default(), data->id);
1326 g_source_destroy(src);
1327 cur = managed_idler_list;
1332 g_slist_free(managed_idler_list);
1333 managed_idler_list = NULL;
1336 int _wifi_check_feature_supported(const char *feature_name)
1338 if(is_feature_checked) {
1339 if(!feature_supported) {
1340 LOGE("%s feature is disabled", feature_name);
1341 return WIFI_ERROR_NOT_SUPPORTED;
1345 if (!system_info_get_platform_bool(feature_name, &feature_supported)) {
1346 is_feature_checked = true;
1347 if (!feature_supported) {
1348 LOGE("%s feature is disabled", feature_name);
1349 return WIFI_ERROR_NOT_SUPPORTED;
1353 LOGE("Error - Feature getting from System Info");
1354 return WIFI_ERROR_OPERATION_FAILED;
1358 return WIFI_ERROR_NONE;