4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (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>
26 #include <vconf-keys.h>
28 #include <tethering.h>
30 #include <network-cm-intf.h>
31 #include <network-wifi-intf.h>
34 #include "wfd_ug_view.h"
35 #include "wfd_client.h"
37 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data);
39 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
41 * This function let the ug make a change callback for wifi state
43 * @param[in] key the pointer to the key
44 * @param[in] data the pointer to the main data structure
46 static void _wifi_state_cb(keynode_t *key, void *data)
49 struct ug_data *ugd = (struct ug_data *)data;
53 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
55 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
59 if (wifi_state == VCONFKEY_WIFI_OFF) {
60 DBG(LOG_INFO, "WiFi is turned off\n");
61 wfd_client_swtch_force(ugd, TRUE);
63 DBG(LOG_INFO, "WiFi is turned on\n");
66 res = net_deregister_client();
67 if (res != NET_ERR_NONE)
68 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
74 * This function let the ug make a event callback for network registering
76 * @param[in] event_info the pointer to the information of network event
77 * @param[in] user_data the pointer to the user data
79 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
82 DBG(LOG_INFO, "Event from network. [%d]\n", event_info->Event);
87 * This function let the ug turn wifi off
88 * @return If success, return 0, else return -1
89 * @param[in] data the pointer to the main data structure
91 int wfd_wifi_off(void *data)
94 struct ug_data *ugd = (struct ug_data *)data;
97 res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
99 DBG(LOG_ERROR, "Failed to register vconf callback\n");
103 DBG(LOG_INFO, "Vconf key callback is registered\n");
105 res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
106 if (res != NET_ERR_NONE) {
107 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
111 DBG(LOG_INFO, "Network client is registered\n");
113 res = net_wifi_power_off();
114 if (res != NET_ERR_NONE) {
115 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
119 DBG(LOG_INFO, "WiFi power off\n");
124 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
128 * This function let the ug make a callback for setting tethering mode enabled
130 * @param[in] error the returned error code
131 * @param[in] type the type of tethering
132 * @param[in] is_requested whether tethering mode is enabled
133 * @param[in] data the pointer to the user data
135 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
138 struct ug_data *ugd = (struct ug_data *)data;
139 tethering_error_e ret = TETHERING_ERROR_NONE;
140 tethering_h th = NULL;
141 bool is_wifi_enabled = false;
143 if (error != TETHERING_ERROR_NONE) {
144 if (is_requested != TRUE)
147 DBG(LOG_ERROR, "error !!! TETHERING is not enabled.\n");
151 th = ugd->hotspot_handle;
153 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
155 DBG(LOG_INFO, "Mobile hotspot is activated\n");
158 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
159 if (ret != TETHERING_ERROR_NONE)
160 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
162 /* Destroy tethering handle */
163 ret = tethering_destroy(th);
164 if (ret != TETHERING_ERROR_NONE)
165 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
167 ugd->hotspot_handle = NULL;
170 DBG(LOG_INFO, "TETHERING is enabled.\n");
177 * This function let the ug make a callback for setting tethering mode disabled
179 * @param[in] error the returned error code
180 * @param[in] type the type of tethering
181 * @param[in] code whether tethering mode is enabled
182 * @param[in] data the pointer to the user data
184 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
188 struct ug_data *ugd = (struct ug_data *)data;
189 tethering_error_e ret = TETHERING_ERROR_NONE;
190 tethering_h th = NULL;
191 bool is_wifi_enabled = false;
193 if (error != TETHERING_ERROR_NONE) {
194 if (code != TETHERING_DISABLED_BY_REQUEST)
197 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
201 th = ugd->hotspot_handle;
203 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
204 if (is_wifi_enabled) {
205 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
209 DBG(LOG_INFO, "Mobile hotspot is deactivated\n");
210 wfd_client_swtch_force(ugd, TRUE);
212 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
213 if (ret != TETHERING_ERROR_NONE)
214 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
216 /* Destroy tethering handle */
217 ret = tethering_destroy(th);
218 if (ret != TETHERING_ERROR_NONE)
219 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
221 ugd->hotspot_handle = NULL;
224 DBG(LOG_INFO, "TETHERING is disabled.\n");
231 * This function let the ug turn AP on
232 * @return If success, return 0, else return -1
233 * @param[in] data the pointer to the main data structure
235 int wfd_mobile_ap_on(void *data)
238 struct ug_data *ugd = (struct ug_data *)data;
239 tethering_error_e ret = TETHERING_ERROR_NONE;
240 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
242 if (NULL == ugd->hotspot_handle) {
243 ret = tethering_create(&(ugd->hotspot_handle));
244 if (TETHERING_ERROR_NONE != ret) {
245 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
246 ugd->hotspot_handle = NULL;
249 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
252 ret = tethering_set_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __enabled_cb, ugd);
253 if (ret != TETHERING_ERROR_NONE) {
254 DBG(LOG_ERROR, "tethering_set_enabled_cb is failed\n", ret);
258 /* Enable tethering */
259 ret = tethering_enable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
260 if (ret != TETHERING_ERROR_NONE) {
261 DBG(LOG_ERROR, "Failed to turn on mobile hotspot. [%d]\n", ret);
264 DBG(LOG_INFO, "Succeeded to turn on mobile hotspot\n");
267 ugd->is_hotspot_off = FALSE;
274 * This function let the ug turn AP off
275 * @return If success, return 0, else return -1
276 * @param[in] data the pointer to the main data structure
278 int wfd_mobile_ap_off(void *data)
281 struct ug_data *ugd = (struct ug_data *)data;
282 WFD_RETV_IF(ugd == NULL || ugd->hotspot_handle == NULL, -1, "Incorrect parameter(NULL)\n");
283 tethering_error_e ret = TETHERING_ERROR_NONE;
284 bool is_wifi_enabled = false;
286 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
288 if (is_wifi_enabled) {
290 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __disabled_cb, ugd);
291 if (ret != TETHERING_ERROR_NONE) {
292 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
295 /* Disable tethering */
296 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
299 if (ret != TETHERING_ERROR_NONE) {
300 DBG(LOG_ERROR, "Failed to turn off mobile hotspot. [%d]\n", ret);
303 DBG(LOG_INFO, "Succeeded to turn off mobile hotspot\n");
306 ugd->is_hotspot_off = TRUE;
312 void wfd_client_free_raw_discovered_peers(struct ug_data *ugd)
315 WFD_RET_IF(ugd->raw_discovered_peer_list == NULL, "Incorrect parameter(NULL)\n");
317 g_list_free(ugd->raw_discovered_peer_list);
318 ugd->raw_discovered_peer_list = NULL;
324 * This function let the ug find the peer by mac address
325 * @return the found peer
326 * @param[in] data the pointer to the main data structure
327 * @param[in] mac_addr the pointer to mac address
329 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
332 struct ug_data *ugd = (struct ug_data *)data;
333 wifi_direct_discovered_peer_info_s *peer_info = NULL;
334 GList *iterator = NULL;
336 WFD_RETV_IF(ugd == NULL, NULL, "Incorrect parameter(NULL)\n");
338 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
339 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
340 if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH))
341 return &ugd->raw_multi_selected_peers[i];
344 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
345 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
346 return (device_type_s *)iterator->data;
351 * In case, device is not in raw discovered list, then get peer info.
352 * There could be situation in which device is not yet discovered and
353 * connected process started.
355 if (WIFI_DIRECT_ERROR_NONE != wifi_direct_get_peer_info((char *)mac_addr, &peer_info) ||
357 DBG(LOG_ERROR, "Peer Not Found !!!");
361 /* Update peer list */
362 DBG(LOG_INFO, "Update Peer info");
363 _wfd_discoverd_peer_cb(peer_info, (void *)ugd);
365 /* Get the device from peer list */
366 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
367 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
368 return (device_type_s *)iterator->data;
376 * This function let the ug make a callback for registering activation event
378 * @param[in] error_code the returned error code
379 * @param[in] device_state the state of device
380 * @param[in] user_data the pointer to the main data structure
382 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
386 struct ug_data *ugd = (struct ug_data *)user_data;
387 wfd_refresh_wifi_direct_state(ugd);
389 switch (device_state) {
390 case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
391 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
392 if (ugd->scan_toolbar == NULL)
393 scan_button_create(ugd);
395 if (error_code != WIFI_DIRECT_ERROR_NONE) {
396 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
397 if (WIFI_DIRECT_ERROR_AUTH_FAILED == error_code)
398 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_SECURITY_POLICY_RESTRICTS_USE_OF_WI_FI"), POPUP_TYPE_ACTIVATE_FAIL_POLICY_RESTRICTS);
400 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_ACTIVATE_FAIL);
402 #ifdef WFD_ON_OFF_GENLIST
404 wfd_ug_refresh_on_off_check(ugd);
409 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
410 #ifdef WFD_ON_OFF_GENLIST
412 wfd_ug_refresh_on_off_check(ugd);
414 wfg_ug_act_popup_remove(ugd);
416 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
417 DBG(LOG_INFO, "Background mode\n");
421 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
422 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
424 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
425 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
427 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
428 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
429 if (res != WIFI_DIRECT_ERROR_NONE) {
430 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
431 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
432 wifi_direct_cancel_discovery();
436 case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
437 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
438 if (error_code != WIFI_DIRECT_ERROR_NONE) {
439 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
440 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_DEACTIVATE_FAIL);
441 #ifdef WFD_ON_OFF_GENLIST
443 wfd_ug_refresh_on_off_check(ugd);
448 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
451 ctxpopup_dismissed_cb(ugd, NULL, NULL);
454 * When multi-connect is on ongoing and deactivte happened destroy
457 if (ugd->disconnect_btn) {
458 Evas_Object *content;
459 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
460 WFD_IF_DEL_OBJ(content);
461 ugd->disconnect_btn = NULL;
462 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
465 /* When connect is on ongoing and deactivte happened refresh scan */
466 if (ugd->scan_toolbar) {
467 wfd_ug_view_refresh_button(ugd->scan_toolbar,
468 "IDS_WIFI_SK4_SCAN", FALSE);
470 /* Delete pop-up when deactivate happens */
471 WFD_IF_DEL_OBJ(ugd->act_popup);
472 /* Remove timeout handlers */
473 if (ugd->timer_stop_progress_bar > 0)
474 g_source_remove(ugd->timer_stop_progress_bar);
476 if (ugd->timer_delete_not_alive_peer > 0)
477 g_source_remove(ugd->timer_delete_not_alive_peer);
479 if (ugd->g_source_multi_connect_next > 0)
480 g_source_remove(ugd->g_source_multi_connect_next);
482 if (ugd->timer_multi_reset > 0)
483 g_source_remove(ugd->timer_multi_reset);
485 /* Delete warn popups for Airplane mode */
486 if (NULL != ugd->warn_popup) {
487 evas_object_del(ugd->warn_popup);
488 ugd->warn_popup = NULL;
491 #ifdef WFD_ON_OFF_GENLIST
493 wfd_ug_refresh_on_off_check(ugd);
496 * when deactivated, clear all the
497 * discovered peers and connected peers
499 wfd_client_free_raw_discovered_peers(ugd);
500 if (ugd->raw_connected_peer_cnt > 0)
501 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
503 ugd->raw_discovered_peer_cnt = 0;
504 ugd->raw_connected_peer_cnt = 0;
506 wfd_free_nodivice_item(ugd);
507 wfd_ug_view_init_genlist(ugd, true);
509 if (ugd->multi_navi_item != NULL)
510 elm_naviframe_item_pop(ugd->naviframe);
512 if (TRUE == ugd->is_hotspot_off && TRUE == ugd->is_hotspot_locally_disabled) {
513 if (0 == wfd_mobile_ap_on(ugd))
514 ugd->is_hotspot_locally_disabled = FALSE;
517 if (ugd->scan_toolbar) {
518 evas_object_del(ugd->scan_toolbar);
519 ugd->scan_toolbar = NULL;
526 /*if (ugd->scan_toolbar)
527 wfd_ug_view_refresh_button(ugd->scan_toolbar, D_("IDS_WIFI_SK4_SCAN"), TRUE);
530 if (ugd->multiconn_scan_stop_btn)
531 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
534 elm_object_disabled_set(ugd->back_btn, FALSE);
541 * This function let the ug make a callback for discovering peer
543 * @param[in] peer the pointer to the discovered peer
544 * @param[in] user_data the pointer to the main data structure
546 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
549 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
551 struct ug_data *ugd = (struct ug_data *)user_data;
552 int peer_cnt = ugd->raw_discovered_peer_cnt;
553 device_type_s *peer_tmp = g_new(device_type_s, 1);
556 DBG_SECURE(LOG_INFO, "%dth discovered peer. [%s] ["MACSECSTR"]\n", peer_cnt,
557 peer->device_name, MAC2SECSTR(peer->mac_address));
559 if (ugd->device_filter < 0 || peer->primary_device_type == ugd->device_filter) {
560 strncpy(peer_tmp->ssid, peer->device_name, sizeof(peer_tmp->ssid) - 1);
561 peer_tmp->ssid[SSID_LENGTH - 1] = '\0';
562 peer_tmp->category = peer->primary_device_type;
563 peer_tmp->sub_category = peer->secondary_device_type;
564 strncpy(peer_tmp->mac_addr, peer->mac_address, MAC_LENGTH - 1);
565 peer_tmp->mac_addr[MAC_LENGTH - 1] = '\0';
566 strncpy(peer_tmp->if_addr, peer->interface_address, MAC_LENGTH - 1);
567 peer_tmp->if_addr[MAC_LENGTH - 1] = '\0';
568 peer_tmp->is_group_owner = peer->is_group_owner;
569 peer_tmp->is_persistent_group_owner = peer->is_persistent_group_owner;
570 peer_tmp->is_connected = peer->is_connected;
571 peer_tmp->dev_sel_state = FALSE;
573 if (TRUE == peer->is_connected)
574 peer_tmp->conn_status = PEER_CONN_STATUS_CONNECTED;
576 peer_tmp->conn_status = PEER_CONN_STATUS_DISCONNECTED;
578 ugd->raw_discovered_peer_list = g_list_append(ugd->raw_discovered_peer_list, peer_tmp);
579 DBG(LOG_INFO, "\tSSID: [%s]\n", peer_tmp->ssid);
580 DBG(LOG_INFO, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peer_tmp->category);
581 DBG(LOG_INFO, "\tStatus: [%d]\n", peer_tmp->conn_status);
582 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
583 ugd->raw_discovered_peer_cnt++;
585 DBG(LOG_INFO, "Unavailable WiFi-Direct Device\n");
588 WFD_IF_FREE_MEM(peer->device_name);
589 WFD_IF_FREE_MEM(peer->mac_address);
590 WFD_IF_FREE_MEM(peer->interface_address);
592 if (NULL != peer->service_list) {
593 for (i = 0; i < peer->service_count && peer->service_list[i] != NULL; i++)
594 free(peer->service_list[i]);
596 WFD_IF_FREE_MEM(peer->service_list);
599 WFD_IF_FREE_MEM(peer);
606 * This function let the ug make a callback for connected peer
608 * @param[in] peer the pointer to the connected peer
609 * @param[in] user_data the pointer to the main data structure
611 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
614 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
616 struct ug_data *ugd = (struct ug_data *)user_data;
617 int peer_cnt = ugd->raw_connected_peer_cnt;
620 DBG_SECURE(LOG_INFO, "%dth connected peer. [%s] ["MACSECSTR"]\n", peer_cnt,
621 peer->device_name, MAC2SECSTR(peer->mac_address));
624 * check wether ug needs to exit
625 * automatically after successed connection
628 char services[256] = {0,};
629 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
630 if (peer->service_count > 0) {
631 unsigned int len = 0;
632 for (i = 0; i < peer->service_count && peer->service_list != NULL; i++) {
633 snprintf(services + len, 256-len, "%s ", peer->service_list[i]);
634 len = len + strlen(peer->service_list[i]) + 1;
636 DBG(LOG_INFO, "\tServices: [%s]\n", services);
639 g_strlcpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid));
640 ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
641 ugd->raw_connected_peers[peer_cnt].sub_category = peer->secondary_device_type;
642 g_strlcpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
643 g_strlcpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
644 ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
646 DBG(LOG_INFO, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
647 DBG(LOG_INFO, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
648 DBG(LOG_INFO, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
650 ugd->raw_connected_peer_cnt++;
653 bool is_group_owner = FALSE;
654 error = wifi_direct_is_group_owner(&is_group_owner);
655 if (error != WIFI_DIRECT_ERROR_NONE) {
656 DBG(LOG_ERROR, "Fail to get group_owner_state. ret=[%d]", error);
660 if (FALSE == is_group_owner) {
663 app_control_h control = NULL;
664 ret = app_control_create(&control);
666 DBG(LOG_ERROR, "Failed to create control");
670 if (peer->ip_address != NULL && strlen(services) != 0) {
671 app_control_add_extra_data(control, "ip_address", peer->ip_address);
672 app_control_add_extra_data(control, "wfds", services);
673 ug_send_result(ugd->ug, control);
675 app_control_destroy(control);
678 WFD_IF_FREE_MEM(peer->device_name);
679 WFD_IF_FREE_MEM(peer->mac_address);
680 WFD_IF_FREE_MEM(peer->interface_address);
682 if (NULL != peer->service_list) {
683 for (i = 0; i < peer->service_count && peer->service_list[i] != NULL; i++)
684 free(peer->service_list[i]);
686 WFD_IF_FREE_MEM(peer->service_list);
689 WFD_IF_FREE_MEM(peer);
696 * This function let the ug get the found peers
697 * @return If success, return 0, else return -1
698 * @param[in] ugd the pointer to the main data structure
700 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
704 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
706 ugd->raw_discovered_peer_cnt = 0;
707 wfd_client_free_raw_discovered_peers(ugd);
708 res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
709 if (res != WIFI_DIRECT_ERROR_NONE) {
710 ugd->raw_discovered_peer_cnt = 0;
711 DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
720 * This function let the ug get the connecting peer
721 * @return If success, return 0, else return -1
722 * @param[in] ugd the pointer to the main data structure
724 int wfd_ug_get_connecting_peer(struct ug_data *ugd)
728 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
729 char *mac_addr = NULL;
730 GList *iterator = NULL;
732 ugd->mac_addr_connecting = NULL;
733 res = wifi_direct_get_connecting_peer(&mac_addr);
734 if (res != WIFI_DIRECT_ERROR_NONE) {
735 DBG(LOG_ERROR, "Get connecting device mac failed: %d\n", res);
738 DBG_SECURE(LOG_INFO, "Mac Addr Connecting: ["MACSECSTR"]\n",
739 MAC2SECSTR(mac_addr));
740 ugd->mac_addr_connecting = mac_addr;
742 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
743 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
744 ((device_type_s *)iterator->data)->conn_status = PEER_CONN_STATUS_CONNECTING;
754 * This function let the ug get the connected peers
755 * @return If success, return 0, else return -1
756 * @param[in] ugd the pointer to the main data structure
758 int wfd_ug_get_connected_peers(struct ug_data *ugd)
762 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
764 ugd->raw_connected_peer_cnt = 0;
765 res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
766 if (res != WIFI_DIRECT_ERROR_NONE) {
767 ugd->raw_connected_peer_cnt = 0;
768 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
776 * This function let the ug exits automatically after successed connection
778 * @param[in] user_data the pointer to the main data structure
780 void _wfd_ug_auto_exit(void *user_data)
783 struct ug_data *ugd = (struct ug_data *)user_data;
784 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
786 deinit_wfd_client(ugd);
792 gboolean wfd_delete_not_alive_peer_cb(void *user_data)
795 struct ug_data *ugd = (struct ug_data *)user_data;
796 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
798 delete_not_alive_peers(ugd, &ugd->gl_avlb_peers_start, &ugd->gl_available_peer_cnt);
799 delete_not_alive_peers(ugd, &ugd->gl_busy_peers_start, &ugd->gl_busy_peer_cnt);
800 delete_not_alive_peers(ugd, &ugd->multi_conn_dev_list_start, &ugd->gl_available_dev_cnt_at_multiconn_view);
801 wfd_ug_view_init_genlist(ugd, false);
802 wfd_update_multiconnect_device(ugd, false);
808 gboolean wfd_delete_progressbar_cb(void *user_data)
811 struct ug_data *ugd = (struct ug_data *)user_data;
812 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
814 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
815 if (ugd->raw_discovered_peer_cnt == 0 &&
816 ugd->nodevice_title_item == NULL &&
817 ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE &&
818 ugd->gl_available_peer_cnt == 0) {
819 _create_no_device_genlist(ugd);
822 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
823 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
825 if (0 == ugd->gl_available_dev_cnt_at_multiconn_view)
826 _create_no_device_multiconnect_genlist(ugd);
828 wfd_refresh_wifi_direct_state(ugd);
829 if (WIFI_DIRECT_STATE_CONNECTING != ugd->wfd_status &&
830 WIFI_DIRECT_STATE_DISCONNECTING != ugd->wfd_status) {
831 if (ugd->scan_toolbar) {
832 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
833 evas_object_data_set(ugd->toolbar, "scan", "scan");
836 if (ugd->multiconn_layout) {
837 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
838 DBG(LOG_INFO, "Multiconn button text IDS_WIFI_SK4_SCAN \n");
848 * This function let the ug make a callback for registering discover event
850 * @param[in] error_code the returned error code
851 * @param[in] discovery_state the state of discover
852 * @param[in] user_data the pointer to the main data structure
854 void discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
858 struct ug_data *ugd = (struct ug_data *)user_data;
861 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
865 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS)
868 DBG(LOG_INFO, "Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
870 if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
871 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
872 ugd->title_content_mode = TITLE_CONTENT_TYPE_SCANNING;
873 wfd_cancel_progressbar_stop_timer(ugd);
874 ugd->timer_stop_progress_bar = g_timeout_add(1000*30, wfd_delete_progressbar_cb, ugd);
875 /* clear all the previous discovered peers */
876 wfd_client_free_raw_discovered_peers(ugd);
878 ugd->raw_discovered_peer_cnt = 0;
879 wfd_ug_view_init_genlist(ugd, false);
881 if (ugd->avlbl_wfd_item == NULL)
882 _create_available_dev_genlist(ugd);
884 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
885 /* clear not alive peers after 5 secs */
886 wfd_cancel_not_alive_delete_timer(ugd);
887 ugd->timer_delete_not_alive_peer = g_timeout_add(1000*5, wfd_delete_not_alive_peer_cb, ugd);
888 set_not_alive_peers(ugd->gl_avlb_peers_start);
889 set_not_alive_peers(ugd->gl_busy_peers_start);
890 set_not_alive_peers(ugd->multi_conn_dev_list_start);
892 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
893 if (ugd->wfd_discovery_status != WIFI_DIRECT_DISCOVERY_NONE) {
894 wfd_ug_get_discovered_peers(ugd);
895 wfd_ug_update_available_peers(ugd);
896 wfd_update_multiconnect_device(ugd, false);
898 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FINISHED) {
899 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
900 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_FULL_SCAN_START;
901 ret = wifi_direct_start_discovery_specific_channel(false, 0, WIFI_DIRECT_DISCOVERY_FULL_SCAN);
902 if (ret != WIFI_DIRECT_ERROR_NONE) {
903 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
904 DBG(LOG_ERROR, "Failed to start discovery with full scan. [%d]\n", ret);
905 wifi_direct_cancel_discovery();
910 if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state &&
911 ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
912 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
913 if (!ugd->conn_wfd_item)
914 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
916 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK_STOP", TRUE);
917 if (ugd->multiconn_scan_stop_btn)
918 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK_STOP", TRUE);
926 * This function let the ug make a callback for registering connection event
928 * @param[in] error_code the returned error code
929 * @param[in] connection_state the state of connection
930 * @param[in] mac_address the mac address of peer
931 * @param[in] user_data the pointer to the main data structure
933 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
936 struct ug_data *ugd = (struct ug_data *)user_data;
937 device_type_s *peer = NULL;
941 if (mac_address == NULL) {
942 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
946 DBG_SECURE(LOG_INFO, "Connection event [%d], error_code [%d], multi_connect_mode [%d] mac ["MACSECSTR"]\n",
947 connection_state, error_code, ugd->multi_connect_mode, MAC2SECSTR(mac_address));
949 /* when not in connection, mac_address is empty */
950 if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
951 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
953 if (NULL == peer || '\0' == peer->ssid[0]) {
954 DBG(LOG_ERROR, "invalid peer from connection !!\n");
955 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
960 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
961 switch (connection_state) {
962 case WIFI_DIRECT_CONNECTION_RSP:
963 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
964 ugd->mac_addr_connecting = NULL;
965 if (error_code == WIFI_DIRECT_ERROR_NONE) {
966 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
967 wfd_ug_get_connected_peers(ugd);
968 wfd_ug_update_connected_peers(ugd);
970 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
971 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
973 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
974 wfd_ug_view_refresh_glitem(peer->gl_item);
977 /* connect the next peer */
978 ugd->g_source_multi_connect_next = g_timeout_add(500, wfd_multi_connect_next_cb, ugd);
980 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
981 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
982 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
983 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
986 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
987 wfd_ug_view_refresh_glitem(peer->gl_item);
990 wfd_ug_update_toolbar(ugd);
992 case WIFI_DIRECT_GROUP_CREATED:
993 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_GROUP_CREATED\n");
994 wfd_cancel_progressbar_stop_timer(ugd);
995 wfd_delete_progressbar_cb(ugd);
997 wfd_ug_view_init_genlist(ugd, true);
998 wfd_ug_view_update_multiconn_peers(ugd);
999 wfd_multi_connect_next_cb(ugd);
1005 switch (connection_state) {
1006 case WIFI_DIRECT_CONNECTION_RSP:
1007 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_RSP\n");
1008 wfd_delete_progressbar_cb(ugd);
1010 if (ugd->act_popup) {
1011 evas_object_del(ugd->act_popup);
1012 ugd->act_popup = NULL;
1014 ugd->mac_addr_connecting = NULL;
1016 if (error_code == WIFI_DIRECT_ERROR_NONE) {
1017 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1018 wfd_ug_get_connected_peers(ugd);
1020 /* when auto_exit and not multi-connect*/
1021 if ((ugd->is_auto_exit) && (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE))
1022 _wfd_ug_auto_exit(ugd);
1024 wfd_ug_update_connected_peers(ugd);
1026 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1027 wfd_ug_update_failed_peers(ugd);
1030 wfd_ug_update_toolbar(ugd);
1032 case WIFI_DIRECT_DISASSOCIATION_IND:
1033 DBG(LOG_INFO, "WIFI_DIRECT_DISASSOCIATION_IND\n");
1034 /* remove any possible popup */
1035 WFD_IF_DEL_OBJ(ugd->act_popup);
1036 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
1038 /* change the multi connection mode, it can be connected now */
1039 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED)
1040 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1042 /* if other peer disconnected, get connected peers and update */
1043 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
1044 wfd_ug_get_connected_peers(ugd);
1045 wfd_ug_update_available_peers(ugd);
1047 case WIFI_DIRECT_DISCONNECTION_RSP:
1048 case WIFI_DIRECT_DISCONNECTION_IND:
1049 DBG(LOG_INFO, "WIFI_DIRECT_DISCONNECTION_X\n");
1050 WFD_IF_DEL_OBJ(ugd->act_popup);
1052 Evas_Object *content;
1053 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1054 WFD_IF_DEL_OBJ(content);
1055 content = elm_object_part_content_unset(ugd->button_layout, "button.prev");
1056 evas_object_hide(content);
1058 /* when disconnection, clear all the connected peers */
1059 if (ugd->raw_connected_peer_cnt > 0)
1060 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
1062 ugd->raw_connected_peer_cnt = 0;
1063 wfd_ug_view_init_genlist(ugd, true);
1064 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1065 DBG(LOG_INFO, "Background mode\n");
1069 if (ugd->is_paused == false) {
1070 /* start discovery again */
1071 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1072 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1073 if (res != WIFI_DIRECT_ERROR_NONE) {
1074 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1075 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1076 wifi_direct_cancel_discovery();
1081 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1082 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1083 wfd_ug_update_toolbar(ugd);
1084 wfd_cancel_progressbar_stop_timer(ugd);
1085 wfd_delete_progressbar_cb(ugd);
1087 if (ugd->multi_navi_item)
1088 elm_naviframe_item_pop(ugd->naviframe);
1090 ugd->mac_addr_connecting = peer->mac_addr;
1091 ugd->is_conn_incoming = FALSE;
1092 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1093 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, peer->mac_addr);
1095 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1096 wfd_ug_view_refresh_glitem(peer->gl_item);
1098 wfd_ug_get_discovered_peers(ugd);
1099 wfd_ug_update_available_peers(ugd);
1103 case WIFI_DIRECT_CONNECTION_REQ:
1104 case WIFI_DIRECT_CONNECTION_WPS_REQ:
1105 ugd->mac_addr_connecting = peer->mac_addr;
1106 ugd->is_conn_incoming = TRUE;
1107 DBG(LOG_INFO, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
1109 case WIFI_DIRECT_GROUP_DESTROYED:
1110 wfd_ug_update_toolbar(ugd);
1111 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1112 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1114 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1115 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1116 if (res != WIFI_DIRECT_ERROR_NONE) {
1117 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1118 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1119 wifi_direct_cancel_discovery();
1130 /* refresh the scan button */
1131 wfd_refresh_wifi_direct_state(ugd);
1132 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
1133 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
1134 res = wifi_direct_is_group_owner(&owner);
1135 if (res == WIFI_DIRECT_ERROR_NONE) {
1137 if (ugd->scan_toolbar)
1138 evas_object_data_set(ugd->toolbar, "scan", "scan");
1140 if (ugd->multiconn_scan_stop_btn)
1141 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1144 DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
1147 if (ugd->scan_toolbar)
1148 evas_object_data_set(ugd->toolbar, "scan", "scan");
1150 if (ugd->multiconn_scan_stop_btn)
1151 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
1159 * This function let the ug make a callback for registering ip assigned event
1161 * @param[in] mac_address the mac address of peer
1162 * @param[in] ip_address the ip address of peer
1163 * @param[in] interface_address the interface address
1164 * @param[in] user_data the pointer to the main data structure
1166 void _ip_assigned_cb(const char *mac_address, const char *ip_address, const char *interface_address, void *user_data)
1171 DBG(LOG_ERROR, "The user_data is NULL\n");
1175 struct ug_data *ugd = (struct ug_data *)user_data;
1177 if (!ip_address || 0 == strncmp(ip_address, "0.0.0.0", 7)) {
1178 DBG(LOG_ERROR, "ip address is invalid.\n");
1182 ugd->peer_ip_address = strdup(ip_address);
1185 /* to send ip_addr*/
1187 app_control_h control = NULL;
1188 ret = app_control_create(&control);
1190 DBG(LOG_ERROR, "Failed to create control");
1193 app_control_add_extra_data(control, "ip_address", ugd->peer_ip_address);
1194 app_control_add_extra_data(control, "wfds", ugd->service_name);
1195 ug_send_result(ugd->ug, control);
1196 app_control_destroy(control);
1198 /* when auto_exit and not multi-connect*/
1199 if ((ugd->is_auto_exit) && (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE))
1200 _wfd_ug_auto_exit(ugd);
1206 * This function let the ug get wi-fi direct status from vconf
1207 * @return If success, return the wfd status, else return -1
1210 int wfd_get_vconf_status()
1213 int wifi_direct_state = 0;
1215 /* get wifi direct status from vconf */
1216 if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
1217 DBG(LOG_ERROR, "Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
1220 DBG(LOG_INFO, "WiFi Direct State [%d]", wifi_direct_state);
1223 return wifi_direct_state;
1227 * This function let the ug get device name from vconf
1228 * @return If success, return 0, else return -1
1229 * @param[in] data the pointer to the main data structure
1231 int wfd_get_vconf_device_name(void *data)
1234 struct ug_data *ugd = (struct ug_data *)data;
1235 char *dev_name = NULL;
1237 /* get device name from vconf */
1238 dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1239 if (dev_name == NULL) {
1240 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1241 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
1245 ugd->dev_name = strdup(dev_name);
1246 WFD_IF_FREE_MEM(dev_name);
1253 * This function let the ug refresh current status of wi-fi direct
1254 * @return If success, return 0, else return -1
1255 * @param[in] data the pointer to the main data structure
1257 int wfd_refresh_wifi_direct_state(void *data)
1260 struct ug_data *ugd = (struct ug_data *)data;
1262 wifi_direct_state_e wfd_status;
1264 res = wifi_direct_get_state(&wfd_status);
1265 if (res != WIFI_DIRECT_ERROR_NONE) {
1266 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
1270 DBG(LOG_INFO, "WFD status [%d]", wfd_status);
1271 ugd->wfd_status = wfd_status;
1277 void wfd_init_ug_by_status(void *user_data)
1280 struct ug_data *ugd = (struct ug_data *)user_data;
1284 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
1288 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) {
1289 //wfd_ug_get_discovered_peers(ugd);
1290 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1293 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
1294 wfd_ug_get_connected_peers(ugd);
1295 wfd_ug_update_connected_peers(ugd);
1296 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1297 wfd_ug_get_discovered_peers(ugd);
1298 wfd_ug_update_available_peers(ugd);
1299 wfd_ug_update_toolbar(ugd);
1302 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1303 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1304 wfd_ug_get_discovered_peers(ugd);
1305 wfd_ug_get_connecting_peer(ugd);
1306 wfd_ug_update_available_peers(ugd);
1307 wfd_ug_update_toolbar(ugd);
1310 if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED ||
1311 ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1312 /* start discovery */
1313 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1314 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1315 if (res != WIFI_DIRECT_ERROR_NONE) {
1316 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1317 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1318 wifi_direct_cancel_discovery();
1326 * This function let the ug do initialization
1327 * @return If success, return 0, else return -1
1328 * @param[in] data the pointer to the main data structure
1330 int init_wfd_client(void* data)
1333 WFD_RETV_IF(data == NULL, -1, "Incorrect parameter(NULL)\n");
1334 struct ug_data *ugd = (struct ug_data *)data;
1337 res = wifi_direct_initialize();
1338 if (res != WIFI_DIRECT_ERROR_NONE) {
1339 if (res != WIFI_DIRECT_ERROR_ALREADY_INITIALIZED) {
1340 DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
1343 DBG(LOG_ERROR, "Already registered\n");
1347 res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1348 if (res != WIFI_DIRECT_ERROR_NONE) {
1349 DBG(LOG_ERROR, "Failed to register _cb_activation. error code = [%d]\n", res);
1353 res = wifi_direct_set_discovery_state_changed_cb(discover_cb, (void *)ugd);
1354 if (res != WIFI_DIRECT_ERROR_NONE) {
1355 DBG(LOG_ERROR, "Failed to register _cb_discover. error code = [%d]\n", res);
1359 res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1360 if (res != WIFI_DIRECT_ERROR_NONE) {
1361 DBG(LOG_ERROR, "Failed to register _cb_connection. error code = [%d]\n", res);
1365 res = wifi_direct_set_client_ip_address_assigned_cb(_ip_assigned_cb, (void *)ugd);
1366 if (res != WIFI_DIRECT_ERROR_NONE) {
1367 DBG(LOG_ERROR, "Failed to register _ip_assigned_cb. error code = [%d]\n", res);
1371 /* update WFD status */
1372 wfd_refresh_wifi_direct_state(ugd);
1373 #ifdef WFD_ON_OFF_GENLIST
1374 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1376 wfd_ug_refresh_on_off_check(ugd);
1382 DBG(LOG_INFO, "WFD link status. [%d]\n", ugd->wfd_status);
1383 ugd->is_init_ok = TRUE;
1384 wfd_init_ug_by_status(ugd);
1390 void wfd_client_destroy_tethering(struct ug_data *ugd)
1394 tethering_error_e ret = TETHERING_ERROR_NONE;
1396 if (ugd->hotspot_handle != NULL) {
1397 /* Deregister cbs */
1398 ret = tethering_unset_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1399 if (ret != TETHERING_ERROR_NONE)
1400 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
1402 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1403 if (ret != TETHERING_ERROR_NONE)
1404 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1406 /* Destroy tethering handle */
1407 ret = tethering_destroy(ugd->hotspot_handle);
1408 if (ret != TETHERING_ERROR_NONE)
1409 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
1411 ugd->hotspot_handle = NULL;
1418 * This function let the ug do de-initialization
1419 * @return If success, return 0, else return -1
1420 * @param[in] data the pointer to the main data structure
1422 int deinit_wfd_client(void *data)
1425 struct ug_data *ugd = (struct ug_data *)data;
1428 wfd_refresh_wifi_direct_state(ugd);
1430 if ((WIFI_DIRECT_STATE_DISCOVERING == ugd->wfd_status) &&
1431 (WIFI_DIRECT_ERROR_NONE != wifi_direct_cancel_discovery())) {
1432 DBG(LOG_ERROR, "Failed to send cancel discovery state [%d]\n", ugd->wfd_status);
1435 wfd_cancel_progressbar_stop_timer(ugd);
1436 wfd_cancel_not_alive_delete_timer(ugd);
1438 if (ugd->timer_multi_reset > 0)
1439 g_source_remove(ugd->timer_multi_reset);
1441 ugd->timer_multi_reset = 0;
1443 if (ugd->g_source_multi_connect_next > 0)
1444 g_source_remove(ugd->g_source_multi_connect_next);
1446 ugd->g_source_multi_connect_next = 0;
1448 res = wifi_direct_unset_discovery_state_changed_cb();
1449 if (res != WIFI_DIRECT_ERROR_NONE)
1450 DBG(LOG_ERROR, "Failed to unset discovery state changed cb. [%d]\n", res);
1452 wifi_direct_unset_device_state_changed_cb();
1453 if (res != WIFI_DIRECT_ERROR_NONE)
1454 DBG(LOG_ERROR, "Failed to unset device state changed cb. [%d]\n", res);
1456 wifi_direct_unset_connection_state_changed_cb();
1457 if (res != WIFI_DIRECT_ERROR_NONE)
1458 DBG(LOG_ERROR, "Failed to unset connection state changed cb. [%d]\n", res);
1460 wifi_direct_unset_client_ip_address_assigned_cb();
1461 if (res != WIFI_DIRECT_ERROR_NONE)
1462 DBG(LOG_ERROR, "Failed to unset client ip address assigned cb. [%d]\n", res);
1464 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING &&
1465 NULL != ugd->mac_addr_connecting) {
1466 if (ugd->is_conn_incoming) {
1467 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
1468 res = wifi_direct_reject_connection(ugd->mac_addr_connecting);
1469 if (res != WIFI_DIRECT_ERROR_NONE)
1470 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", res);
1472 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
1473 res = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
1474 if (res != WIFI_DIRECT_ERROR_NONE)
1475 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", res);
1477 ugd->mac_addr_connecting = NULL;
1481 res = wifi_direct_deinitialize();
1482 if (res != WIFI_DIRECT_ERROR_NONE)
1483 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
1485 /* release vconf, hotspot.. */
1486 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1487 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1489 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
1491 res = net_deregister_client();
1492 if (res != NET_ERR_NONE)
1493 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
1495 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1498 wfd_client_destroy_tethering(ugd);
1505 * This function let the ug turn wi-fi direct on
1506 * @return If success, return 0, else return -1
1507 * @param[in] data the pointer to the main data structure
1509 int wfd_client_switch_on(void *data)
1512 struct ug_data *ugd = (struct ug_data *)data;
1515 bool is_wifi_enabled = false;
1517 if (!ugd->is_init_ok) {
1518 DBG(LOG_ERROR, "device is initializing, please wait\n");
1522 wfd_refresh_wifi_direct_state(ugd);
1523 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1525 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1527 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1529 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1531 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
1534 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1536 ugd->hotspot_handle = NULL;
1537 res = tethering_create(&(ugd->hotspot_handle));
1538 if (res != TETHERING_ERROR_NONE) {
1539 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", res);
1542 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
1545 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1547 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1548 if (wifi_state > VCONFKEY_WIFI_OFF) {
1549 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1550 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_CONNECTION_CONTINUE_Q"), POPUP_TYPE_WIFI_OFF);
1552 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1554 if (is_wifi_enabled) {
1555 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1556 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_TETHERING_CONTINUE_Q"), POPUP_TYPE_HOTSPOT_OFF);
1558 res = wifi_direct_activate();
1559 if (res != WIFI_DIRECT_ERROR_NONE) {
1560 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1561 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1562 #ifdef WFD_ON_OFF_GENLIST
1563 wfd_ug_refresh_on_off_check(ugd);
1568 #ifdef WFD_ON_OFF_GENLIST
1569 if (ugd->on_off_check) {
1570 elm_check_state_set(ugd->on_off_check, TRUE);
1571 elm_object_disabled_set(ugd->on_off_check, TRUE);
1574 /* while activating, disable the buttons */
1575 if (ugd->scan_toolbar == NULL)
1576 scan_button_create(ugd);
1578 if (ugd->scan_toolbar)
1579 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1581 if (ugd->multiconn_scan_stop_btn)
1582 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1585 elm_object_disabled_set(ugd->back_btn, TRUE);
1588 DBG(LOG_INFO, "Wi-Fi Direct is already activated\n");
1596 * This function let the ug turn wi-fi direct off
1597 * @return If success, return 0, else return -1
1598 * @param[in] data the pointer to the main data structure
1600 int wfd_client_switch_off(void *data)
1603 struct ug_data *ugd = (struct ug_data *)data;
1606 wfd_ug_view_free_peers(ugd);
1607 wfd_free_nodivice_item(ugd);
1609 wfd_refresh_wifi_direct_state(ugd);
1610 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1612 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1613 DBG(LOG_INFO, "Wi-Fi Direct is already deactivated\n");
1616 wfd_client_destroy_tethering(ugd);
1618 wfd_cancel_progressbar_stop_timer(ugd);
1619 wfd_cancel_not_alive_delete_timer(ugd);
1621 if (ugd->timer_multi_reset > 0)
1622 g_source_remove(ugd->timer_multi_reset);
1624 ugd->timer_multi_reset = 0;
1626 if (ugd->g_source_multi_connect_next > 0)
1627 g_source_remove(ugd->g_source_multi_connect_next);
1629 ugd->g_source_multi_connect_next = 0;
1631 /*if connected, disconnect all devices*/
1632 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1633 res = wifi_direct_disconnect_all();
1634 if (res != WIFI_DIRECT_ERROR_NONE) {
1635 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1640 res = wifi_direct_deactivate();
1641 if (res != WIFI_DIRECT_ERROR_NONE) {
1642 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1643 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE_DEACTIVATE_FAIL);
1644 #ifdef WFD_ON_OFF_GENLIST
1645 wfd_ug_refresh_on_off_check(ugd);
1650 /* while deactivating, disable the buttons */
1651 if (ugd->scan_toolbar) {
1652 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1653 evas_object_del(ugd->scan_toolbar);
1654 ugd->scan_toolbar = NULL;
1657 if (ugd->multiconn_scan_stop_btn)
1658 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1660 if (ugd->multi_connect_toolbar_item)
1661 elm_object_item_disabled_set(ugd->multi_connect_toolbar_item, TRUE);
1664 elm_object_disabled_set(ugd->back_btn, TRUE);
1671 #ifdef WFD_ON_OFF_GENLIST
1673 * This function let the ug turn wi-fi direct on/off forcely
1674 * @return If success, return 0, else return -1
1675 * @param[in] data the pointer to the main data structure
1676 * @param[in] onoff whether to turn on/off wi-fi direct
1678 int wfd_client_swtch_force(void *data, int onoff)
1681 struct ug_data *ugd = (struct ug_data *)data;
1685 res = wifi_direct_activate();
1686 if (res != WIFI_DIRECT_ERROR_NONE) {
1687 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1688 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1689 wfd_ug_refresh_on_off_check(ugd);
1693 res = wifi_direct_deactivate();
1694 if (res != WIFI_DIRECT_ERROR_NONE) {
1695 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1696 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE);
1697 wfd_ug_refresh_on_off_check(ugd);
1708 * This function let the ug create a group
1709 * @return If success, return 0, else return -1
1711 int wfd_client_group_add()
1716 res = wifi_direct_create_group();
1717 if (res != WIFI_DIRECT_ERROR_NONE) {
1718 DBG(LOG_ERROR, "Failed to add group");
1728 * This function let the ug connect to the device by mac address
1729 * @return If success, return 0, else return -1
1730 * @param[in] mac_addr the pointer to the mac address of device
1732 int wfd_client_connect(const char *mac_addr)
1737 DBG_SECURE(LOG_INFO, "connect to peer=["MACSECSTR"]\n", MAC2SECSTR(mac_addr));
1738 res = wifi_direct_connect((char *)mac_addr);
1739 if (res != WIFI_DIRECT_ERROR_NONE) {
1740 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
1749 * This function let the ug disconnect to the device by mac address
1750 * @return If success, return 0, else return -1
1751 * @param[in] mac_addr the pointer to the mac address of device
1753 int wfd_client_disconnect(const char *mac_addr)
1758 wifi_direct_cancel_discovery();
1760 * No need to handle return in cancel discovery as there maybe case
1761 * when framework can return failure.
1764 if (mac_addr == NULL) {
1765 res = wifi_direct_disconnect_all();
1766 if (res != WIFI_DIRECT_ERROR_NONE) {
1767 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1771 res = wifi_direct_disconnect((char *)mac_addr);
1772 if (res != WIFI_DIRECT_ERROR_NONE) {
1773 DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
1783 * This function let the ug set the intent of a group owner
1784 * @return If success, return 0, else return -1
1785 * @param[in] go_intent the intent parameter
1787 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1792 res = wifi_direct_set_group_owner_intent(go_intent);
1793 if (res != WIFI_DIRECT_ERROR_NONE) {
1794 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);