2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
18 * This file implements Wi-Fi direct client functions.
21 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
29 #include <Elementary.h>
32 #include <network-cm-intf.h>
33 #include <network-wifi-intf.h>
34 #include <wifi-direct.h>
37 #include "wfd_ug_view.h"
38 #include "wfd_client.h"
43 static void _wifi_state_cb(keynode_t *key, void *data)
46 struct ug_data *ugd = (struct ug_data*) data;
50 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
53 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
57 if (wifi_state == VCONFKEY_WIFI_OFF)
59 DBG(LOG_VERBOSE, "WiFi is turned off\n");
60 wfd_client_swtch_force(ugd, TRUE);
64 DBG(LOG_VERBOSE, "WiFi is turned on\n");
67 res = net_deregister_client();
68 if (res != NET_ERR_NONE)
70 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
76 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
79 DBG(LOG_VERBOSE, "Event from network. [%d]\n", event_info->Event);
83 int wfd_wifi_off(void *data)
86 struct ug_data *ugd = (struct ug_data*) data;
89 res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
92 DBG(LOG_ERROR, "Failed to register vconf callback\n");
95 DBG(LOG_VERBOSE, "Vconf key callback is registered\n");
96 res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
97 if (res != NET_ERR_NONE)
99 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
102 DBG(LOG_VERBOSE, "Network client is registered\n");
103 res = net_wifi_power_off();
104 if (res != NET_ERR_NONE)
106 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
109 DBG(LOG_VERBOSE, "WiFi power off\n");
114 static device_type_s *wfd_client_find_peer_by_ssid(void *data, const char *ssid)
117 struct ug_data *ugd = (struct ug_data *) data;
122 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
126 for (i = 0; i < ugd->peer_cnt; i++)
128 DBG(LOG_VERBOSE, "check %dth peer\n", i);
129 if (!strcmp(ugd->peers[i].ssid, ssid))
131 DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
133 return &ugd->peers[i];
141 static device_type_s *wfd_client_find_peer_by_mac(void *data,
142 const char *mac_addr)
145 struct ug_data *ugd = (struct ug_data *) data;
150 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
154 for (i = 0; i < ugd->peer_cnt; i++)
156 DBG(LOG_VERBOSE, "check %dth peer\n", i);
158 (mac_addr, (const char *) ugd->peers[i].mac_addr, MAC_LENGTH))
160 DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
162 return &ugd->peers[i];
170 void _activation_cb(int error_code, wifi_direct_device_state_e device_state,
175 wifi_direct_state_e wfd_status;
176 struct ug_data *ugd = (struct ug_data *) user_data;
178 wifi_direct_get_state(&wfd_status);
179 DBG(LOG_VERBOSE, "WFD status [%d]", wfd_status);
180 ugd->wfd_status = wfd_status;
182 switch (device_state)
184 case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
185 DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
186 if(error_code != WIFI_DIRECT_ERROR_NONE)
188 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
189 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL);
191 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
193 wfd_ug_view_refresh_glitem(ugd->head);
197 ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
199 wfd_ug_view_refresh_glitem(ugd->head);
200 res = vconf_set_int("db/wifi_direct/onoff", ugd->wfd_onoff);
203 DBG(LOG_ERROR, "Failed to set vconf value for WFD onoff status\n");
205 wfg_ug_act_popup_remove(ugd);
207 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
211 "Failed to ignore vconf key callback for wifi state\n");
214 res = wifi_direct_start_discovery(FALSE, 0);
215 if (res != WIFI_DIRECT_ERROR_NONE)
217 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
220 DBG(LOG_VERBOSE, "Discovery is started\n");
221 case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
222 DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
223 if(error_code != WIFI_DIRECT_ERROR_NONE)
225 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
226 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL);
227 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
229 wfd_ug_view_refresh_glitem(ugd->head);
233 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
235 wfd_ug_view_refresh_glitem(ugd->head);
236 res = vconf_set_int("db/wifi_direct/onoff", ugd->wfd_onoff);
239 DBG(LOG_ERROR, "Failed to set vconf value for WFD onoff status\n");
241 wfd_ug_view_free_peers(ugd);
242 wfd_ug_view_update_peers(ugd);
247 wfd_ug_view_refresh_button(ugd->scan_btn, ugd->wfd_onoff);
254 static int connected_cnt;
255 static int discovered_cnt;
257 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s * peer,
261 device_type_s *peers = (device_type_s *) user_data;
263 DBG(LOG_VERBOSE, "%dth discovered peer. [%s]\n", peer_cnt, peer->ssid);
264 if (peer->is_connected == TRUE)
266 memcpy(peers[peer_cnt].ssid, peer->ssid, SSID_LENGTH);
267 peers[peer_cnt].ssid[31] = '\0';
268 DBG(LOG_VERBOSE, "\tSSID: [%s]\n", peers[peer_cnt].ssid);
269 peers[peer_cnt].category = peer->primary_device_type;
270 DBG(LOG_VERBOSE, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peers[peer_cnt].category);
271 strncpy(peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
272 strncpy(peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
273 peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED;
274 DBG(LOG_VERBOSE, "\tStatus: [%d]\n", peers[peer_cnt].conn_status);
278 free(peer->mac_address);
279 free(peer->interface_address);
285 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s * peer,
289 device_type_s *peers = (device_type_s *) user_data;
291 DBG(LOG_VERBOSE, "%dth connected peer. [%s]\n", peer_cnt, peer->ssid);
292 memcpy(peers[peer_cnt].ssid, peer->ssid, SSID_LENGTH);
293 peers[peer_cnt].ssid[31] = '\0';
294 DBG(LOG_VERBOSE, "\tSSID: [%s]\n", peers[peer_cnt].ssid);
295 peers[peer_cnt].category = peer->primary_device_type;
296 DBG(LOG_VERBOSE, "\tCategory: [%d]\n", peers[peer_cnt].category);
297 strncpy(peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
298 strncpy(peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
299 peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
300 DBG(LOG_VERBOSE, "\tStatus: [%d]\n", peers[peer_cnt].conn_status);
304 free(peer->mac_address);
305 free(peer->interface_address);
311 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state,
315 struct ug_data *ugd = (struct ug_data *) user_data;
317 device_type_s *peers = NULL;
321 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
325 peers = calloc(MAX_PEER_NUM, sizeof(device_type_s));
327 if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED)
329 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
331 else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED)
333 ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
335 wfd_ug_view_refresh_glitem(ugd->head);
337 if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATED
338 || ugd->wfd_status > WFD_LINK_STATUS_GROUP_OWNER)
347 if (ugd->wfd_status >= WFD_LINK_STATUS_CONNECTED)
349 DBG(LOG_VERBOSE, "getting connected peer..\n");
351 wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb,
353 if (res != WIFI_DIRECT_ERROR_NONE)
356 DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
360 if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND)
362 DBG(LOG_VERBOSE, "Peer is found\n");
363 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
364 wfd_ug_view_refresh_glitem(ugd->head);
366 if (ugd->wfd_status >= WFD_LINK_STATUS_ACTIVATED)
368 DBG(LOG_VERBOSE, "getting discovered peer..\n");
370 wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb,
372 if (res != WIFI_DIRECT_ERROR_NONE)
375 DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
380 wfd_ug_view_free_peers(ugd);
383 ugd->peer_cnt = peer_cnt;
385 wfd_ug_view_update_peers(ugd);
386 DBG(LOG_VERBOSE, "%d peers are updated\n", peer_cnt);
392 void _connection_cb(int error_code,
393 wifi_direct_connection_state_e connection_state,
394 const char *mac_address, void *user_data)
397 DBG(LOG_VERBOSE, "Connection event [%d], error_code [%d]\n",
398 connection_state, error_code);
399 struct ug_data *ugd = (struct ug_data *) user_data;
400 device_type_s *peer = NULL;
404 if (mac_address == NULL)
406 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
409 DBG(LOG_VERBOSE, "Connection event from %s", mac_address);
411 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
414 DBG(LOG_ERROR, "Failed to find peer [mac: %s]\n", mac_address);
418 switch (connection_state)
420 case WIFI_DIRECT_CONNECTION_RSP:
421 DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_RSP\n");
423 if (error_code == WIFI_DIRECT_ERROR_NONE)
425 ugd->wfd_status = WFD_LINK_STATUS_CONNECTED;
426 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
427 res = wifi_direct_is_group_owner(&owner);
428 if (res == WIFI_DIRECT_ERROR_NONE)
431 wfd_ug_view_refresh_button(ugd->scan_btn, FALSE);
436 "Failed to get whether client is group owner. [%d]\n", res);
441 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
442 wifi_direct_start_discovery(FALSE, 0);
445 case WIFI_DIRECT_DISCONNECTION_RSP:
446 case WIFI_DIRECT_DISCONNECTION_IND:
447 case WIFI_DIRECT_DISASSOCIATION_IND:
448 DBG(LOG_VERBOSE, "WIFI_DIRECT_DISCONNECTION_X\n");
449 if (error_code != WIFI_DIRECT_ERROR_NONE)
454 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
456 ugd->wfd_status = WFD_LINK_STATUS_ACTIVATED;
457 ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
459 wfd_ug_view_refresh_button(ugd->scan_btn, TRUE);
460 wifi_direct_start_discovery(FALSE, 0);
461 ugd->wfd_status = WFD_LINK_STATUS_DISCOVERING;
462 ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
463 wfd_ug_view_refresh_glitem(ugd->head);
465 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
466 DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
467 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
469 case WIFI_DIRECT_CONNECTION_REQ:
470 case WIFI_DIRECT_CONNECTION_WPS_REQ:
471 DBG(LOG_VERBOSE, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
478 wfd_ug_view_refresh_glitem(peer->gl_item);
484 int wfd_get_vconf_status(void *data)
487 struct ug_data *ugd = (struct ug_data *) data;
491 res = vconf_get_int("db/wifi_direct/onoff", &ugd->wfd_onoff);
494 DBG(LOG_ERROR, "vconf_get_int is failed\n");
496 DBG(LOG_VERBOSE, "VCONF_WFD_ONOFF : %d\n", ugd->wfd_onoff);
498 dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
499 if (dev_name == NULL)
501 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
502 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
506 ugd->dev_name = strdup(dev_name);
515 int init_wfd_client(void *data)
518 struct ug_data *ugd = (struct ug_data *) data;
520 wifi_direct_state_e wfd_status;
522 res = wifi_direct_initialize();
523 if (res != WIFI_DIRECT_ERROR_NONE)
525 DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
529 res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *) ugd);
531 wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *) ugd);
533 wifi_direct_set_connection_state_changed_cb(_connection_cb,
536 res = wifi_direct_get_state(&wfd_status);
537 if (res != WIFI_DIRECT_ERROR_NONE)
539 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
542 ugd->wfd_status = wfd_status;
543 DBG(LOG_VERBOSE, "WFD link status. [%d]\n", wfd_status);
545 if (wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
547 vconf_set_int("db/wifi_direct/onoff", 1);
552 vconf_set_int("db/wifi_direct/onoff", 0);
555 wfd_ug_view_refresh_glitem(ugd->head);
556 wfd_ug_view_refresh_button(ugd->scan_btn, ugd->wfd_onoff);
558 if(wfd_status >= WIFI_DIRECT_STATE_CONNECTED)
560 device_type_s *peers = NULL;
562 peers = calloc(MAX_PEER_NUM, sizeof(device_type_s));
563 res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void*) peers);
564 if(res != WIFI_DIRECT_ERROR_NONE)
567 DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
569 wfd_ug_view_free_peers(ugd);
572 ugd->peer_cnt = peer_cnt;
574 wfd_ug_view_update_peers(ugd);
575 DBG(LOG_VERBOSE, "%d peers are updated\n", peer_cnt);
578 if (wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
581 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
583 if (wifi_state < VCONFKEY_WIFI_CONNECTED)
585 res = wifi_direct_start_discovery(FALSE, 0);
586 if (res != WIFI_DIRECT_ERROR_NONE)
588 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
590 DBG(LOG_VERBOSE, "Discovery is started\n");
594 wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"),
595 POPUP_TYPE_WIFI_OFF);
604 int deinit_wfd_client(void *data)
608 wifi_direct_state_e status = 0;
610 wifi_direct_get_state(&status);
612 if (status == WIFI_DIRECT_STATE_DISCOVERING)
614 DBG(LOG_VERBOSE, "Stop discovery before deregister client\n");
615 wifi_direct_cancel_discovery();
618 res = wifi_direct_deinitialize();
619 if (res != WIFI_DIRECT_ERROR_NONE)
621 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
624 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
627 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
630 res = net_deregister_client();
631 if (res != NET_ERR_NONE)
633 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
642 int wfd_client_get_link_status()
645 wifi_direct_state_e status;
648 res = wifi_direct_get_state(&status);
649 if (res != WIFI_DIRECT_ERROR_NONE)
651 DBG(LOG_ERROR, "Failed to get link status from wfd-server. [%d]", res);
659 int wfd_client_switch_on(void *data)
662 struct ug_data *ugd = (struct ug_data *) data;
665 DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
667 if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
669 ugd->wfd_status = WFD_LINK_STATUS_ACTIVATING;
672 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
675 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
679 if (wifi_state > VCONFKEY_WIFI_OFF)
681 DBG(LOG_VERBOSE, "WiFi is connected, so have to turn off WiFi");
682 wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"),
683 POPUP_TYPE_WIFI_OFF);
687 res = wifi_direct_activate();
688 if (res != WIFI_DIRECT_ERROR_NONE)
691 "Failed to activate Wi-Fi Direct. error code = [%d]\n",
693 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
695 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
696 wfd_ug_view_refresh_glitem(ugd->head);
703 DBG(LOG_VERBOSE, "Wi-Fi Direct is already activated\n");
710 int wfd_client_switch_off(void *data)
713 struct ug_data *ugd = (struct ug_data *) data;
716 DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
718 if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
720 DBG(LOG_VERBOSE, "Wi-Fi Direct is already deactivated\n");
724 ugd->wfd_status = WFD_LINK_STATUS_DEACTIVATING;
726 res = wifi_direct_deactivate();
727 if (res != WIFI_DIRECT_ERROR_NONE)
730 "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
731 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
733 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
734 wfd_ug_view_refresh_glitem(ugd->head);
743 int wfd_client_swtch_force(void *data, int onoff)
746 struct ug_data *ugd = (struct ug_data*) data;
751 res = wifi_direct_activate();
752 if (res != WIFI_DIRECT_ERROR_NONE)
755 "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
756 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
758 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
759 wfd_ug_view_refresh_glitem(ugd->head);
765 res = wifi_direct_deactivate();
766 if (res != WIFI_DIRECT_ERROR_NONE)
769 "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
770 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
772 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
773 wfd_ug_view_refresh_glitem(ugd->head);
781 int wfd_client_start_discovery(void *data)
785 wifi_direct_state_e status;
787 wifi_direct_get_state(&status);
788 if (status >= WIFI_DIRECT_STATE_ACTIVATED)
790 res = wifi_direct_start_discovery(FALSE, 0);
791 if (res != WIFI_DIRECT_ERROR_NONE)
793 DBG(LOG_ERROR, "Failed to start wfd discovery. [%d]", res);
801 int wfd_client_connect(const char *mac_addr)
806 res = wifi_direct_connect(mac_addr);
807 if (res != WIFI_DIRECT_ERROR_NONE)
809 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
816 int wfd_client_disconnect(const char *mac_addr)
821 if (mac_addr == NULL)
823 res = wifi_direct_disconnect_all();
824 if (res != WIFI_DIRECT_ERROR_NONE)
827 "Failed to send disconnection request to all. [%d]\n", res);
833 res = wifi_direct_disconnect(mac_addr);
834 if (res != WIFI_DIRECT_ERROR_NONE)
836 DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);