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>
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);
75 * This function let the ug make a event callback for network registering
77 * @param[in] event_info the pointer to the information of network event
78 * @param[in] user_data the pointer to the user data
80 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
83 DBG(LOG_INFO, "Event from network. [%d]\n", event_info->Event);
88 * This function let the ug turn wifi off
89 * @return If success, return 0, else return -1
90 * @param[in] data the pointer to the main data structure
92 int wfd_wifi_off(void *data)
95 struct ug_data *ugd = (struct ug_data *)data;
98 res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
100 DBG(LOG_ERROR, "Failed to register vconf callback\n");
104 DBG(LOG_INFO, "Vconf key callback is registered\n");
106 res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
107 if (res != NET_ERR_NONE) {
108 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
112 DBG(LOG_INFO, "Network client is registered\n");
114 res = net_wifi_power_off();
115 if (res != NET_ERR_NONE) {
116 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
120 DBG(LOG_INFO, "WiFi power off\n");
125 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
129 * This function let the ug make a callback for setting tethering mode enabled
131 * @param[in] error the returned error code
132 * @param[in] type the type of tethering
133 * @param[in] is_requested whether tethering mode is enabled
134 * @param[in] data the pointer to the user data
136 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
139 struct ug_data *ugd = (struct ug_data *)data;
140 tethering_error_e ret = TETHERING_ERROR_NONE;
141 tethering_h th = NULL;
142 bool is_wifi_enabled = false;
144 if (error != TETHERING_ERROR_NONE) {
145 if (is_requested != TRUE) {
149 DBG(LOG_ERROR, "error !!! TETHERING is not enabled.\n");
153 th = ugd->hotspot_handle;
155 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
156 if (is_wifi_enabled) {
157 DBG(LOG_INFO, "Mobile hotspot is activated\n");
161 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
162 if (ret != TETHERING_ERROR_NONE) {
163 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
166 /* Destroy tethering handle */
167 ret = tethering_destroy(th);
168 if (ret != TETHERING_ERROR_NONE) {
169 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
172 ugd->hotspot_handle = NULL;
175 DBG(LOG_INFO, "TETHERING is enabled.\n");
182 * This function let the ug make a callback for setting tethering mode disabled
184 * @param[in] error the returned error code
185 * @param[in] type the type of tethering
186 * @param[in] code whether tethering mode is enabled
187 * @param[in] data the pointer to the user data
189 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
193 struct ug_data *ugd = (struct ug_data *)data;
194 tethering_error_e ret = TETHERING_ERROR_NONE;
195 tethering_h th = NULL;
196 bool is_wifi_enabled = false;
197 bool is_wifi_ap_enabled = false;
199 if (error != TETHERING_ERROR_NONE) {
200 if (code != TETHERING_DISABLED_BY_REQUEST) {
204 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
208 th = ugd->hotspot_handle;
210 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
211 is_wifi_ap_enabled = tethering_is_enabled(th, TETHERING_TYPE_RESERVED);
212 if (is_wifi_enabled || is_wifi_ap_enabled) {
213 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
214 DBG(LOG_ERROR, "is_wifi_enabled:%d is_wifi_ap_enabled:%d\n", is_wifi_enabled, is_wifi_ap_enabled);
218 DBG(LOG_INFO, "Mobile hotspot is deactivated\n");
219 wfd_client_swtch_force(ugd, TRUE);
221 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
222 if (ret != TETHERING_ERROR_NONE) {
223 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
226 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_RESERVED);
227 if (ret != TETHERING_ERROR_NONE) {
228 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
231 /* Destroy tethering handle */
232 ret = tethering_destroy(th);
233 if (ret != TETHERING_ERROR_NONE) {
234 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
237 ugd->hotspot_handle = NULL;
240 DBG(LOG_INFO, "TETHERING is disabled.\n");
247 * This function let the ug turn AP on
248 * @return If success, return 0, else return -1
249 * @param[in] data the pointer to the main data structure
251 int wfd_mobile_ap_on(void *data)
254 struct ug_data *ugd = (struct ug_data *)data;
255 tethering_error_e ret = TETHERING_ERROR_NONE;
256 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
258 if (NULL == ugd->hotspot_handle) {
259 ret = tethering_create(&(ugd->hotspot_handle));
260 if (TETHERING_ERROR_NONE != ret) {
261 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
262 ugd->hotspot_handle = NULL;
265 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
268 ret = tethering_set_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __enabled_cb, ugd);
269 if (ret != TETHERING_ERROR_NONE) {
270 DBG(LOG_ERROR, "tethering_set_enabled_cb is failed\n", ret);
274 /* Enable tethering */
275 ret = tethering_enable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
276 if (ret != TETHERING_ERROR_NONE) {
277 DBG(LOG_ERROR, "Failed to turn on mobile hotspot. [%d]\n", ret);
280 DBG(LOG_INFO, "Succeeded to turn on mobile hotspot\n");
283 ugd->is_hotspot_off = FALSE;
290 * This function let the ug turn AP off
291 * @return If success, return 0, else return -1
292 * @param[in] data the pointer to the main data structure
294 int wfd_mobile_ap_off(void *data)
297 struct ug_data *ugd = (struct ug_data *)data;
298 WFD_RETV_IF(ugd == NULL || ugd->hotspot_handle == NULL, -1, "Incorrect parameter(NULL)\n");
299 tethering_error_e ret = TETHERING_ERROR_NONE;
300 bool is_wifi_enabled = false;
301 bool is_wifi_ap_enabled = false;
303 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
304 is_wifi_ap_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
306 if (is_wifi_enabled) {
308 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __disabled_cb, ugd);
309 if (ret != TETHERING_ERROR_NONE) {
310 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
313 /* Disable tethering */
314 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
315 } else if (is_wifi_ap_enabled) {
316 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_RESERVED, __disabled_cb, ugd);
317 if (ret != TETHERING_ERROR_NONE) {
318 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
321 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
324 if (ret != TETHERING_ERROR_NONE) {
325 DBG(LOG_ERROR, "Failed to turn off mobile hotspot. [%d]\n", ret);
328 DBG(LOG_INFO, "Succeeded to turn off mobile hotspot\n");
331 ugd->is_hotspot_off = TRUE;
337 void wfd_client_free_raw_discovered_peers(struct ug_data *ugd)
340 WFD_RET_IF(ugd->raw_discovered_peer_list == NULL, "Incorrect parameter(NULL)\n");
342 g_list_free(ugd->raw_discovered_peer_list);
343 ugd->raw_discovered_peer_list = NULL;
349 * This function let the ug find the peer by mac address
350 * @return the found peer
351 * @param[in] data the pointer to the main data structure
352 * @param[in] mac_addr the pointer to mac address
354 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
357 struct ug_data *ugd = (struct ug_data *)data;
358 wifi_direct_discovered_peer_info_s *peer_info = NULL;
359 GList *iterator = NULL;
361 WFD_RETV_IF(ugd == NULL, NULL, "Incorrect parameter(NULL)\n");
363 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
364 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
365 if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH)) {
366 return &ugd->raw_multi_selected_peers[i];
370 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
371 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
372 return (device_type_s *)iterator->data;
378 * In case, device is not in raw discovered list, then get peer info.
379 * There could be situation in which device is not yet discovered and
380 * connected process started.
382 if (WIFI_DIRECT_ERROR_NONE != wifi_direct_get_peer_info((char *)mac_addr, &peer_info) ||
384 DBG(LOG_ERROR, "Peer Not Found !!!");
388 /* Update peer list */
389 DBG(LOG_INFO, "Update Peer info");
390 _wfd_discoverd_peer_cb(peer_info, (void *)ugd);
392 /* Get the device from peer list */
393 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
394 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
395 return (device_type_s *)iterator->data;
404 * This function let the ug make a callback for registering activation event
406 * @param[in] error_code the returned error code
407 * @param[in] device_state the state of device
408 * @param[in] user_data the pointer to the main data structure
410 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
414 struct ug_data *ugd = (struct ug_data *)user_data;
415 wfd_refresh_wifi_direct_state(ugd);
417 switch (device_state) {
418 case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
419 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
420 if(ugd->scan_toolbar == NULL) {
421 scan_button_create(ugd);
423 if (error_code != WIFI_DIRECT_ERROR_NONE) {
424 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
425 if (WIFI_DIRECT_ERROR_AUTH_FAILED == error_code) {
426 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_SECURITY_POLICY_RESTRICTS_USE_OF_WI_FI"), POPUP_TYPE_ACTIVATE_FAIL_POLICY_RESTRICTS);
428 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_ACTIVATE_FAIL);
431 #ifdef WFD_ON_OFF_GENLIST
433 wfd_ug_refresh_on_off_check(ugd);
438 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
439 #ifdef WFD_ON_OFF_GENLIST
441 wfd_ug_refresh_on_off_check(ugd);
443 wfg_ug_act_popup_remove(ugd);
445 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
446 DBG(LOG_INFO, "Background mode\n");
450 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
451 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
453 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
455 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
457 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
458 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
459 if (res != WIFI_DIRECT_ERROR_NONE) {
460 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
461 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
462 wifi_direct_cancel_discovery();
466 case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
467 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
468 if (error_code != WIFI_DIRECT_ERROR_NONE) {
469 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
470 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_DEACTIVATE_FAIL);
471 #ifdef WFD_ON_OFF_GENLIST
473 wfd_ug_refresh_on_off_check(ugd);
478 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
481 ctxpopup_dismissed_cb(ugd, NULL, NULL);
485 * When multi-connect is on ongoing and deactivte happened destroy
488 if (ugd->disconnect_btn) {
489 Evas_Object *content;
490 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
491 WFD_IF_DEL_OBJ(content);
492 ugd->disconnect_btn = NULL;
493 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
496 /* When connect is on ongoing and deactivte happened refresh scan */
497 if (ugd->scan_toolbar) {
498 wfd_ug_view_refresh_button(ugd->scan_toolbar,
499 "IDS_WIFI_SK4_SCAN", FALSE);
501 /* Delete pop-up when deactivate happens */
502 WFD_IF_DEL_OBJ(ugd->act_popup);
503 /* Remove timeout handlers */
504 if (ugd->timer_stop_progress_bar > 0)
505 g_source_remove(ugd->timer_stop_progress_bar);
507 if (ugd->timer_delete_not_alive_peer > 0)
508 g_source_remove(ugd->timer_delete_not_alive_peer);
510 if (ugd->g_source_multi_connect_next > 0)
511 g_source_remove(ugd->g_source_multi_connect_next);
513 if (ugd->timer_multi_reset > 0)
514 g_source_remove(ugd->timer_multi_reset);
516 /* Delete warn popups for Airplane mode */
517 if (NULL != ugd->warn_popup) {
518 evas_object_del( ugd->warn_popup);
519 ugd->warn_popup = NULL;
522 #ifdef WFD_ON_OFF_GENLIST
524 wfd_ug_refresh_on_off_check(ugd);
527 * when deactivated, clear all the
528 * discovered peers and connected peers
530 wfd_client_free_raw_discovered_peers(ugd);
531 if (ugd->raw_connected_peer_cnt > 0) {
532 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
535 ugd->raw_discovered_peer_cnt = 0;
536 ugd->raw_connected_peer_cnt = 0;
538 wfd_free_nodivice_item(ugd);
539 wfd_ug_view_init_genlist(ugd, true);
541 if (ugd->multi_navi_item != NULL) {
542 elm_naviframe_item_pop(ugd->naviframe);
545 if (TRUE == ugd->is_hotspot_off && TRUE == ugd->is_hotspot_locally_disabled) {
546 if (0 == wfd_mobile_ap_on(ugd)) {
547 ugd->is_hotspot_locally_disabled = FALSE;
551 if(ugd->scan_toolbar) {
552 evas_object_del(ugd->scan_toolbar);
553 ugd->scan_toolbar = NULL;
560 /*if (ugd->scan_toolbar) {
561 wfd_ug_view_refresh_button(ugd->scan_toolbar, D_("IDS_WIFI_SK4_SCAN"), TRUE);
564 if (ugd->multiconn_scan_stop_btn) {
565 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
569 elm_object_disabled_set(ugd->back_btn, FALSE);
577 * This function let the ug make a callback for discovering peer
579 * @param[in] peer the pointer to the discovered peer
580 * @param[in] user_data the pointer to the main data structure
582 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
585 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
587 struct ug_data *ugd = (struct ug_data *)user_data;
588 int peer_cnt = ugd->raw_discovered_peer_cnt;
589 device_type_s *peer_tmp = g_new(device_type_s, 1);
592 DBG_SECURE(LOG_INFO, "%dth discovered peer. [%s] ["MACSECSTR"]\n", peer_cnt,
593 peer->device_name, MAC2SECSTR(peer->mac_address));
595 if (ugd->device_filter < 0 || peer->primary_device_type == ugd->device_filter) {
596 strncpy(peer_tmp->ssid, peer->device_name, sizeof(peer_tmp->ssid) - 1);
597 peer_tmp->ssid[SSID_LENGTH - 1] = '\0';
598 peer_tmp->category = peer->primary_device_type;
599 peer_tmp->sub_category = peer->secondary_device_type;
600 strncpy(peer_tmp->mac_addr, peer->mac_address, MAC_LENGTH - 1);
601 peer_tmp->mac_addr[MAC_LENGTH - 1] = '\0';
602 strncpy(peer_tmp->if_addr, peer->interface_address, MAC_LENGTH - 1);
603 peer_tmp->if_addr[MAC_LENGTH - 1] = '\0';
604 peer_tmp->is_group_owner = peer->is_group_owner;
605 peer_tmp->is_persistent_group_owner = peer->is_persistent_group_owner;
606 peer_tmp->is_connected = peer->is_connected;
607 peer_tmp->dev_sel_state = FALSE;
609 if (TRUE == peer->is_connected) {
610 peer_tmp->conn_status = PEER_CONN_STATUS_CONNECTED;
612 peer_tmp->conn_status = PEER_CONN_STATUS_DISCONNECTED;
615 ugd->raw_discovered_peer_list = g_list_append(ugd->raw_discovered_peer_list, peer_tmp);
616 DBG(LOG_INFO, "\tSSID: [%s]\n", peer_tmp->ssid);
617 DBG(LOG_INFO, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peer_tmp->category);
618 DBG(LOG_INFO, "\tStatus: [%d]\n", peer_tmp->conn_status);
619 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
620 ugd->raw_discovered_peer_cnt++;
622 DBG(LOG_INFO, "Unavailable WiFi-Direct Device\n");
625 WFD_IF_FREE_MEM(peer->device_name);
626 WFD_IF_FREE_MEM(peer->mac_address);
627 WFD_IF_FREE_MEM(peer->interface_address);
629 if (NULL != peer->service_list)
631 for (i=0; i<peer->service_count && peer->service_list[i] != NULL; i++) {
632 free(peer->service_list[i]);
634 WFD_IF_FREE_MEM(peer->service_list);
637 WFD_IF_FREE_MEM(peer);
644 * This function let the ug make a callback for connected peer
646 * @param[in] peer the pointer to the connected peer
647 * @param[in] user_data the pointer to the main data structure
649 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
652 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
654 struct ug_data *ugd = (struct ug_data *)user_data;
655 int peer_cnt = ugd->raw_connected_peer_cnt;
658 DBG_SECURE(LOG_INFO, "%dth connected peer. [%s] ["MACSECSTR"]\n", peer_cnt,
659 peer->device_name, MAC2SECSTR(peer->mac_address));
662 * check wether ug needs to exit
663 * automatically after successed connection
666 char services[256] = {0,};
667 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
668 if (peer->service_count>0) {
669 unsigned int len = 0;
670 for (i=0; i<peer->service_count && peer->service_list != NULL; i++) {
671 snprintf(services + len, 256-len, "%s ", peer->service_list[i]);
672 len = len + strlen(peer->service_list[i]) + 1;
674 DBG(LOG_INFO, "\tServices: [%s]\n", services);
677 strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid) - 1);
678 ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
679 ugd->raw_connected_peers[peer_cnt].sub_category = peer->secondary_device_type;
680 strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH - 1);
681 strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH - 1);
682 ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
684 DBG(LOG_INFO, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
685 DBG(LOG_INFO, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
686 DBG(LOG_INFO, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
688 ugd->raw_connected_peer_cnt++;
691 bool is_group_owner = FALSE;
692 error = wifi_direct_is_group_owner(&is_group_owner);
693 if (error != WIFI_DIRECT_ERROR_NONE) {
694 DBG(LOG_ERROR, "Fail to get group_owner_state. ret=[%d]", error);
698 if (FALSE == is_group_owner) {
701 app_control_h control = NULL;
702 ret = app_control_create(&control);
704 DBG(LOG_ERROR, "Failed to create control");
708 if(peer->ip_address != NULL && strlen(services) != 0 ) {
709 app_control_add_extra_data(control, "ip_address", peer->ip_address);
710 app_control_add_extra_data(control, "wfds", services);
711 ug_send_result(ugd->ug, control);
713 app_control_destroy(control);
716 WFD_IF_FREE_MEM(peer->device_name);
717 WFD_IF_FREE_MEM(peer->mac_address);
718 WFD_IF_FREE_MEM(peer->interface_address);
720 if (NULL != peer->service_list)
722 for (i=0; i<peer->service_count && peer->service_list[i] != NULL; i++) {
723 free(peer->service_list[i]);
725 WFD_IF_FREE_MEM(peer->service_list);
728 WFD_IF_FREE_MEM(peer);
735 * This function let the ug get the found peers
736 * @return If success, return 0, else return -1
737 * @param[in] ugd the pointer to the main data structure
739 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
743 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
745 ugd->raw_discovered_peer_cnt = 0;
746 wfd_client_free_raw_discovered_peers(ugd);
747 res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
748 if (res != WIFI_DIRECT_ERROR_NONE) {
749 ugd->raw_discovered_peer_cnt = 0;
750 DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
759 * This function let the ug get the connecting peer
760 * @return If success, return 0, else return -1
761 * @param[in] ugd the pointer to the main data structure
763 int wfd_ug_get_connecting_peer(struct ug_data *ugd)
767 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
768 char *mac_addr = NULL;
769 GList *iterator = NULL;
771 ugd->mac_addr_connecting = NULL;
772 res = wifi_direct_get_connecting_peer(&mac_addr);
773 if (res != WIFI_DIRECT_ERROR_NONE) {
774 DBG(LOG_ERROR, "Get connecting device mac failed: %d\n", res);
777 DBG_SECURE(LOG_INFO, "Mac Addr Connecting: ["MACSECSTR"]\n",
778 MAC2SECSTR(mac_addr));
779 ugd->mac_addr_connecting = mac_addr;
781 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
782 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
783 ((device_type_s *)iterator->data)->conn_status = PEER_CONN_STATUS_CONNECTING;
794 * This function let the ug get the connected peers
795 * @return If success, return 0, else return -1
796 * @param[in] ugd the pointer to the main data structure
798 int wfd_ug_get_connected_peers(struct ug_data *ugd)
802 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
804 ugd->raw_connected_peer_cnt = 0;
805 res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
806 if (res != WIFI_DIRECT_ERROR_NONE) {
807 ugd->raw_connected_peer_cnt = 0;
808 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
816 * This function let the ug exits automatically after successed connection
818 * @param[in] user_data the pointer to the main data structure
820 void _wfd_ug_auto_exit(void *user_data)
823 struct ug_data *ugd = (struct ug_data *)user_data;
824 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
826 deinit_wfd_client(ugd);
832 gboolean wfd_delete_not_alive_peer_cb(void *user_data)
835 struct ug_data *ugd = (struct ug_data *)user_data;
836 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
838 delete_not_alive_peers(ugd, &ugd->gl_avlb_peers_start, &ugd->gl_available_peer_cnt);
839 delete_not_alive_peers(ugd, &ugd->gl_busy_peers_start, &ugd->gl_busy_peer_cnt);
840 delete_not_alive_peers(ugd, &ugd->multi_conn_dev_list_start, &ugd->gl_available_dev_cnt_at_multiconn_view);
841 wfd_ug_view_init_genlist(ugd, false);
842 wfd_update_multiconnect_device(ugd, false);
848 gboolean wfd_delete_progressbar_cb(void *user_data)
851 struct ug_data *ugd = (struct ug_data *)user_data;
852 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
854 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
855 if (ugd->raw_discovered_peer_cnt == 0 &&
856 ugd->nodevice_title_item == NULL &&
857 ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE &&
858 ugd->gl_available_peer_cnt == 0) {
859 _create_no_device_genlist(ugd);
862 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
863 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
865 if (0 == ugd->gl_available_dev_cnt_at_multiconn_view) {
866 _create_no_device_multiconnect_genlist(ugd);
869 wfd_refresh_wifi_direct_state(ugd);
870 if (WIFI_DIRECT_STATE_CONNECTING != ugd->wfd_status &&
871 WIFI_DIRECT_STATE_DISCONNECTING != ugd->wfd_status) {
872 if (ugd->scan_toolbar) {
873 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
874 evas_object_data_set(ugd->toolbar, "scan", "scan");
877 if (ugd->multiconn_layout) {
878 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
879 DBG(LOG_INFO, "Multiconn button text IDS_WIFI_SK4_SCAN \n");
889 * This function let the ug make a callback for registering discover event
891 * @param[in] error_code the returned error code
892 * @param[in] discovery_state the state of discover
893 * @param[in] user_data the pointer to the main data structure
895 void discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
899 struct ug_data *ugd = (struct ug_data *)user_data;
902 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
906 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
910 DBG(LOG_INFO, "Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
912 if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
913 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
914 ugd->title_content_mode = TITLE_CONTENT_TYPE_SCANNING;
915 wfd_cancel_progressbar_stop_timer(ugd);
916 ugd->timer_stop_progress_bar = g_timeout_add(1000*30, wfd_delete_progressbar_cb, ugd);
917 /* clear all the previous discovered peers */
918 wfd_client_free_raw_discovered_peers(ugd);
920 ugd->raw_discovered_peer_cnt = 0;
921 wfd_ug_view_init_genlist(ugd, false);
923 if (ugd->avlbl_wfd_item == NULL) {
924 _create_available_dev_genlist(ugd);
927 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
928 /* clear not alive peers after 5 secs */
929 wfd_cancel_not_alive_delete_timer(ugd);
930 ugd->timer_delete_not_alive_peer = g_timeout_add(1000*5, wfd_delete_not_alive_peer_cb, ugd);
931 set_not_alive_peers(ugd->gl_avlb_peers_start);
932 set_not_alive_peers(ugd->gl_busy_peers_start);
933 set_not_alive_peers(ugd->multi_conn_dev_list_start);
935 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
936 if (ugd->wfd_discovery_status != WIFI_DIRECT_DISCOVERY_NONE) {
937 wfd_ug_get_discovered_peers(ugd);
938 wfd_ug_update_available_peers(ugd);
939 wfd_update_multiconnect_device(ugd, false);
941 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FINISHED) {
942 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
943 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_FULL_SCAN_START;
944 ret = wifi_direct_start_discovery_specific_channel(false, 0, WIFI_DIRECT_DISCOVERY_FULL_SCAN);
945 if (ret != WIFI_DIRECT_ERROR_NONE) {
946 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
947 DBG(LOG_ERROR, "Failed to start discovery with full scan. [%d]\n", ret);
948 wifi_direct_cancel_discovery();
953 if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state &&
954 ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
955 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
956 if (!ugd->conn_wfd_item) {
957 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
959 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK_STOP", TRUE);
960 if (ugd->multiconn_scan_stop_btn) {
961 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK_STOP", TRUE);
970 * This function let the ug make a callback for registering connection event
972 * @param[in] error_code the returned error code
973 * @param[in] connection_state the state of connection
974 * @param[in] mac_address the mac address of peer
975 * @param[in] user_data the pointer to the main data structure
977 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
980 struct ug_data *ugd = (struct ug_data *)user_data;
981 device_type_s *peer = NULL;
985 if (mac_address == NULL) {
986 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
990 DBG_SECURE(LOG_INFO, "Connection event [%d], error_code [%d], multi_connect_mode [%d] mac ["MACSECSTR"]\n",
991 connection_state, error_code, ugd->multi_connect_mode, MAC2SECSTR(mac_address));
993 /* when not in connection, mac_address is empty */
994 if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
995 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
997 if (NULL == peer || '\0' == peer->ssid[0]) {
998 DBG(LOG_ERROR, "invalid peer from connection !!\n");
999 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1000 goto refresh_button;
1004 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
1005 switch (connection_state) {
1006 case WIFI_DIRECT_CONNECTION_RSP:
1007 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
1008 ugd->mac_addr_connecting = NULL;
1009 if (error_code == WIFI_DIRECT_ERROR_NONE) {
1010 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1011 wfd_ug_get_connected_peers(ugd);
1012 wfd_ug_update_connected_peers(ugd);
1014 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1015 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
1016 if ( peer != NULL) {
1017 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1018 wfd_ug_view_refresh_glitem(peer->gl_item);
1021 /* connect the next peer */
1022 ugd->g_source_multi_connect_next = g_timeout_add(500, wfd_multi_connect_next_cb, ugd);
1024 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1025 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1026 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1027 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
1029 if ( peer != NULL) {
1030 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1031 wfd_ug_view_refresh_glitem(peer->gl_item);
1034 wfd_ug_update_toolbar(ugd);
1036 case WIFI_DIRECT_GROUP_CREATED:
1037 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_GROUP_CREATED\n");
1038 wfd_cancel_progressbar_stop_timer(ugd);
1039 wfd_delete_progressbar_cb(ugd);
1041 wfd_ug_view_init_genlist(ugd, true);
1042 wfd_ug_view_update_multiconn_peers(ugd);
1043 wfd_multi_connect_next_cb(ugd);
1049 switch (connection_state) {
1050 case WIFI_DIRECT_CONNECTION_RSP:
1051 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_RSP\n");
1052 wfd_delete_progressbar_cb(ugd);
1054 if (ugd->act_popup) {
1055 evas_object_del(ugd->act_popup);
1056 ugd->act_popup = NULL;
1058 ugd->mac_addr_connecting = NULL;
1060 if (error_code == WIFI_DIRECT_ERROR_NONE) {
1061 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1062 wfd_ug_get_connected_peers(ugd);
1064 /* when auto_exit and not multi-connect*/
1065 if ((ugd->is_auto_exit)&&(ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE)) {
1066 _wfd_ug_auto_exit(ugd);
1069 wfd_ug_update_connected_peers(ugd);
1071 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1072 wfd_ug_update_failed_peers(ugd);
1075 wfd_ug_update_toolbar(ugd);
1077 case WIFI_DIRECT_DISASSOCIATION_IND:
1078 DBG(LOG_INFO, "WIFI_DIRECT_DISASSOCIATION_IND\n");
1079 /* remove any possible popup */
1080 WFD_IF_DEL_OBJ(ugd->act_popup);
1081 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
1083 /* change the multi connection mode, it can be connected now */
1084 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1085 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1088 /* if other peer disconnected, get connected peers and update */
1089 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
1090 wfd_ug_get_connected_peers(ugd);
1091 wfd_ug_update_available_peers(ugd);
1093 case WIFI_DIRECT_DISCONNECTION_RSP:
1094 case WIFI_DIRECT_DISCONNECTION_IND:
1095 DBG(LOG_INFO, "WIFI_DIRECT_DISCONNECTION_X\n");
1096 WFD_IF_DEL_OBJ(ugd->act_popup);
1098 Evas_Object *content;
1099 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1100 WFD_IF_DEL_OBJ(content);
1101 content = elm_object_part_content_unset(ugd->button_layout, "button.prev");
1102 evas_object_hide(content);
1104 /* when disconnection, clear all the connected peers */
1105 if (ugd->raw_connected_peer_cnt > 0) {
1106 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
1109 ugd->raw_connected_peer_cnt = 0;
1110 wfd_ug_view_init_genlist(ugd, true);
1111 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1112 DBG(LOG_INFO, "Background mode\n");
1116 if (ugd->is_paused == false) {
1117 /* start discovery again */
1118 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1119 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1120 if (res != WIFI_DIRECT_ERROR_NONE) {
1121 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1122 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1123 wifi_direct_cancel_discovery();
1128 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1129 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1130 wfd_ug_update_toolbar(ugd);
1131 wfd_cancel_progressbar_stop_timer(ugd);
1132 wfd_delete_progressbar_cb(ugd);
1134 if (ugd->multi_navi_item) {
1135 elm_naviframe_item_pop(ugd->naviframe);
1138 ugd->mac_addr_connecting = peer->mac_addr;
1139 ugd->is_conn_incoming = FALSE;
1140 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1141 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, peer->mac_addr);
1143 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1144 wfd_ug_view_refresh_glitem(peer->gl_item);
1146 wfd_ug_get_discovered_peers(ugd);
1147 wfd_ug_update_available_peers(ugd);
1151 case WIFI_DIRECT_CONNECTION_REQ:
1152 case WIFI_DIRECT_CONNECTION_WPS_REQ:
1153 ugd->mac_addr_connecting = peer->mac_addr;
1154 ugd->is_conn_incoming = TRUE;
1155 DBG(LOG_INFO, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
1157 case WIFI_DIRECT_GROUP_DESTROYED:
1158 wfd_ug_update_toolbar(ugd);
1159 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1160 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1162 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1163 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1164 if (res != WIFI_DIRECT_ERROR_NONE) {
1165 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1166 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1167 wifi_direct_cancel_discovery();
1178 /* refresh the scan button */
1179 wfd_refresh_wifi_direct_state(ugd);
1180 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
1181 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
1182 res = wifi_direct_is_group_owner(&owner);
1183 if (res == WIFI_DIRECT_ERROR_NONE) {
1185 if (ugd->scan_toolbar) {
1186 evas_object_data_set(ugd->toolbar, "scan", "scan");
1189 if (ugd->multiconn_scan_stop_btn) {
1190 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1194 DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
1197 if (ugd->scan_toolbar) {
1198 evas_object_data_set(ugd->toolbar, "scan", "scan");
1201 if (ugd->multiconn_scan_stop_btn) {
1202 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
1211 * This function let the ug make a callback for registering ip assigned event
1213 * @param[in] mac_address the mac address of peer
1214 * @param[in] ip_address the ip address of peer
1215 * @param[in] interface_address the interface address
1216 * @param[in] user_data the pointer to the main data structure
1218 void _ip_assigned_cb(const char *mac_address, const char *ip_address, const char *interface_address, void *user_data)
1223 DBG(LOG_ERROR, "The user_data is NULL\n");
1227 struct ug_data *ugd = (struct ug_data *)user_data;
1229 if (!ip_address || 0 == strncmp(ip_address, "0.0.0.0", 7)) {
1230 DBG(LOG_ERROR,"ip address is invalid.\n");
1234 ugd->peer_ip_address = strdup(ip_address);
1237 /* to send ip_addr*/
1239 app_control_h control = NULL;
1240 ret = app_control_create(&control);
1242 DBG(LOG_ERROR, "Failed to create control");
1245 app_control_add_extra_data(control, "ip_address", ugd->peer_ip_address);
1246 app_control_add_extra_data(control, "wfds", ugd->service_name);
1247 ug_send_result(ugd->ug, control);
1248 app_control_destroy(control);
1250 /* when auto_exit and not multi-connect*/
1251 if ((ugd->is_auto_exit)&&(ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE)) {
1252 _wfd_ug_auto_exit(ugd);
1259 * This function let the ug get wi-fi direct status from vconf
1260 * @return If success, return the wfd status, else return -1
1263 int wfd_get_vconf_status()
1266 int wifi_direct_state = 0;
1268 /* get wifi direct status from vconf */
1269 if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
1270 DBG(LOG_ERROR, "Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
1273 DBG(LOG_INFO, "WiFi Direct State [%d]", wifi_direct_state);
1276 return wifi_direct_state;
1280 * This function let the ug get device name from vconf
1281 * @return If success, return 0, else return -1
1282 * @param[in] data the pointer to the main data structure
1284 int wfd_get_vconf_device_name(void *data)
1287 struct ug_data *ugd = (struct ug_data *)data;
1288 char *dev_name = NULL;
1290 /* get device name from vconf */
1291 dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1292 if (dev_name == NULL) {
1293 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1294 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
1298 ugd->dev_name = strdup(dev_name);
1299 WFD_IF_FREE_MEM(dev_name);
1306 * This function let the ug refresh current status of wi-fi direct
1307 * @return If success, return 0, else return -1
1308 * @param[in] data the pointer to the main data structure
1310 int wfd_refresh_wifi_direct_state(void *data)
1313 struct ug_data *ugd = (struct ug_data *)data;
1315 wifi_direct_state_e wfd_status;
1317 res = wifi_direct_get_state(&wfd_status);
1318 if (res != WIFI_DIRECT_ERROR_NONE) {
1319 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
1323 DBG(LOG_INFO, "WFD status [%d]", wfd_status);
1324 ugd->wfd_status = wfd_status;
1330 void wfd_init_ug_by_status(void *user_data)
1333 struct ug_data *ugd = (struct ug_data *)user_data;
1337 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
1341 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) {
1342 //wfd_ug_get_discovered_peers(ugd);
1343 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1346 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
1347 wfd_ug_get_connected_peers(ugd);
1348 wfd_ug_update_connected_peers(ugd);
1349 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1350 wfd_ug_get_discovered_peers(ugd);
1351 wfd_ug_update_available_peers(ugd);
1352 wfd_ug_update_toolbar(ugd);
1355 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1356 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1357 wfd_ug_get_discovered_peers(ugd);
1358 wfd_ug_get_connecting_peer(ugd);
1359 wfd_ug_update_available_peers(ugd);
1360 wfd_ug_update_toolbar(ugd);
1363 if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED ||
1364 ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1365 /* start discovery */
1366 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1367 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1368 if (res != WIFI_DIRECT_ERROR_NONE) {
1369 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1370 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1371 wifi_direct_cancel_discovery();
1379 * This function let the ug do initialization
1380 * @return If success, return 0, else return -1
1381 * @param[in] data the pointer to the main data structure
1383 int init_wfd_client(void* data)
1386 WFD_RETV_IF(data == NULL, -1, "Incorrect parameter(NULL)\n");
1387 struct ug_data *ugd = (struct ug_data *)data;
1390 res = wifi_direct_initialize();
1391 if (res != WIFI_DIRECT_ERROR_NONE) {
1392 if (res != WIFI_DIRECT_ERROR_ALREADY_INITIALIZED) {
1393 DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
1396 DBG(LOG_ERROR, "Already registered\n");
1400 res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1401 if (res != WIFI_DIRECT_ERROR_NONE) {
1402 DBG(LOG_ERROR, "Failed to register _cb_activation. error code = [%d]\n", res);
1406 res = wifi_direct_set_discovery_state_changed_cb(discover_cb, (void *)ugd);
1407 if (res != WIFI_DIRECT_ERROR_NONE) {
1408 DBG(LOG_ERROR, "Failed to register _cb_discover. error code = [%d]\n", res);
1412 res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1413 if (res != WIFI_DIRECT_ERROR_NONE) {
1414 DBG(LOG_ERROR, "Failed to register _cb_connection. error code = [%d]\n", res);
1418 res = wifi_direct_set_client_ip_address_assigned_cb(_ip_assigned_cb, (void *)ugd);
1419 if (res != WIFI_DIRECT_ERROR_NONE) {
1420 DBG(LOG_ERROR, "Failed to register _ip_assigned_cb. error code = [%d]\n", res);
1424 /* update WFD status */
1425 wfd_refresh_wifi_direct_state(ugd);
1426 #ifdef WFD_ON_OFF_GENLIST
1427 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1429 wfd_ug_refresh_on_off_check(ugd);
1435 DBG(LOG_INFO, "WFD link status. [%d]\n", ugd->wfd_status);
1436 ugd->is_init_ok = TRUE;
1437 wfd_init_ug_by_status(ugd);
1443 #ifdef WFD_DBUS_LAUNCH
1444 void wfd_gdbus_callback(GObject *source_object, GAsyncResult *result, gpointer user_data)
1447 struct ug_data *ugd = (struct ug_data *)user_data;
1448 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1451 GError *error = NULL;
1452 GVariant *return_data;
1454 g_object_unref(ugd->dbus_cancellable);
1455 ugd->dbus_cancellable = NULL;
1456 ugd->conn = G_DBUS_CONNECTION (source_object);
1457 return_data = g_dbus_connection_call_finish(ugd->conn, result, &error);
1459 if (error != NULL) {
1460 DBG(LOG_ERROR,"DBus action failed. Error Msg [%s]\n", error->message);
1461 g_clear_error(&error);
1463 DBG(LOG_INFO, "error msg is NULL\n");
1467 g_variant_unref(return_data);
1470 g_object_unref(ugd->conn);
1474 res = init_wfd_client(ugd);
1475 WFD_RET_IF(res != 0, "Failed to initialize WFD client library\n");
1477 /* Activate WiFi Direct */
1478 DBG(LOG_INFO, "Activating WiFi Direct...");
1479 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1480 res = wfd_client_switch_on(ugd);
1481 WFD_RET_IF(res != 0, "Failed to activate WFD\n");
1487 int launch_wifi_direct_manager(void *data)
1492 GError *error = NULL;
1494 struct ug_data *ugd = (struct ug_data *)data;
1495 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
1497 ugd->dbus_cancellable = g_cancellable_new();
1499 addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1500 WFD_RETV_IF(addr == NULL, -1, "Fail to get dbus addr.\n");
1502 ugd->conn = g_dbus_connection_new_for_address_sync(addr,G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
1503 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, NULL, NULL, NULL);
1505 if(ugd->conn == NULL) {
1506 DBG(LOG_ERROR,"g_dbus_conn is NULL\n");
1509 g_dbus_connection_call(ugd->conn, "net.netconfig", "/net/netconfig/wifi","net.netconfig.wifi",
1510 "LaunchDirect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, ugd->dbus_cancellable, wfd_gdbus_callback, data);
1518 void wfd_client_destroy_tethering(struct ug_data *ugd)
1522 tethering_error_e ret = TETHERING_ERROR_NONE;
1524 if (ugd->hotspot_handle != NULL) {
1525 /* Deregister cbs */
1526 ret = tethering_unset_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1527 if (ret != TETHERING_ERROR_NONE) {
1528 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
1531 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1532 if (ret != TETHERING_ERROR_NONE) {
1533 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1536 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
1537 if (ret != TETHERING_ERROR_NONE) {
1538 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1541 /* Destroy tethering handle */
1542 ret = tethering_destroy(ugd->hotspot_handle);
1543 if (ret != TETHERING_ERROR_NONE) {
1544 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
1547 ugd->hotspot_handle = NULL;
1554 * This function let the ug do de-initialization
1555 * @return If success, return 0, else return -1
1556 * @param[in] data the pointer to the main data structure
1558 int deinit_wfd_client(void *data)
1561 struct ug_data *ugd = (struct ug_data *)data;
1564 wfd_refresh_wifi_direct_state(ugd);
1566 if ((WIFI_DIRECT_STATE_DISCOVERING == ugd->wfd_status) &&
1567 (WIFI_DIRECT_ERROR_NONE != wifi_direct_cancel_discovery())) {
1568 DBG(LOG_ERROR, "Failed to send cancel discovery state [%d]\n", ugd->wfd_status);
1571 wfd_cancel_progressbar_stop_timer(ugd);
1572 wfd_cancel_not_alive_delete_timer(ugd);
1574 if(ugd->timer_multi_reset > 0) {
1575 g_source_remove(ugd->timer_multi_reset);
1577 ugd->timer_multi_reset = 0;
1579 if (ugd->g_source_multi_connect_next > 0) {
1580 g_source_remove(ugd->g_source_multi_connect_next);
1582 ugd->g_source_multi_connect_next = 0;
1584 res = wifi_direct_unset_discovery_state_changed_cb();
1585 if (res != WIFI_DIRECT_ERROR_NONE) {
1586 DBG(LOG_ERROR, "Failed to unset discovery state changed cb. [%d]\n", res);
1589 wifi_direct_unset_device_state_changed_cb();
1590 if (res != WIFI_DIRECT_ERROR_NONE) {
1591 DBG(LOG_ERROR, "Failed to unset device state changed cb. [%d]\n", res);
1594 wifi_direct_unset_connection_state_changed_cb();
1595 if (res != WIFI_DIRECT_ERROR_NONE) {
1596 DBG(LOG_ERROR, "Failed to unset connection state changed cb. [%d]\n", res);
1599 wifi_direct_unset_client_ip_address_assigned_cb();
1600 if (res != WIFI_DIRECT_ERROR_NONE) {
1601 DBG(LOG_ERROR, "Failed to unset client ip address assigned cb. [%d]\n", res);
1604 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING &&
1605 NULL != ugd->mac_addr_connecting) {
1606 if (ugd->is_conn_incoming) {
1607 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
1608 res = wifi_direct_reject_connection(ugd->mac_addr_connecting);
1609 if (res != WIFI_DIRECT_ERROR_NONE) {
1610 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", res);
1613 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
1614 res = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
1615 if (res != WIFI_DIRECT_ERROR_NONE) {
1616 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", res);
1619 ugd->mac_addr_connecting = NULL;
1623 res = wifi_direct_deinitialize();
1624 if (res != WIFI_DIRECT_ERROR_NONE) {
1625 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
1628 /* release vconf, hotspot.. */
1629 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1630 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1632 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
1635 res = net_deregister_client();
1636 if (res != NET_ERR_NONE) {
1637 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
1639 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1642 wfd_client_destroy_tethering(ugd);
1649 * This function let the ug turn wi-fi direct on
1650 * @return If success, return 0, else return -1
1651 * @param[in] data the pointer to the main data structure
1653 int wfd_client_switch_on(void *data)
1656 struct ug_data *ugd = (struct ug_data *)data;
1659 bool is_wifi_enabled = false;
1660 bool is_wifi_ap_enabled = false;
1663 if(!ugd->is_init_ok) {
1664 DBG(LOG_ERROR, "device is initializing, please wait\n");
1668 wfd_refresh_wifi_direct_state(ugd);
1669 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1671 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1673 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1675 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1677 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
1680 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1682 ugd->hotspot_handle = NULL;
1683 res = tethering_create(&(ugd->hotspot_handle));
1684 if (res != TETHERING_ERROR_NONE) {
1685 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", res);
1688 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
1691 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1692 is_wifi_ap_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
1694 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1695 if (wifi_state > VCONFKEY_WIFI_OFF) {
1696 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1697 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);
1699 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1701 if (is_wifi_enabled || is_wifi_ap_enabled) {
1702 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1703 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);
1707 res = wifi_direct_activate();
1708 if (res != WIFI_DIRECT_ERROR_NONE) {
1709 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1710 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1711 #ifdef WFD_ON_OFF_GENLIST
1712 wfd_ug_refresh_on_off_check(ugd);
1717 #ifdef WFD_ON_OFF_GENLIST
1718 if (ugd->on_off_check) {
1719 elm_check_state_set(ugd->on_off_check, TRUE);
1720 elm_object_disabled_set(ugd->on_off_check, TRUE);
1723 /* while activating, disable the buttons */
1724 if (ugd->scan_toolbar == NULL) {
1725 scan_button_create(ugd);
1728 if (ugd->scan_toolbar) {
1729 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1732 if (ugd->multiconn_scan_stop_btn) {
1733 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1736 if (ugd->back_btn) {
1737 elm_object_disabled_set(ugd->back_btn, TRUE);
1741 DBG(LOG_INFO, "Wi-Fi Direct is already activated\n");
1749 * This function let the ug turn wi-fi direct off
1750 * @return If success, return 0, else return -1
1751 * @param[in] data the pointer to the main data structure
1753 int wfd_client_switch_off(void *data)
1756 struct ug_data *ugd = (struct ug_data *)data;
1759 wfd_ug_view_free_peers(ugd);
1760 wfd_free_nodivice_item(ugd);
1762 wfd_refresh_wifi_direct_state(ugd);
1763 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1765 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1766 DBG(LOG_INFO, "Wi-Fi Direct is already deactivated\n");
1769 wfd_client_destroy_tethering(ugd);
1771 wfd_cancel_progressbar_stop_timer(ugd);
1772 wfd_cancel_not_alive_delete_timer(ugd);
1774 if(ugd->timer_multi_reset > 0) {
1775 g_source_remove(ugd->timer_multi_reset);
1777 ugd->timer_multi_reset = 0;
1779 if (ugd->g_source_multi_connect_next > 0) {
1780 g_source_remove(ugd->g_source_multi_connect_next);
1782 ugd->g_source_multi_connect_next = 0;
1784 /*if connected, disconnect all devices*/
1785 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1786 res = wifi_direct_disconnect_all();
1787 if (res != WIFI_DIRECT_ERROR_NONE) {
1788 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1793 res = wifi_direct_deactivate();
1794 if (res != WIFI_DIRECT_ERROR_NONE) {
1795 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1796 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE_DEACTIVATE_FAIL);
1797 #ifdef WFD_ON_OFF_GENLIST
1798 wfd_ug_refresh_on_off_check(ugd);
1803 /* while deactivating, disable the buttons */
1804 if (ugd->scan_toolbar) {
1805 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1806 evas_object_del(ugd->scan_toolbar);
1807 ugd->scan_toolbar = NULL;
1810 if (ugd->multiconn_scan_stop_btn) {
1811 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1814 if (ugd->multi_connect_toolbar_item) {
1815 elm_object_item_disabled_set(ugd->multi_connect_toolbar_item, TRUE);
1818 if (ugd->back_btn) {
1819 elm_object_disabled_set(ugd->back_btn, TRUE);
1827 #ifdef WFD_ON_OFF_GENLIST
1829 * This function let the ug turn wi-fi direct on/off forcely
1830 * @return If success, return 0, else return -1
1831 * @param[in] data the pointer to the main data structure
1832 * @param[in] onoff whether to turn on/off wi-fi direct
1834 int wfd_client_swtch_force(void *data, int onoff)
1837 struct ug_data *ugd = (struct ug_data *)data;
1841 res = wifi_direct_activate();
1842 if (res != WIFI_DIRECT_ERROR_NONE) {
1843 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1844 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1845 wfd_ug_refresh_on_off_check(ugd);
1849 res = wifi_direct_deactivate();
1850 if (res != WIFI_DIRECT_ERROR_NONE) {
1851 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1852 wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE);
1853 wfd_ug_refresh_on_off_check(ugd);
1864 * This function let the ug create a group
1865 * @return If success, return 0, else return -1
1867 int wfd_client_group_add()
1872 res = wifi_direct_create_group();
1873 if (res != WIFI_DIRECT_ERROR_NONE) {
1874 DBG(LOG_ERROR, "Failed to add group");
1884 * This function let the ug connect to the device by mac address
1885 * @return If success, return 0, else return -1
1886 * @param[in] mac_addr the pointer to the mac address of device
1888 int wfd_client_connect(const char *mac_addr)
1893 DBG_SECURE(LOG_INFO, "connect to peer=["MACSECSTR"]\n", MAC2SECSTR(mac_addr));
1894 res = wifi_direct_connect((char *)mac_addr);
1895 if (res != WIFI_DIRECT_ERROR_NONE) {
1896 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
1905 * This function let the ug disconnect to the device by mac address
1906 * @return If success, return 0, else return -1
1907 * @param[in] mac_addr the pointer to the mac address of device
1909 int wfd_client_disconnect(const char *mac_addr)
1914 wifi_direct_cancel_discovery();
1916 * No need to handle return in cancel discovery as there maybe case
1917 * when framework can return failure.
1920 if (mac_addr == NULL) {
1921 res = wifi_direct_disconnect_all();
1922 if (res != WIFI_DIRECT_ERROR_NONE) {
1923 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1927 res = wifi_direct_disconnect((char *)mac_addr);
1928 if (res != WIFI_DIRECT_ERROR_NONE) {
1929 DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
1939 * This function let the ug set the intent of a group owner
1940 * @return If success, return 0, else return -1
1941 * @param[in] go_intent the intent parameter
1943 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1948 res = wifi_direct_set_group_owner_intent(go_intent);
1949 if (res != WIFI_DIRECT_ERROR_NONE) {
1950 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);