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 GSList *managed_idler_list = NULL;
70 bool _wifi_is_init(void)
75 static void __wifi_set_init(bool tag)
80 static wifi_error_e __libnet_convert_to_ap_error_type(net_err_t err_type)
84 return WIFI_ERROR_NONE;
85 case NET_ERR_APP_ALREADY_REGISTERED:
86 return WIFI_ERROR_INVALID_OPERATION;
87 case NET_ERR_APP_NOT_REGISTERED:
88 return WIFI_ERROR_INVALID_OPERATION;
89 case NET_ERR_NO_ACTIVE_CONNECTIONS:
90 return WIFI_ERROR_NO_CONNECTION;
91 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
92 return WIFI_ERROR_ALREADY_EXISTS;
93 case NET_ERR_CONNECTION_DHCP_FAILED:
94 return WIFI_ERROR_DHCP_FAILED;
95 case NET_ERR_CONNECTION_INVALID_KEY:
96 return WIFI_ERROR_INVALID_KEY;
97 case NET_ERR_IN_PROGRESS:
98 return WIFI_ERROR_NOW_IN_PROGRESS;
99 case NET_ERR_OPERATION_ABORTED:
100 return WIFI_ERROR_OPERATION_ABORTED;
101 case NET_ERR_TIME_OUT:
102 return WIFI_ERROR_NO_REPLY;
103 case NET_ERR_ACCESS_DENIED:
104 return WIFI_ERROR_PERMISSION_DENIED;
106 return WIFI_ERROR_OPERATION_FAILED;
110 static const char *__libnet_convert_ap_error_type_to_string(wifi_error_e err_type)
113 case WIFI_ERROR_NONE:
115 case WIFI_ERROR_INVALID_PARAMETER:
116 return "INVALID_PARAMETER";
117 case WIFI_ERROR_OUT_OF_MEMORY:
118 return "OUT_OF_MEMORY";
119 case WIFI_ERROR_INVALID_OPERATION:
120 return "INVALID_OPERATION";
121 case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
122 return "ADDRESS_FAMILY_NOT_SUPPORTED";
123 case WIFI_ERROR_OPERATION_FAILED:
124 return "OPERATION_FAILED";
125 case WIFI_ERROR_NO_CONNECTION:
126 return "NO_CONNECTION";
127 case WIFI_ERROR_NOW_IN_PROGRESS:
128 return "NOW_IN_PROGRESS";
129 case WIFI_ERROR_ALREADY_EXISTS:
130 return "ALREADY_EXISTS";
131 case WIFI_ERROR_OPERATION_ABORTED:
132 return "OPERATION_ABORTED";
133 case WIFI_ERROR_DHCP_FAILED:
134 return "DHCP_FAILED";
135 case WIFI_ERROR_INVALID_KEY:
136 return "INVALID_KEY";
137 case WIFI_ERROR_NO_REPLY:
139 case WIFI_ERROR_SECURITY_RESTRICTED:
140 return "SECURITY_RESTRICTED";
141 case WIFI_ERROR_PERMISSION_DENIED:
142 return "PERMISSION_DENIED";
143 case WIFI_ERROR_NOT_SUPPORTED:
144 return "NOT_SUPPROTED";
150 static const char *__libnet_convert_ap_state_to_string(wifi_connection_state_e state)
153 case WIFI_CONNECTION_STATE_FAILURE:
155 case WIFI_CONNECTION_STATE_DISCONNECTED:
156 return "DISCONNECTED";
157 case WIFI_CONNECTION_STATE_ASSOCIATION:
158 return "ASSOCIATION";
159 case WIFI_CONNECTION_STATE_CONFIGURATION:
160 return "CONFIGURATION";
161 case WIFI_CONNECTION_STATE_CONNECTED:
168 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
170 if (profile_list->count > 0)
171 g_free(profile_list->profiles);
173 profile_list->count = 0;
174 profile_list->profiles = NULL;
177 static int __libnet_update_profile_iterator(void)
180 struct _profile_list_s wifi_profiles = { 0, NULL };
182 __libnet_clear_profile_list(&profile_iterator);
184 rv = net_get_profile_list(NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
185 WIFI_LOG(WIFI_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
187 if (rv == NET_ERR_ACCESS_DENIED) {
188 WIFI_LOG(WIFI_ERROR, "Access denied");
189 return WIFI_ERROR_PERMISSION_DENIED;
192 if (wifi_profiles.count == 0)
193 return WIFI_ERROR_NONE;
195 profile_iterator.count = wifi_profiles.count;
196 profile_iterator.profiles = wifi_profiles.profiles;
198 return WIFI_ERROR_NONE;
201 static void __libnet_update_specific_profile_iterator(GSList *ap_list)
204 GSList *list = ap_list;
206 for (count = 0; list; list = list->next) {
211 WIFI_LOG(WIFI_INFO, "No hidden AP found\n");
215 specific_profile_iterator.count = count;
216 specific_profile_iterator.profiles = g_try_new0(net_profile_info_t, count);
219 for (count = 0; list; list = list->next) {
220 struct ssid_scan_bss_info_t *ap = (struct ssid_scan_bss_info_t *)list->data;
221 net_profile_info_t *profile = &specific_profile_iterator.profiles[count];
223 g_strlcpy(profile->ProfileInfo.Wlan.essid, ap->ssid, NET_WLAN_ESSID_LEN+1);
224 profile->ProfileInfo.Wlan.security_info.sec_mode = ap->security;
229 WIFI_LOG(WIFI_INFO, "Specific AP count : %d\n", count);
232 static void __libnet_convert_profile_info_to_wifi_info(net_wifi_connection_info_t *wifi_info,
233 net_profile_info_t *ap_info)
235 g_strlcpy(wifi_info->essid, ap_info->ProfileInfo.Wlan.essid, NET_WLAN_ESSID_LEN+1);
236 wifi_info->wlan_mode = ap_info->ProfileInfo.Wlan.wlan_mode;
237 memcpy(&wifi_info->security_info, &ap_info->ProfileInfo.Wlan.security_info, sizeof(wlan_security_info_t));
238 wifi_info->is_hidden = ap_info->ProfileInfo.Wlan.is_hidden;
241 static int __libnet_connect_with_wifi_info(net_profile_info_t *ap_info)
244 net_wifi_connection_info_t wifi_info;
245 memset(&wifi_info, 0, sizeof(net_wifi_connection_info_t));
247 __libnet_convert_profile_info_to_wifi_info(&wifi_info, ap_info);
249 rv = net_open_connection_with_wifi_info(&wifi_info);
250 if (rv == NET_ERR_ACCESS_DENIED) {
251 WIFI_LOG(WIFI_ERROR, "Access denied");
252 return WIFI_ERROR_PERMISSION_DENIED;
253 } else if (rv != NET_ERR_NONE)
254 return WIFI_ERROR_OPERATION_FAILED;
256 return WIFI_ERROR_NONE;
259 static gboolean __wifi_state_changed_cb(gpointer data)
262 struct _wifi_state_notify *notify = (struct _wifi_state_notify *)data;
267 if (notify->ap_info == NULL) {
272 ap_info = (wifi_ap_h)notify->ap_info;
274 _wifi_libnet_add_to_ap_list(ap_info);
276 if (wifi_callbacks.connection_state_cb != NULL)
277 wifi_callbacks.connection_state_cb(notify->state, ap_info,
278 wifi_callbacks.connection_state_user_data);
280 _wifi_libnet_remove_from_ap_list(ap_info);
287 static void __libnet_state_changed_cb(char *profile_name, net_profile_info_t *profile_info,
288 wifi_connection_state_e state)
291 net_profile_info_t *ap_info = NULL;
292 struct _wifi_state_notify *notify = NULL;
294 if (_wifi_is_init() != true) {
295 WIFI_LOG(WIFI_ERROR, "Application is not registered"
296 "If multi-threaded, thread integrity be broken.");
300 if (wifi_callbacks.connection_state_cb == NULL)
303 if (profile_name == NULL)
306 if (profile_info == NULL) {
307 SECURE_WIFI_LOG(WIFI_ERROR, "Failed to find: %s", profile_name);
311 ap_info = g_try_malloc0(sizeof(net_profile_info_t));
312 if (ap_info == NULL) {
313 WIFI_LOG(WIFI_ERROR, "Memory allocation error");
317 memcpy(ap_info, profile_info, sizeof(net_profile_info_t));
319 notify = g_try_new0(struct _wifi_state_notify, 1);
320 if (notify == NULL) {
325 notify->ap_info = ap_info;
326 notify->state = state;
328 id = _wifi_callback_add(__wifi_state_changed_cb, (gpointer)notify);
333 static void __libnet_set_activated_cb(wifi_activated_cb user_cb, void *user_data)
335 if (user_cb != NULL) {
336 wifi_callbacks.activated_cb = user_cb;
337 wifi_callbacks.activated_user_data = user_data;
341 static gboolean __activated_cb_idle(gpointer data)
343 wifi_error_e result = (wifi_error_e)data;
345 if (wifi_callbacks.activated_cb != NULL)
346 wifi_callbacks.activated_cb(result, wifi_callbacks.activated_user_data);
348 wifi_callbacks.activated_cb = NULL;
349 wifi_callbacks.activated_user_data = NULL;
354 static void __libnet_set_deactivated_cb(wifi_deactivated_cb user_cb, void *user_data)
356 if (user_cb != NULL) {
357 wifi_callbacks.deactivated_cb = user_cb;
358 wifi_callbacks.deactivated_user_data = user_data;
362 static gboolean __deactivated_cb_idle(gpointer data)
364 wifi_error_e result = (wifi_error_e)data;
366 if (wifi_callbacks.deactivated_cb != NULL)
367 wifi_callbacks.deactivated_cb(result, wifi_callbacks.deactivated_user_data);
369 wifi_callbacks.deactivated_cb = NULL;
370 wifi_callbacks.deactivated_user_data = NULL;
375 static gboolean __device_state_cb_idle(gpointer data)
377 wifi_device_state_e state = (wifi_device_state_e)data;
379 if (wifi_callbacks.device_state_cb != NULL)
380 wifi_callbacks.device_state_cb(state, wifi_callbacks.device_state_user_data);
385 static void __libnet_power_on_off_cb(net_event_info_t *event_cb, bool is_requested)
387 if (_wifi_is_init() != true) {
388 WIFI_LOG(WIFI_ERROR, "Application is not registered"
389 "If multi-threaded, thread integrity be broken.");
393 if (wifi_callbacks.device_state_cb == NULL &&
394 wifi_callbacks.activated_cb == NULL &&
395 wifi_callbacks.deactivated_cb == NULL)
398 wifi_error_e error_code = WIFI_ERROR_NONE;
399 wifi_device_state_e state = WIFI_DEVICE_STATE_DEACTIVATED;
400 net_wifi_state_t *wifi_state = (net_wifi_state_t *)event_cb->Data;
402 if (event_cb->Error == NET_ERR_NONE &&
403 event_cb->Datalength == sizeof(net_wifi_state_t)) {
404 if (*wifi_state == WIFI_ON) {
405 WIFI_LOG(WIFI_INFO, "Wi-Fi power on");
406 state = WIFI_DEVICE_STATE_ACTIVATED;
407 } else if (*wifi_state == WIFI_OFF) {
408 WIFI_LOG(WIFI_INFO, "Wi-Fi power off");
409 state = WIFI_DEVICE_STATE_DEACTIVATED;
410 __libnet_clear_profile_list(&profile_iterator);
412 WIFI_LOG(WIFI_ERROR, "Error Wi-Fi state %d", *wifi_state);
413 error_code = WIFI_ERROR_OPERATION_FAILED;
414 state = WIFI_DEVICE_STATE_DEACTIVATED;
417 WIFI_LOG(WIFI_ERROR, "Wi-Fi power request failed(%d)", event_cb->Error);
419 if (event_cb->Error == NET_ERR_SECURITY_RESTRICTED)
420 error_code = WIFI_ERROR_SECURITY_RESTRICTED;
422 error_code = WIFI_ERROR_OPERATION_FAILED;
424 state = WIFI_DEVICE_STATE_DEACTIVATED;
427 if (wifi_callbacks.activated_cb != NULL)
428 _wifi_callback_add(__activated_cb_idle, (gpointer)error_code);
430 if (wifi_callbacks.deactivated_cb != NULL)
431 _wifi_callback_add(__deactivated_cb_idle, (gpointer)error_code);
433 if (wifi_callbacks.device_state_cb != NULL)
434 _wifi_callback_add(__device_state_cb_idle, (gpointer)state);
437 static gboolean __scan_request_cb_idle(gpointer data)
439 wifi_error_e error_code = (wifi_error_e)data;
441 if (wifi_callbacks.scan_request_cb != NULL)
442 wifi_callbacks.scan_request_cb(error_code, wifi_callbacks.scan_request_user_data);
444 wifi_callbacks.scan_request_cb = NULL;
445 wifi_callbacks.scan_request_user_data = NULL;
450 static void __libnet_set_specific_scan_cb(wifi_scan_finished_cb user_cb, void *user_data)
452 if (user_cb != NULL) {
453 wifi_callbacks.specific_scan_cb = user_cb;
454 wifi_callbacks.specific_scan_user_data = user_data;
458 static gboolean __specific_scan_cb_idle(gpointer data)
460 wifi_error_e error_code = (wifi_error_e)data;
462 if (wifi_callbacks.specific_scan_cb != NULL)
463 wifi_callbacks.specific_scan_cb(error_code, wifi_callbacks.specific_scan_user_data);
465 wifi_callbacks.specific_scan_cb = NULL;
466 wifi_callbacks.specific_scan_user_data = NULL;
471 static gboolean __bgscan_cb_idle(gpointer data)
473 wifi_error_e error_code = (wifi_error_e)data;
475 if (wifi_callbacks.bg_scan_cb != NULL)
476 wifi_callbacks.bg_scan_cb(error_code, wifi_callbacks.bg_scan_user_data);
481 static void __libnet_scan_cb(net_event_info_t *event_cb, bool is_requested)
483 wifi_error_e error_code = WIFI_ERROR_NONE;
485 if (_wifi_is_init() != true) {
486 WIFI_LOG(WIFI_ERROR, "Application is not registered"
487 "If multi-threaded, thread integrity be broken.");
491 if (event_cb->Error != NET_ERR_NONE) {
492 WIFI_LOG(WIFI_ERROR, "Scan failed[%d]", event_cb->Error);
493 error_code = WIFI_ERROR_OPERATION_FAILED;
496 if (wifi_callbacks.scan_request_cb != NULL) {
497 _wifi_callback_add(__scan_request_cb_idle, (gpointer)error_code);
501 if (wifi_callbacks.bg_scan_cb != NULL)
502 _wifi_callback_add(__bgscan_cb_idle, (gpointer)error_code);
505 static void __libnet_specific_scan_cb(net_event_info_t *event_cb)
507 wifi_error_e error_code = WIFI_ERROR_NONE;
509 __libnet_clear_profile_list(&specific_profile_iterator);
511 if (event_cb->Error != NET_ERR_NONE) {
512 WIFI_LOG(WIFI_ERROR, "Specific scan failed!, Error [%d]\n", event_cb->Error);
513 error_code = WIFI_ERROR_OPERATION_FAILED;
514 } else if (event_cb->Data) {
515 GSList *ap_list = (GSList *)event_cb->Data;
516 __libnet_update_specific_profile_iterator(ap_list);
519 if (wifi_callbacks.specific_scan_cb != NULL)
520 _wifi_callback_add(__specific_scan_cb_idle, (gpointer)error_code);
523 static void __libnet_set_connected_cb(wifi_connected_cb user_cb, void *user_data)
525 if (user_cb != NULL) {
526 wifi_callbacks.connected_cb = user_cb;
527 wifi_callbacks.connected_user_data = user_data;
531 static gboolean __connected_cb_idle(gpointer data)
533 wifi_error_e result = (wifi_error_e)data;
535 if (wifi_callbacks.connected_cb != NULL)
536 wifi_callbacks.connected_cb(result, wifi_callbacks.connected_user_data);
538 wifi_callbacks.connected_cb = NULL;
539 wifi_callbacks.connected_user_data = NULL;
544 static void __libnet_connected_cb(wifi_error_e result)
546 if (_wifi_is_init() != true) {
547 WIFI_LOG(WIFI_ERROR, "Application is not registered"
548 "If multi-threaded, thread integrity be broken.");
552 if (wifi_callbacks.connected_cb != NULL)
553 _wifi_callback_add(__connected_cb_idle, (gpointer)result);
556 static void __libnet_set_disconnected_cb(wifi_disconnected_cb user_cb, void *user_data)
558 if (user_cb != NULL) {
559 wifi_callbacks.disconnected_cb = user_cb;
560 wifi_callbacks.disconnected_user_data = user_data;
564 static gboolean __disconnected_cb_idle(gpointer data)
566 wifi_error_e result = (wifi_error_e)data;
568 if (wifi_callbacks.disconnected_cb != NULL)
569 wifi_callbacks.disconnected_cb(result, wifi_callbacks.disconnected_user_data);
571 wifi_callbacks.disconnected_cb = NULL;
572 wifi_callbacks.disconnected_user_data = NULL;
577 static void __libnet_disconnected_cb(wifi_error_e result)
579 if (_wifi_is_init() != true) {
580 WIFI_LOG(WIFI_ERROR, "Application is not registered"
581 "If multi-threaded, thread integrity be broken.");
585 if (wifi_callbacks.disconnected_cb != NULL)
586 _wifi_callback_add(__disconnected_cb_idle, (gpointer)result);
589 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
591 bool is_requested = false;
592 net_profile_info_t *prof_info_p = NULL;
593 net_profile_info_t prof_info;
594 wifi_error_e result = WIFI_ERROR_NONE;
596 bool is_profile_exists = false;
598 switch (event_cb->Event) {
599 case NET_EVENT_OPEN_RSP:
600 case NET_EVENT_WIFI_WPS_RSP:
603 case NET_EVENT_OPEN_IND:
604 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
607 result = __libnet_convert_to_ap_error_type(event_cb->Error);
608 WIFI_LOG(WIFI_INFO, "Connection open error %s",
609 __libnet_convert_ap_error_type_to_string(result));
612 __libnet_connected_cb(result);
614 switch (event_cb->Error) {
616 if (event_cb->Datalength == sizeof(net_profile_info_t))
617 prof_info_p = (net_profile_info_t *)event_cb->Data;
619 __libnet_state_changed_cb(event_cb->ProfileName, prof_info_p,
620 WIFI_CONNECTION_STATE_CONNECTED);
622 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
628 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
629 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
630 WIFI_CONNECTION_STATE_DISCONNECTED);
632 __libnet_state_changed_cb(event_cb->ProfileName, NULL,
633 WIFI_CONNECTION_STATE_DISCONNECTED);
636 case NET_EVENT_CLOSE_RSP:
639 case NET_EVENT_CLOSE_IND:
640 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
643 result = __libnet_convert_to_ap_error_type(event_cb->Error);
644 WIFI_LOG(WIFI_ERROR, "Connection close error %s",
645 __libnet_convert_ap_error_type_to_string(result));
648 __libnet_disconnected_cb(result);
650 switch (event_cb->Error) {
652 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
653 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info,
654 WIFI_CONNECTION_STATE_DISCONNECTED);
656 __libnet_state_changed_cb(event_cb->ProfileName, NULL,
657 WIFI_CONNECTION_STATE_DISCONNECTED);
664 case NET_EVENT_NET_STATE_IND:
665 if (_wifi_libnet_check_profile_name_validity(event_cb->ProfileName) != true)
668 if (event_cb->Datalength != sizeof(net_state_type_t))
671 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
672 wifi_connection_state_e ap_state = _wifi_convert_to_ap_state(*profile_state);
674 WIFI_LOG(WIFI_INFO, "state: %s", __libnet_convert_ap_state_to_string(ap_state));
675 SECURE_WIFI_LOG(WIFI_INFO, "profile name: %s", event_cb->ProfileName);
677 if (net_get_profile_info(event_cb->ProfileName, &prof_info) == NET_ERR_NONE)
678 __libnet_state_changed_cb(event_cb->ProfileName, &prof_info, ap_state);
679 else if (ap_state == WIFI_CONNECTION_STATE_DISCONNECTED) {
680 for (i = 0; i < profile_iterator.count; i++) {
681 if (!g_strcmp0(event_cb->ProfileName,
682 profile_iterator.profiles[i].ProfileName)) {
683 is_profile_exists = true;
688 if (is_profile_exists == true) {
689 profile_iterator.profiles[i].ProfileState = *profile_state;
690 __libnet_state_changed_cb(event_cb->ProfileName,
691 &profile_iterator.profiles[i], ap_state);
693 __libnet_state_changed_cb(event_cb->ProfileName,
696 __libnet_state_changed_cb(event_cb->ProfileName, NULL, ap_state);
699 case NET_EVENT_WIFI_SCAN_RSP:
700 case NET_EVENT_WIFI_SCAN_IND:
701 __libnet_scan_cb(event_cb, is_requested);
703 case NET_EVENT_SPECIFIC_SCAN_RSP:
704 WIFI_LOG(WIFI_INFO, "Got Wi-Fi specific scan RSP\n");
706 case NET_EVENT_SPECIFIC_SCAN_IND:
707 WIFI_LOG(WIFI_INFO, "Got Wi-Fi specific scan IND\n");
708 __libnet_specific_scan_cb(event_cb);
710 case NET_EVENT_WIFI_POWER_RSP:
713 case NET_EVENT_WIFI_POWER_IND:
714 __libnet_power_on_off_cb(event_cb, is_requested);
721 int _wifi_libnet_init(void)
725 rv = net_register_client_ext((net_event_cb_t)__libnet_evt_cb, NET_DEVICE_WIFI, NULL);
726 if (rv != NET_ERR_NONE)
729 __wifi_set_init(true);
734 bool _wifi_libnet_deinit(void)
736 if (net_deregister_client_ext(NET_DEVICE_WIFI) != NET_ERR_NONE)
739 __libnet_clear_profile_list(&profile_iterator);
740 g_slist_free_full(ap_handle_list, g_free);
741 ap_handle_list = NULL;
742 memset(&wifi_callbacks, 0, sizeof(struct _wifi_cb_s));
744 __wifi_set_init(false);
749 int _wifi_activate(wifi_activated_cb callback, gboolean wifi_picker_test,
752 int rv = NET_ERR_NONE;
754 rv = net_wifi_power_on(wifi_picker_test);
755 if (rv == NET_ERR_NONE) {
756 __libnet_set_activated_cb(callback, user_data);
757 return WIFI_ERROR_NONE;
758 } else if (rv == NET_ERR_ACCESS_DENIED) {
759 WIFI_LOG(WIFI_ERROR, "Access denied");
760 return WIFI_ERROR_PERMISSION_DENIED;
761 } else if (rv == NET_ERR_INVALID_OPERATION)
762 return WIFI_ERROR_INVALID_OPERATION;
763 else if (rv == NET_ERR_ALREADY_EXISTS)
764 return WIFI_ERROR_ALREADY_EXISTS;
765 else if (rv == NET_ERR_IN_PROGRESS)
766 return WIFI_ERROR_NOW_IN_PROGRESS;
767 else if (rv == NET_ERR_SECURITY_RESTRICTED)
768 return WIFI_ERROR_SECURITY_RESTRICTED;
770 return WIFI_ERROR_OPERATION_FAILED;
773 int _wifi_deactivate(wifi_deactivated_cb callback, void *user_data)
775 int rv = NET_ERR_NONE;
777 rv = net_wifi_power_off();
778 if (rv == NET_ERR_NONE) {
779 __libnet_set_deactivated_cb(callback, user_data);
780 return WIFI_ERROR_NONE;
781 } else if (rv == NET_ERR_ACCESS_DENIED) {
782 WIFI_LOG(WIFI_ERROR, "Access denied");
783 return WIFI_ERROR_PERMISSION_DENIED;
784 } else if (rv == NET_ERR_INVALID_OPERATION)
785 return WIFI_ERROR_INVALID_OPERATION;
786 else if (rv == NET_ERR_ALREADY_EXISTS)
787 return WIFI_ERROR_ALREADY_EXISTS;
788 else if (rv == NET_ERR_IN_PROGRESS)
789 return WIFI_ERROR_NOW_IN_PROGRESS;
790 else if (rv == NET_ERR_SECURITY_RESTRICTED)
791 return WIFI_ERROR_SECURITY_RESTRICTED;
793 return WIFI_ERROR_OPERATION_FAILED;
796 bool _wifi_libnet_check_ap_validity(wifi_ap_h ap_h)
804 for (list = ap_handle_list; list; list = list->next)
805 if (ap_h == list->data) return true;
807 for (i = 0; i < profile_iterator.count; i++)
808 if (ap_h == &profile_iterator.profiles[i]) return true;
810 for (i = 0; i < specific_profile_iterator.count; i++)
811 if (ap_h == &specific_profile_iterator.profiles[i]) return true;
816 void _wifi_libnet_add_to_ap_list(wifi_ap_h ap_h)
818 ap_handle_list = g_slist_append(ap_handle_list, ap_h);
821 void _wifi_libnet_remove_from_ap_list(wifi_ap_h ap_h)
823 ap_handle_list = g_slist_remove(ap_handle_list, ap_h);
827 bool _wifi_libnet_check_profile_name_validity(const char *profile_name)
829 const char *profile_prefix = "/net/connman/service/wifi_";
832 if (profile_name == NULL ||
833 g_str_has_prefix(profile_name, profile_prefix) != TRUE) {
834 WIFI_LOG(WIFI_INFO, "The profile is a hidden or not a regular Wi-Fi profile");
838 while (profile_name[i] != '\0') {
839 if (isgraph(profile_name[i]) == 0) {
840 WIFI_LOG(WIFI_INFO, "Invalid format: %s", profile_name);
849 int _wifi_libnet_get_wifi_device_state(wifi_device_state_e *device_state)
851 net_tech_info_t tech_info;
853 int rv = NET_ERR_NONE;
854 rv = net_get_technology_properties(NET_DEVICE_WIFI, &tech_info);
855 if (rv == NET_ERR_ACCESS_DENIED) {
856 WIFI_LOG(WIFI_ERROR, "Access denied");
857 return WIFI_ERROR_PERMISSION_DENIED;
858 } else if (rv != NET_ERR_NONE) {
859 WIFI_LOG(WIFI_ERROR, "Failed to get technology properties");
860 return WIFI_ERROR_OPERATION_FAILED;
863 if (tech_info.powered)
864 *device_state = WIFI_DEVICE_STATE_ACTIVATED;
866 *device_state = WIFI_DEVICE_STATE_DEACTIVATED;
868 return WIFI_ERROR_NONE;
871 int _wifi_libnet_get_wifi_state(wifi_connection_state_e* connection_state)
874 net_wifi_state_t wlan_state = 0;
875 net_profile_name_t profile_name;
877 rv = net_get_wifi_state(&wlan_state, &profile_name);
878 if (rv == NET_ERR_ACCESS_DENIED) {
879 WIFI_LOG(WIFI_ERROR, "Access denied");
880 return WIFI_ERROR_PERMISSION_DENIED;
881 } else if (rv != NET_ERR_NONE) {
882 WIFI_LOG(WIFI_ERROR, "Failed to get Wi-Fi state");
883 return WIFI_ERROR_OPERATION_FAILED;
886 switch (wlan_state) {
889 *connection_state = WIFI_CONNECTION_STATE_DISCONNECTED;
891 case WIFI_ASSOCIATION:
892 *connection_state = WIFI_CONNECTION_STATE_ASSOCIATION;
894 case WIFI_CONFIGURATION:
895 *connection_state = WIFI_CONNECTION_STATE_CONFIGURATION;
898 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
900 case WIFI_DISCONNECTING:
901 *connection_state = WIFI_CONNECTION_STATE_CONNECTED;
904 WIFI_LOG(WIFI_ERROR, "Unknown state");
905 return WIFI_ERROR_OPERATION_FAILED;
908 return WIFI_ERROR_NONE;
911 int _wifi_libnet_get_intf_name(char** name)
915 if (profile_iterator.count == 0) {
916 rv = __libnet_update_profile_iterator();
917 if (rv == NET_ERR_ACCESS_DENIED) {
918 WIFI_LOG(WIFI_ERROR, "Access denied");
919 return WIFI_ERROR_PERMISSION_DENIED;
923 if (profile_iterator.count == 0) {
924 WIFI_LOG(WIFI_ERROR, "There is no AP");
925 return WIFI_ERROR_OPERATION_FAILED;
928 *name = g_strdup(profile_iterator.profiles->ProfileInfo.Wlan.net_info.DevName);
930 return WIFI_ERROR_OUT_OF_MEMORY;
932 return WIFI_ERROR_NONE;
935 int _wifi_libnet_scan_request(wifi_scan_finished_cb callback, void *user_data)
938 rv = net_scan_wifi();
940 if (rv == NET_ERR_NONE) {
941 wifi_callbacks.scan_request_cb = callback;
942 wifi_callbacks.scan_request_user_data = user_data;
943 return WIFI_ERROR_NONE;
944 } else if (rv == NET_ERR_ACCESS_DENIED) {
945 WIFI_LOG(WIFI_ERROR, "Access denied");
946 return WIFI_ERROR_PERMISSION_DENIED;
947 } else if (rv == NET_ERR_INVALID_OPERATION)
948 return WIFI_ERROR_INVALID_OPERATION;
950 return WIFI_ERROR_OPERATION_FAILED;
953 int _wifi_libnet_scan_specific_ap(const char *essid,
954 wifi_scan_finished_cb callback, void *user_data)
957 rv = net_specific_scan_wifi(essid);
959 if (rv == NET_ERR_NONE) {
960 g_strlcpy(specific_profile_essid, essid, NET_WLAN_ESSID_LEN+1);
961 __libnet_set_specific_scan_cb(callback, user_data);
962 return WIFI_ERROR_NONE;
963 } else if (rv == NET_ERR_ACCESS_DENIED) {
964 WIFI_LOG(WIFI_ERROR, "Access denied");
965 return WIFI_ERROR_PERMISSION_DENIED;
966 } else if (rv == NET_ERR_INVALID_OPERATION)
967 return WIFI_ERROR_INVALID_OPERATION;
969 return WIFI_ERROR_OPERATION_FAILED;
972 int _wifi_libnet_get_connected_profile(wifi_ap_h *ap)
975 wifi_ap_h ap_h = NULL;
977 rv = __libnet_update_profile_iterator();
978 if (rv == NET_ERR_ACCESS_DENIED) {
979 WIFI_LOG(WIFI_ERROR, "Access denied");
980 return WIFI_ERROR_PERMISSION_DENIED;
983 for (i = 0; i < profile_iterator.count; i++) {
984 if (profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
985 profile_iterator.profiles[i].ProfileState == NET_STATE_TYPE_READY) {
986 ap_h = (wifi_ap_h)(&profile_iterator.profiles[i]);
992 WIFI_LOG(WIFI_ERROR, "There is no connected AP");
993 return WIFI_ERROR_NO_CONNECTION;
996 *ap = g_try_malloc0(sizeof(net_profile_info_t));
998 return WIFI_ERROR_OUT_OF_MEMORY;
1000 memcpy(*ap, ap_h, sizeof(net_profile_info_t));
1002 _wifi_libnet_add_to_ap_list(*ap);
1004 return WIFI_ERROR_NONE;
1007 int _wifi_libnet_foreach_found_aps(wifi_found_ap_cb callback, void *user_data)
1011 rv = __libnet_update_profile_iterator();
1012 if (rv == NET_ERR_ACCESS_DENIED) {
1013 WIFI_LOG(WIFI_ERROR, "Access denied");
1014 return WIFI_ERROR_PERMISSION_DENIED;
1017 if (profile_iterator.count == 0) {
1018 WIFI_LOG(WIFI_WARN, "There is no AP");
1019 return WIFI_ERROR_NONE;
1022 for (i = 0; i < profile_iterator.count; i++) {
1023 if (profile_iterator.profiles[i].ProfileInfo.Wlan.is_hidden == TRUE)
1026 rv = callback((wifi_ap_h)(&profile_iterator.profiles[i]), user_data);
1027 if (rv == false) break;
1030 return WIFI_ERROR_NONE;
1033 int _wifi_libnet_foreach_found_specific_aps(wifi_found_ap_cb callback, void *user_data)
1037 if (specific_profile_iterator.count == 0) {
1038 WIFI_LOG(WIFI_WARN, "There is no specific APs");
1040 rv = __libnet_update_profile_iterator();
1041 if (rv == NET_ERR_ACCESS_DENIED) {
1042 WIFI_LOG(WIFI_ERROR, "Access denied");
1043 return WIFI_ERROR_PERMISSION_DENIED;
1046 if (profile_iterator.count == 0) {
1047 WIFI_LOG(WIFI_WARN, "There is no APs");
1048 return WIFI_ERROR_NONE;
1051 for (i = 0; i < profile_iterator.count; i++) {
1052 if (!g_strcmp0(specific_profile_essid,
1053 profile_iterator.profiles[i].ProfileInfo.Wlan.essid)) {
1054 rv = callback((wifi_ap_h)(&profile_iterator.profiles[i]), user_data);
1055 if (rv == false) break;
1058 return WIFI_ERROR_NONE;
1061 for (i = 0; i < specific_profile_iterator.count; i++) {
1062 rv = callback((wifi_ap_h)(&specific_profile_iterator.profiles[i]), user_data);
1063 if (rv == false) break;
1066 return WIFI_ERROR_NONE;
1069 int _wifi_libnet_open_profile(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
1073 net_profile_info_t *ap_info = ap_h;
1076 _wifi_libnet_check_profile_name_validity(ap_info->ProfileName);
1078 if (valid_profile == true && ap_info->Favourite)
1079 rv = net_open_connection_with_profile(ap_info->ProfileName);
1080 else if (valid_profile == true &&
1081 ap_info->ProfileInfo.Wlan.is_hidden != TRUE &&
1082 ap_info->ProfileInfo.Wlan.security_info.sec_mode ==
1084 rv = net_open_connection_with_profile(ap_info->ProfileName);
1086 rv = __libnet_connect_with_wifi_info(ap_info);
1088 rv = __libnet_convert_to_ap_error_type(rv);
1089 if (rv == WIFI_ERROR_NONE)
1090 __libnet_set_connected_cb(callback, user_data);
1095 int _wifi_libnet_close_profile(wifi_ap_h ap_h, wifi_disconnected_cb callback, void *user_data)
1098 net_profile_info_t *ap_info = ap_h;
1100 rv = net_close_connection(ap_info->ProfileName);
1101 if (rv == NET_ERR_ACCESS_DENIED) {
1102 WIFI_LOG(WIFI_ERROR, "Access denied");
1103 return WIFI_ERROR_PERMISSION_DENIED;
1104 } else if (rv != NET_ERR_NONE)
1105 return WIFI_ERROR_OPERATION_FAILED;
1107 __libnet_set_disconnected_cb(callback, user_data);
1109 return WIFI_ERROR_NONE;
1112 int _wifi_libnet_connect_with_wps_pbc(wifi_ap_h ap_h, wifi_connected_cb callback, void *user_data)
1115 net_profile_info_t *ap_info = ap_h;
1116 net_wifi_wps_info_t wps_info;
1117 memset(&wps_info, 0, sizeof(net_wifi_wps_info_t));
1119 wps_info.type = WIFI_WPS_PBC;
1121 rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
1122 if (rv == NET_ERR_ACCESS_DENIED) {
1123 WIFI_LOG(WIFI_ERROR, "Access denied");
1124 return WIFI_ERROR_PERMISSION_DENIED;
1125 } else if (rv != NET_ERR_NONE)
1126 return WIFI_ERROR_OPERATION_FAILED;
1128 __libnet_set_connected_cb(callback, user_data);
1130 return WIFI_ERROR_NONE;
1133 int _wifi_libnet_connect_with_wps_pin(wifi_ap_h ap_h, const char *pin,
1134 wifi_connected_cb callback, void *user_data)
1137 net_profile_info_t *ap_info = ap_h;
1138 net_wifi_wps_info_t wps_info;
1140 if (ap_info == NULL) {
1141 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
1142 return WIFI_ERROR_INVALID_PARAMETER;
1145 wps_info.type = WIFI_WPS_PIN;
1146 g_strlcpy(wps_info.pin, pin, NET_WLAN_MAX_WPSPIN_LEN + 1);
1148 rv = net_wifi_enroll_wps(ap_info->ProfileName, &wps_info);
1149 if (rv == NET_ERR_ACCESS_DENIED) {
1150 WIFI_LOG(WIFI_ERROR, "Access denied");
1151 return WIFI_ERROR_PERMISSION_DENIED;
1152 } else if (rv != NET_ERR_NONE)
1153 return WIFI_ERROR_OPERATION_FAILED;
1155 __libnet_set_connected_cb(callback, user_data);
1157 return WIFI_ERROR_NONE;
1160 int _wifi_libnet_forget_ap(wifi_ap_h ap)
1163 net_profile_info_t *ap_info = ap;
1165 if (ap_info == NULL) {
1166 WIFI_LOG(WIFI_ERROR, "Invalid parameter");
1167 return WIFI_ERROR_INVALID_PARAMETER;
1170 rv = net_delete_profile(ap_info->ProfileName);
1171 if (rv == NET_ERR_ACCESS_DENIED) {
1172 WIFI_LOG(WIFI_ERROR, "Access denied");
1173 return WIFI_ERROR_PERMISSION_DENIED;
1174 } else if (rv != NET_ERR_NONE)
1175 return WIFI_ERROR_OPERATION_FAILED;
1177 ap_info->Favourite = (char)FALSE;
1179 return WIFI_ERROR_NONE;
1182 int _wifi_set_power_on_off_cb(wifi_device_state_changed_cb callback, void *user_data)
1184 if (wifi_callbacks.device_state_cb != NULL)
1185 return WIFI_ERROR_INVALID_OPERATION;
1187 wifi_callbacks.device_state_cb = callback;
1188 wifi_callbacks.device_state_user_data = user_data;
1190 WIFI_LOG(WIFI_INFO, "Wi-Fi registered device state changed callback");
1192 return WIFI_ERROR_NONE;
1195 int _wifi_unset_power_on_off_cb(void)
1197 if (wifi_callbacks.device_state_cb == NULL)
1198 return WIFI_ERROR_INVALID_OPERATION;
1200 wifi_callbacks.device_state_cb = NULL;
1201 wifi_callbacks.device_state_user_data = NULL;
1203 return WIFI_ERROR_NONE;
1206 int _wifi_set_background_scan_cb(wifi_scan_finished_cb callback, void *user_data)
1208 if (wifi_callbacks.bg_scan_cb != NULL)
1209 return WIFI_ERROR_INVALID_OPERATION;
1211 wifi_callbacks.bg_scan_cb = callback;
1212 wifi_callbacks.bg_scan_user_data = user_data;
1214 return WIFI_ERROR_NONE;
1217 int _wifi_unset_background_scan_cb(void)
1219 if (wifi_callbacks.bg_scan_cb == NULL)
1220 return WIFI_ERROR_INVALID_OPERATION;
1222 wifi_callbacks.bg_scan_cb = NULL;
1223 wifi_callbacks.bg_scan_user_data = NULL;
1225 return WIFI_ERROR_NONE;
1228 int _wifi_set_connection_state_cb(wifi_connection_state_changed_cb callback, void *user_data)
1230 if (wifi_callbacks.connection_state_cb != NULL)
1231 return WIFI_ERROR_INVALID_OPERATION;
1233 wifi_callbacks.connection_state_cb = callback;
1234 wifi_callbacks.connection_state_user_data = user_data;
1236 return WIFI_ERROR_NONE;
1239 int _wifi_unset_connection_state_cb()
1241 if (wifi_callbacks.connection_state_cb == NULL)
1242 return WIFI_ERROR_INVALID_OPERATION;
1244 wifi_callbacks.connection_state_cb = NULL;
1245 wifi_callbacks.connection_state_user_data = NULL;
1247 return WIFI_ERROR_NONE;
1250 int _wifi_update_ap_info(net_profile_info_t *ap_info)
1252 int rv = NET_ERR_NONE;
1253 rv = net_modify_profile(ap_info->ProfileName, ap_info);
1255 if (rv == NET_ERR_ACCESS_DENIED) {
1256 WIFI_LOG(WIFI_ERROR, "Access denied");
1257 return WIFI_ERROR_PERMISSION_DENIED;
1258 } else if (rv != NET_ERR_NONE)
1259 return WIFI_ERROR_OPERATION_FAILED;
1261 return WIFI_ERROR_NONE;
1264 static void __wifi_idle_destroy_cb(gpointer data)
1269 managed_idler_list = g_slist_remove(managed_idler_list, data);
1273 static gboolean __wifi_idle_cb(gpointer user_data)
1275 struct managed_idle_data *data = (struct managed_idle_data *)user_data;
1280 return data->func(data->user_data);
1283 guint _wifi_callback_add(GSourceFunc func, gpointer user_data)
1286 struct managed_idle_data *data;
1291 data = g_try_new0(struct managed_idle_data, 1);
1296 data->user_data = user_data;
1298 id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, __wifi_idle_cb, data,
1299 __wifi_idle_destroy_cb);
1307 managed_idler_list = g_slist_append(managed_idler_list, data);
1312 void _wifi_callback_cleanup(void)
1314 GSList *cur = managed_idler_list;
1316 struct managed_idle_data *data;
1319 GSList *next = cur->next;
1320 data = (struct managed_idle_data *)cur->data;
1322 src = g_main_context_find_source_by_id(g_main_context_default(), data->id);
1324 g_source_destroy(src);
1325 cur = managed_idler_list;
1330 g_slist_free(managed_idler_list);
1331 managed_idler_list = NULL;