4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.tizenopensource.org/license
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include <Elementary.h>
27 //#include <vconf-keys.h>
28 #include <tethering.h>
29 #include <network-cm-intf.h>
30 #include <network-wifi-intf.h>
33 #include "wfd_ug_view.h"
34 #include "wfd_client.h"
37 * This function let the ug make a change callback for wifi state
39 * @param[in] key the pointer to the key
40 * @param[in] data the pointer to the main data structure
42 static void _wifi_state_cb(keynode_t *key, void *data)
45 struct ug_data *ugd = (struct ug_data *)data;
49 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
51 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
55 if (wifi_state == VCONFKEY_WIFI_OFF) {
56 DBG(LOG_VERBOSE, "WiFi is turned off\n");
57 wfd_client_swtch_force(ugd, TRUE);
59 DBG(LOG_VERBOSE, "WiFi is turned on\n");
62 res = net_deregister_client();
63 if (res != NET_ERR_NONE) {
64 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
71 * This function let the ug make a event callback for network registering
73 * @param[in] event_info the pointer to the information of network event
74 * @param[in] user_data the pointer to the user data
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);
84 * This function let the ug turn wifi off
85 * @return If success, return 0, else return -1
86 * @param[in] data the pointer to the main data structure
88 int wfd_wifi_off(void *data)
91 struct ug_data *ugd = (struct ug_data *)data;
94 res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
96 DBG(LOG_ERROR, "Failed to register vconf callback\n");
100 DBG(LOG_VERBOSE, "Vconf key callback is registered\n");
102 res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
103 if (res != NET_ERR_NONE) {
104 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
108 DBG(LOG_VERBOSE, "Network client is registered\n");
110 res = net_wifi_power_off();
111 if (res != NET_ERR_NONE) {
112 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
116 DBG(LOG_VERBOSE, "WiFi power off\n");
123 * This function let the ug make a change callback for enabling hotspot state
125 * @param[in] key the pointer to the key
126 * @param[in] data the pointer to the main data structure
128 static void _enable_hotspot_state_cb(keynode_t *key, void *data)
131 struct ug_data *ugd = (struct ug_data *)data;
134 tethering_error_e ret = TETHERING_ERROR_NONE;
135 tethering_h th = NULL;
137 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
139 DBG(LOG_ERROR, "Failed to get mobile hotspot state from vconf. [%d]\n", res);
143 if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
144 DBG(LOG_VERBOSE, " Mobile hotspot is activated\n");
147 th = ugd->hotspot_handle;
151 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
152 if (ret != TETHERING_ERROR_NONE) {
153 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
156 /* Destroy tethering handle */
157 ret = tethering_destroy(th);
158 if (ret != TETHERING_ERROR_NONE) {
159 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
162 ugd->hotspot_handle = NULL;
169 * This function let the ug make a change callback for disabling hotspot state
171 * @param[in] key the pointer to the key
172 * @param[in] data the pointer to the main data structure
174 static void _disable_hotspot_state_cb(keynode_t *key, void *data)
177 struct ug_data *ugd = (struct ug_data *)data;
180 tethering_error_e ret = TETHERING_ERROR_NONE;
181 tethering_h th = NULL;
183 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
185 DBG(LOG_ERROR, "Failed to get mobile hotspot state from vconf. [%d]\n", res);
189 if (!(hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)) {
190 DBG(LOG_VERBOSE, " Mobile hotspot is deactivated\n");
191 wfd_client_swtch_force(ugd, TRUE);
194 th = ugd->hotspot_handle;
198 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
199 if (ret != TETHERING_ERROR_NONE) {
200 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
203 /* Destroy tethering handle */
204 ret = tethering_destroy(th);
205 if (ret != TETHERING_ERROR_NONE) {
206 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
209 ugd->hotspot_handle = NULL;
216 * This function let the ug make a callback for setting tethering mode enabled
218 * @param[in] error the returned error code
219 * @param[in] type the type of tethering
220 * @param[in] is_requested whether tethering mode is enabled
221 * @param[in] data the pointer to the user data
223 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
227 if (error != TETHERING_ERROR_NONE) {
228 if (is_requested != TRUE) {
232 DBG(LOG_ERROR, "error !!! TETHERING is not enabled.\n");
236 DBG(LOG_VERBOSE, "TETHERING is enabled.\n");
243 * This function let the ug make a callback for setting tethering mode disabled
245 * @param[in] error the returned error code
246 * @param[in] type the type of tethering
247 * @param[in] code whether tethering mode is enabled
248 * @param[in] data the pointer to the user data
250 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
254 if (error != TETHERING_ERROR_NONE) {
255 if (code != TETHERING_DISABLED_BY_REQUEST) {
259 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
263 DBG(LOG_VERBOSE, "TETHERING is disabled.\n");
270 * This function let the ug turn AP on
271 * @return If success, return 0, else return -1
272 * @param[in] data the pointer to the main data structure
274 int wfd_mobile_ap_on(void *data)
277 struct ug_data *ugd = (struct ug_data *)data;
279 tethering_error_e ret = TETHERING_ERROR_NONE;
280 tethering_h th = NULL;
282 res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb, ugd);
284 DBG(LOG_ERROR, "Failed to register vconf callback\n");
288 /* Create tethering handle */
289 ret = tethering_create(&th);
290 if (ret != TETHERING_ERROR_NONE) {
291 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
294 DBG(LOG_VERBOSE, "Succeeded to tethering_create()\n");
298 ret = tethering_set_enabled_cb(th, TETHERING_TYPE_WIFI, __enabled_cb, NULL);
299 if (ret != TETHERING_ERROR_NONE) {
300 DBG(LOG_ERROR, "tethering_set_enabled_cb is failed\n", ret);
304 /* Enable tethering */
305 ret = tethering_enable(th, TETHERING_TYPE_WIFI);
306 if (ret != TETHERING_ERROR_NONE) {
307 DBG(LOG_ERROR, "Failed to turn on mobile hotspot. [%d]\n", ret);
310 DBG(LOG_VERBOSE, "Succeeded to turn on mobile hotspot\n");
313 ugd->hotspot_handle = th;
314 ugd->is_hotspot_off = FALSE;
321 * This function let the ug turn AP off
322 * @return If success, return 0, else return -1
323 * @param[in] data the pointer to the main data structure
325 int wfd_mobile_ap_off(void *data)
328 struct ug_data *ugd = (struct ug_data *)data;
330 tethering_error_e ret = TETHERING_ERROR_NONE;
331 tethering_h th = NULL;
333 res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb, ugd);
335 DBG(LOG_ERROR, "Failed to register vconf callback\n");
339 /* Create tethering handle */
340 ret = tethering_create(&th);
341 if (ret != TETHERING_ERROR_NONE) {
342 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
345 DBG(LOG_VERBOSE, "Succeeded to tethering_create()\n");
349 ret = tethering_set_disabled_cb(th, TETHERING_TYPE_WIFI, __disabled_cb, NULL);
350 if (ret != TETHERING_ERROR_NONE) {
351 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
355 /* Disable tethering */
356 ret = tethering_disable(th, TETHERING_TYPE_WIFI);
357 if (ret != TETHERING_ERROR_NONE) {
358 DBG(LOG_ERROR, "Failed to turn off mobile hotspot. [%d]\n", ret);
361 DBG(LOG_VERBOSE, "Succeeded to turn off mobile hotspot\n");
364 ugd->hotspot_handle = th;
365 ugd->is_hotspot_off = TRUE;
372 * This function let the ug find the peer by mac address
373 * @return the found peer
374 * @param[in] data the pointer to the main data structure
375 * @param[in] mac_addr the pointer to mac address
377 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
380 struct ug_data *ugd = (struct ug_data *)data;
384 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
388 if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) {
389 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
390 DBG(LOG_VERBOSE, "[Multi Connect] check %dth peer\n", i);
391 if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH)) {
392 DBG(LOG_VERBOSE, "selected found peer. [%d]\n", i);
394 return &ugd->raw_multi_selected_peers[i];
398 for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) {
399 DBG(LOG_VERBOSE, "check %dth peer\n", i);
400 if (!strncmp(mac_addr, (const char *)ugd->raw_discovered_peers[i].mac_addr, MAC_LENGTH)) {
401 DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
403 return &ugd->raw_discovered_peers[i];
413 * This function let the ug make a callback for registering activation event
415 * @param[in] error_code the returned error code
416 * @param[in] device_state the state of device
417 * @param[in] user_data the pointer to the main data structure
419 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
423 struct ug_data *ugd = (struct ug_data *)user_data;
425 wfd_refresh_wifi_direct_state(ugd);
427 switch (device_state) {
428 case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
429 DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
430 if (error_code != WIFI_DIRECT_ERROR_NONE) {
431 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
432 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL);
434 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
436 wfd_ug_view_refresh_glitem(ugd->head);
440 ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
442 wfd_ug_view_refresh_glitem(ugd->head);
444 wfg_ug_act_popup_remove(ugd);
446 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
448 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
451 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb);
453 DBG(LOG_ERROR, "Failed to ignore vconf key callback for hotspot state\n");
456 res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
457 if (res != WIFI_DIRECT_ERROR_NONE) {
458 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
459 ugd->is_re_discover = TRUE;
460 wifi_direct_cancel_discovery();
462 DBG(LOG_VERBOSE, "Discovery is started\n");
463 ugd->is_re_discover = FALSE;
467 case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
468 DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
469 if (error_code != WIFI_DIRECT_ERROR_NONE) {
470 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
471 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL);
472 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
474 wfd_ug_view_refresh_glitem(ugd->head);
478 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
482 * when deactivated, clear all the
483 * discovered peers and connected peers
485 if (ugd->raw_discovered_peer_cnt > 0) {
486 memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s));
489 if (ugd->raw_connected_peer_cnt > 0) {
490 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
493 ugd->raw_discovered_peer_cnt = 0;
494 ugd->raw_connected_peer_cnt = 0;
496 wfd_ug_view_update_peers(ugd);
498 /* remove the callback for hotspot */
499 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb);
501 DBG(LOG_ERROR, "Failed to ignore vconf key callback for hotspot state\n");
504 /* when deactivated, stop the timer */
505 if (ugd->monitor_timer) {
506 ecore_timer_del(ugd->monitor_timer);
507 ugd->monitor_timer = NULL;
514 wfd_ug_view_refresh_glitem(ugd->head);
517 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
520 if (ugd->multi_connect_btn) {
521 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
525 elm_object_disabled_set(ugd->back_btn, FALSE);
533 * This function let the ug make a callback for discovering peer
535 * @param[in] peer the pointer to the discovered peer
536 * @param[in] user_data the pointer to the main data structure
538 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
541 if (NULL == peer || NULL == user_data) {
542 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
547 struct ug_data *ugd = (struct ug_data *)user_data;
548 int peer_cnt = ugd->raw_discovered_peer_cnt;
550 DBG(LOG_VERBOSE, "%dth discovered peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address);
552 strncpy(ugd->raw_discovered_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_discovered_peers[peer_cnt].ssid));
553 ugd->raw_discovered_peers[peer_cnt].category = peer->primary_device_type;
554 strncpy(ugd->raw_discovered_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
555 strncpy(ugd->raw_discovered_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
556 ugd->raw_discovered_peers[peer_cnt].is_group_owner = peer->is_group_owner;
557 ugd->raw_discovered_peers[peer_cnt].is_persistent_group_owner = peer->is_persistent_group_owner;
558 ugd->raw_discovered_peers[peer_cnt].is_connected = peer->is_connected;
560 if (TRUE == peer->is_connected) {
561 ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
563 ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED;
566 DBG(LOG_VERBOSE, "\tSSID: [%s]\n", ugd->raw_discovered_peers[peer_cnt].ssid);
567 DBG(LOG_VERBOSE, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, ugd->raw_discovered_peers[peer_cnt].category);
568 DBG(LOG_VERBOSE, "\tStatus: [%d]\n", ugd->raw_discovered_peers[peer_cnt].conn_status);
570 ugd->raw_discovered_peer_cnt++;
572 free(peer->device_name);
573 free(peer->mac_address);
574 free(peer->interface_address);
582 * This function let the ug make a callback for connected peer
584 * @param[in] peer the pointer to the connected peer
585 * @param[in] user_data the pointer to the main data structure
587 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
590 if (NULL == peer || NULL == user_data) {
591 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
596 struct ug_data *ugd = (struct ug_data *)user_data;
597 int peer_cnt = ugd->raw_connected_peer_cnt;
599 DBG(LOG_VERBOSE, "%dth connected peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address);
601 strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid));
602 ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
603 strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
604 strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
605 ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
607 DBG(LOG_VERBOSE, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
608 DBG(LOG_VERBOSE, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
609 DBG(LOG_VERBOSE, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
611 ugd->raw_connected_peer_cnt++;
613 free(peer->device_name);
614 free(peer->mac_address);
615 free(peer->interface_address);
623 * This function let the ug get the found peers
624 * @return If success, return 0, else return -1
625 * @param[in] ugd the pointer to the main data structure
627 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
636 ugd->raw_discovered_peer_cnt = 0;
637 res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
638 if (res != WIFI_DIRECT_ERROR_NONE) {
639 ugd->raw_discovered_peer_cnt = 0;
640 DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
648 * This function let the ug get the connected peers
649 * @return If success, return 0, else return -1
650 * @param[in] ugd the pointer to the main data structure
652 int wfd_ug_get_connected_peers(struct ug_data *ugd)
661 ugd->raw_connected_peer_cnt = 0;
662 res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
663 if (res != WIFI_DIRECT_ERROR_NONE) {
664 ugd->raw_connected_peer_cnt = 0;
665 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
673 * This function let the ug make a callback for deactivating wfd automatically
674 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
675 * @param[in] user_data the pointer to the main data structure
677 static Eina_Bool _wfd_automatic_deactivated_for_no_connection_cb(void *user_data)
681 struct ug_data *ugd = (struct ug_data *)user_data;
684 DBG(LOG_ERROR, "NULL parameters.\n");
685 return ECORE_CALLBACK_CANCEL;
688 /* check the action, if action is exist, keep the cb */
689 res = wifi_direct_get_state(&ugd->wfd_status);
690 if (res != WIFI_DIRECT_ERROR_NONE) {
691 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
692 return ECORE_CALLBACK_CANCEL;
695 if (ugd->last_wfd_status != ugd->wfd_status) {
696 DBG(LOG_ERROR, "Action is exist, last status: %d\n",
697 ugd->last_wfd_status);
698 ugd->last_wfd_status = ugd->wfd_status;
699 ugd->last_wfd_time = time(NULL);
700 return ECORE_CALLBACK_RENEW;
703 /* check the timeout, if not timeout, keep the cb */
704 interval = time(NULL) - ugd->last_wfd_time;
705 if (interval < MAX_NO_ACTION_TIME_OUT) {
706 return ECORE_CALLBACK_RENEW;
709 /* turn off the Wi-Fi Direct */
710 wifi_direct_get_state(&ugd->wfd_status);
711 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
712 DBG(LOG_ERROR, "Wi-Fi Direct is already deactivated\n");
714 wfd_ug_warn_popup(ugd, IDS_WFD_POP_AUTOMATIC_TURN_OFF, POP_TYPE_AUTOMATIC_TURN_OFF);
717 return ECORE_CALLBACK_CANCEL;
721 * This function let the ug make a callback for registering discover event
723 * @param[in] error_code the returned error code
724 * @param[in] discovery_state the state of discover
725 * @param[in] user_data the pointer to the main data structure
727 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
730 struct ug_data *ugd = (struct ug_data *)user_data;
733 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
737 DBG(LOG_VERBOSE, "Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
739 if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED) {
742 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
743 ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
745 /* clear all the previous discovered peers */
746 if (ugd->raw_discovered_peer_cnt > 0) {
747 memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s));
750 ugd->raw_discovered_peer_cnt = 0;
751 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
752 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
753 wfd_ug_get_discovered_peers(ugd);
755 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
757 if (TRUE == ugd->is_re_discover) {
758 ugd->is_re_discover = FALSE;
759 wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
761 /* start LISTEN ONLY mode */
762 wifi_direct_start_discovery(TRUE, 0);
766 wfd_ug_view_refresh_glitem(ugd->head);
767 wfd_ug_view_update_peers(ugd);
768 wfd_update_multiconnect_device(ugd);
770 if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state) {
772 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
775 if (ugd->multi_connect_btn) {
776 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
780 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
783 if (ugd->multi_connect_btn) {
784 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
793 * This function let the ug make a callback for registering connection event
795 * @param[in] error_code the returned error code
796 * @param[in] connection_state the state of connection
797 * @param[in] mac_address the mac address of peer
798 * @param[in] user_data the pointer to the main data structure
800 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
803 struct ug_data *ugd = (struct ug_data *)user_data;
804 device_type_s *peer = NULL;
808 DBG(LOG_VERBOSE, "Connection event [%d], error_code [%d], multi_connect_mode [%d]\n",
809 connection_state, error_code, ugd->multi_connect_mode);
811 if (mac_address == NULL) {
812 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
816 /* when not in connection, mac_address is empty */
817 if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
818 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
820 if (NULL == peer || '\0' == peer->ssid[0]) {
821 DBG(LOG_ERROR, "invalid peer from connection !!\n");
826 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
827 switch (connection_state) {
828 case WIFI_DIRECT_CONNECTION_RSP:
829 DBG(LOG_VERBOSE, "MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
831 if (error_code == WIFI_DIRECT_ERROR_NONE) {
832 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
833 wfd_ug_get_connected_peers(ugd);
835 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
838 wfd_ug_view_update_peers(ugd);
840 /* connect the next peer */
841 ugd->g_source_multi_connect_next = g_timeout_add(1000, wfd_multi_connect_next_cb, ugd);
843 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
844 DBG(LOG_VERBOSE, "MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
845 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
846 wfd_ug_view_update_peers(ugd);
848 case WIFI_DIRECT_GROUP_CREATED:
849 DBG(LOG_VERBOSE, "MULTI: WIFI_DIRECT_GROUP_CREATED\n");
850 wfd_multi_connect_next_cb(ugd);
856 switch (connection_state) {
857 case WIFI_DIRECT_CONNECTION_RSP:
858 DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_RSP\n");
860 if (error_code == WIFI_DIRECT_ERROR_NONE) {
861 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
862 wfd_ug_get_connected_peers(ugd);
864 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
867 wfd_ug_view_update_peers(ugd);
869 case WIFI_DIRECT_DISASSOCIATION_IND:
870 DBG(LOG_VERBOSE, "WIFI_DIRECT_DISASSOCIATION_IND\n");
871 /* change the multi connection mode, it can be connected now */
872 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
873 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS;
876 /* if other peer disconnected, get connected peers and update */
877 peer->conn_status = PEER_CONN_STATUS_WAIT_FOR_CONNECT;
878 wfd_ug_get_connected_peers(ugd);
879 wfd_ug_view_update_peers(ugd);
881 case WIFI_DIRECT_DISCONNECTION_RSP:
882 case WIFI_DIRECT_DISCONNECTION_IND:
883 DBG(LOG_VERBOSE, "WIFI_DIRECT_DISCONNECTION_X\n");
885 /* when disconnection, clear all the connected peers */
886 if (ugd->raw_connected_peer_cnt > 0) {
887 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
890 ugd->raw_connected_peer_cnt = 0;
892 /* start discovery again */
893 res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
894 if (res != WIFI_DIRECT_ERROR_NONE) {
895 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
896 ugd->is_re_discover = TRUE;
897 wifi_direct_cancel_discovery();
899 DBG(LOG_VERBOSE, "Discovery is started\n");
900 ugd->is_re_discover = FALSE;
904 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
905 DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
906 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
907 wfd_ug_view_update_peers(ugd);
909 case WIFI_DIRECT_CONNECTION_REQ:
910 case WIFI_DIRECT_CONNECTION_WPS_REQ:
911 DBG(LOG_VERBOSE, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
919 wfd_ug_view_refresh_glitem(peer->gl_item);
922 _change_multi_button_title(ugd);
925 /* refresh the scan button */
926 wfd_refresh_wifi_direct_state(ugd);
927 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
928 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
929 res = wifi_direct_is_group_owner(&owner);
930 if (res == WIFI_DIRECT_ERROR_NONE) {
933 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
936 if (ugd->multi_connect_btn) {
937 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
941 DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
945 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
948 if (ugd->multi_connect_btn) {
949 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
953 /* if no connection, start the monitor timer */
954 wifi_direct_get_state(&ugd->wfd_status);
955 DBG(LOG_VERBOSE, "status: %d", ugd->wfd_status);
957 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
958 if (ugd->monitor_timer) {
959 ecore_timer_del(ugd->monitor_timer);
960 ugd->monitor_timer = NULL;
963 if (NULL == ugd->monitor_timer) {
964 DBG(LOG_VERBOSE, "start the monitor timer\n");
965 ugd->last_wfd_time = time(NULL);
966 ugd->monitor_timer = ecore_timer_add(5.0,
967 (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
976 * This function let the ug get wi-fi direct status from vconf
977 * @return If success, return 0, else return -1
978 * @param[in] data the pointer to the main data structure
980 int wfd_get_vconf_status(void *data)
983 struct ug_data *ugd = (struct ug_data *)data;
985 int wifi_direct_state = 0;
987 /* get wifi direct status from vconf */
988 if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
989 DBG(LOG_ERROR, "Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
993 ugd->wfd_status = wifi_direct_state;
995 /* get device name from vconf */
996 dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
997 if (dev_name == NULL) {
998 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
999 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
1001 ugd->dev_name = strdup(dev_name);
1010 * This function let the ug refresh current status of wi-fi direct
1011 * @return If success, return 0, else return -1
1012 * @param[in] data the pointer to the main data structure
1014 int wfd_refresh_wifi_direct_state(void *data)
1017 struct ug_data *ugd = (struct ug_data *)data;
1019 wifi_direct_state_e wfd_status;
1021 res = wifi_direct_get_state(&wfd_status);
1022 if (res != WIFI_DIRECT_ERROR_NONE) {
1023 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
1027 DBG(LOG_VERBOSE, "WFD status [%d]", wfd_status);
1028 ugd->wfd_status = wfd_status;
1035 * This function let the ug do initialization
1036 * @return If success, return 0, else return -1
1037 * @param[in] data the pointer to the main data structure
1039 int init_wfd_client(void *data)
1042 struct ug_data *ugd = (struct ug_data *)data;
1045 res = wifi_direct_initialize();
1046 if (res != WIFI_DIRECT_ERROR_NONE) {
1047 DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
1051 res = wifi_direct_initialize();
1052 if (res != WIFI_DIRECT_ERROR_NONE) {
1053 DBG(LOG_ERROR, "Failed to initialize Wi-Fi Direct. error code = [%d]\n", res);
1057 res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1058 if (res != WIFI_DIRECT_ERROR_NONE) {
1059 DBG(LOG_ERROR, "Failed to register _cb_activation. error code = [%d]\n", res);
1063 res = wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *)ugd);
1064 if (res != WIFI_DIRECT_ERROR_NONE) {
1065 DBG(LOG_ERROR, "Failed to register _cb_discover. error code = [%d]\n", res);
1069 res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1070 if (res != WIFI_DIRECT_ERROR_NONE) {
1071 DBG(LOG_ERROR, "Failed to register _cb_connection. error code = [%d]\n", res);
1075 /* update WFD status */
1076 wfd_refresh_wifi_direct_state(ugd);
1077 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1083 DBG(LOG_VERBOSE, "WFD link status. [%d]\n", ugd->wfd_status);
1085 /* start the monitor timer */
1086 ugd->last_wfd_time = time(NULL);
1087 ugd->last_wfd_status = WIFI_DIRECT_STATE_DEACTIVATED;
1088 ugd->monitor_timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
1090 ugd->is_re_discover = FALSE;
1097 * This function let the ug do de-initialization
1098 * @return If success, return 0, else return -1
1099 * @param[in] data the pointer to the main data structure
1101 int deinit_wfd_client(void *data)
1104 struct ug_data *ugd = (struct ug_data *)data;
1106 tethering_error_e ret = TETHERING_ERROR_NONE;
1107 tethering_h th = NULL;
1109 wfd_refresh_wifi_direct_state(ugd);
1111 if (ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1112 DBG(LOG_VERBOSE, "Stop discovery before deregister client\n");
1113 wifi_direct_cancel_discovery();
1116 res = wifi_direct_deinitialize();
1117 if (res != WIFI_DIRECT_ERROR_NONE) {
1118 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
1121 /* release monitor timer */
1122 if (ugd->monitor_timer) {
1123 ecore_timer_del(ugd->monitor_timer);
1124 ugd->monitor_timer = NULL;
1127 /* release vconf, hotspot.. */
1128 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1130 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
1133 res = net_deregister_client();
1134 if (res != NET_ERR_NONE) {
1135 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
1138 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb);
1140 DBG(LOG_ERROR, "Failed to ignore vconf key callback for hotspot state\n");
1143 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb);
1145 DBG(LOG_ERROR, "Failed to ignore vconf key callback for hotspot state\n");
1148 th = ugd->hotspot_handle;
1151 /* Deregister cbs */
1152 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
1153 if (ret != TETHERING_ERROR_NONE) {
1154 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
1157 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
1158 if (ret != TETHERING_ERROR_NONE) {
1159 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1162 /* Destroy tethering handle */
1163 ret = tethering_destroy(th);
1164 if (ret != TETHERING_ERROR_NONE) {
1165 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
1168 ugd->hotspot_handle = NULL;
1176 * This function let the ug turn wi-fi direct on
1177 * @return If success, return 0, else return -1
1178 * @param[in] data the pointer to the main data structure
1180 int wfd_client_switch_on(void *data)
1183 struct ug_data *ugd = (struct ug_data *)data;
1186 wfd_refresh_wifi_direct_state(ugd);
1187 DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
1189 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1191 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1193 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
1198 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
1200 DBG(LOG_ERROR, "Failed to get mobile hotspot state from vconf. [%d]\n", res);
1204 if (wifi_state > VCONFKEY_WIFI_OFF) {
1205 DBG(LOG_VERBOSE, "WiFi is connected, so have to turn off WiFi");
1206 wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"), POPUP_TYPE_WIFI_OFF);
1207 } else if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
1208 DBG(LOG_VERBOSE, "WiFi is connected, so have to turn off WiFi");
1209 wfd_ug_act_popup(ugd, _("IDS_WFD_POP_HOTSPOT_OFF"), POPUP_TYPE_HOTSPOT_OFF);
1211 res = wifi_direct_activate();
1212 if (res != WIFI_DIRECT_ERROR_NONE) {
1213 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1214 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1216 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1217 wfd_ug_view_refresh_glitem(ugd->head);
1221 /* refresh the header */
1222 ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING;
1223 wfd_ug_view_refresh_glitem(ugd->head);
1225 /* while activating, disable the buttons */
1226 if (ugd->scan_btn) {
1227 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1230 if (ugd->multi_scan_btn) {
1231 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1234 if (ugd->back_btn) {
1235 elm_object_disabled_set(ugd->back_btn, TRUE);
1239 DBG(LOG_VERBOSE, "Wi-Fi Direct is already activated\n");
1247 * This function let the ug turn wi-fi direct off
1248 * @return If success, return 0, else return -1
1249 * @param[in] data the pointer to the main data structure
1251 int wfd_client_switch_off(void *data)
1254 struct ug_data *ugd = (struct ug_data *)data;
1257 wfd_refresh_wifi_direct_state(ugd);
1258 DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
1260 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1261 DBG(LOG_VERBOSE, "Wi-Fi Direct is already deactivated\n");
1263 /*if connected, disconnect all devices*/
1264 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1265 res = wifi_direct_disconnect_all();
1266 if (res != WIFI_DIRECT_ERROR_NONE) {
1267 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1272 res = wifi_direct_deactivate();
1273 if (res != WIFI_DIRECT_ERROR_NONE) {
1274 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1275 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1277 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1278 wfd_ug_view_refresh_glitem(ugd->head);
1282 /* refresh the header */
1283 ugd->head_text_mode = HEAD_TEXT_TYPE_DEACTIVATING;
1284 wfd_ug_view_refresh_glitem(ugd->head);
1286 /* while deactivating, disable the buttons */
1287 if (ugd->scan_btn) {
1288 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1291 if (ugd->multi_scan_btn) {
1292 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1295 if (ugd->back_btn) {
1296 elm_object_disabled_set(ugd->back_btn, TRUE);
1305 * This function let the ug turn wi-fi direct on/off forcely
1306 * @return If success, return 0, else return -1
1307 * @param[in] data the pointer to the main data structure
1308 * @param[in] onoff whether to turn on/off wi-fi direct
1310 int wfd_client_swtch_force(void *data, int onoff)
1313 struct ug_data *ugd = (struct ug_data *)data;
1317 res = wifi_direct_activate();
1318 if (res != WIFI_DIRECT_ERROR_NONE) {
1319 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1320 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1322 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1323 wfd_ug_view_refresh_glitem(ugd->head);
1327 res = wifi_direct_deactivate();
1328 if (res != WIFI_DIRECT_ERROR_NONE) {
1329 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1330 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1332 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1333 wfd_ug_view_refresh_glitem(ugd->head);
1343 * This function let the ug create a group
1344 * @return If success, return 0, else return -1
1346 int wfd_client_group_add()
1351 res = wifi_direct_create_group();
1352 if (res != WIFI_DIRECT_ERROR_NONE) {
1353 DBG(LOG_ERROR, "Failed to add group");
1363 * This function let the ug connect to the device by mac address
1364 * @return If success, return 0, else return -1
1365 * @param[in] mac_addr the pointer to the mac address of device
1367 int wfd_client_connect(const char *mac_addr)
1372 DBG(LOG_ERROR, "connect to peer=[%s]\n", mac_addr);
1373 res = wifi_direct_connect(mac_addr);
1374 if (res != WIFI_DIRECT_ERROR_NONE) {
1375 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
1384 * This function let the ug disconnect to the device by mac address
1385 * @return If success, return 0, else return -1
1386 * @param[in] mac_addr the pointer to the mac address of device
1388 int wfd_client_disconnect(const char *mac_addr)
1393 if (mac_addr == NULL) {
1394 res = wifi_direct_disconnect_all();
1395 if (res != WIFI_DIRECT_ERROR_NONE) {
1396 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1400 res = wifi_direct_disconnect(mac_addr);
1401 if (res != WIFI_DIRECT_ERROR_NONE) {
1402 DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
1412 * This function let the ug set the intent of a group owner
1413 * @return If success, return 0, else return -1
1414 * @param[in] go_intent the intent parameter
1416 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1421 res = wifi_direct_set_group_owner_intent(go_intent);
1422 if (res != WIFI_DIRECT_ERROR_NONE) {
1423 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);