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>
33 #include <wifi-direct.h>
36 #include "wfd_ug_view.h"
37 #include "wfd_client.h"
39 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data);
41 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
43 * This function let the ug make a change callback for wifi state
45 * @param[in] key the pointer to the key
46 * @param[in] data the pointer to the main data structure
48 static void _wifi_state_cb(keynode_t *key, void *data)
51 struct ug_data *ugd = (struct ug_data *)data;
55 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
57 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
61 if (wifi_state == VCONFKEY_WIFI_OFF) {
62 DBG(LOG_INFO, "WiFi is turned off\n");
63 wfd_client_swtch_force(ugd, TRUE);
65 DBG(LOG_INFO, "WiFi is turned on\n");
68 res = net_deregister_client();
69 if (res != NET_ERR_NONE) {
70 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
77 * This function let the ug make a event callback for network registering
79 * @param[in] event_info the pointer to the information of network event
80 * @param[in] user_data the pointer to the user data
82 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
85 DBG(LOG_INFO, "Event from network. [%d]\n", event_info->Event);
90 * This function let the ug turn wifi off
91 * @return If success, return 0, else return -1
92 * @param[in] data the pointer to the main data structure
94 int wfd_wifi_off(void *data)
97 struct ug_data *ugd = (struct ug_data *)data;
100 res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
102 DBG(LOG_ERROR, "Failed to register vconf callback\n");
106 DBG(LOG_INFO, "Vconf key callback is registered\n");
108 res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
109 if (res != NET_ERR_NONE) {
110 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
114 DBG(LOG_INFO, "Network client is registered\n");
116 res = net_wifi_power_off();
117 if (res != NET_ERR_NONE) {
118 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
122 DBG(LOG_INFO, "WiFi power off\n");
127 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
131 * This function let the ug make a callback for setting tethering mode enabled
133 * @param[in] error the returned error code
134 * @param[in] type the type of tethering
135 * @param[in] is_requested whether tethering mode is enabled
136 * @param[in] data the pointer to the user data
138 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
141 struct ug_data *ugd = (struct ug_data *)data;
142 tethering_error_e ret = TETHERING_ERROR_NONE;
143 tethering_h th = NULL;
144 bool is_wifi_enabled = false;
146 if (error != TETHERING_ERROR_NONE) {
147 if (is_requested != TRUE) {
151 DBG(LOG_ERROR, "error !!! TETHERING is not enabled.\n");
155 th = ugd->hotspot_handle;
157 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
158 if (is_wifi_enabled) {
159 DBG(LOG_INFO, "Mobile hotspot is activated\n");
163 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
164 if (ret != TETHERING_ERROR_NONE) {
165 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
168 /* Destroy tethering handle */
169 ret = tethering_destroy(th);
170 if (ret != TETHERING_ERROR_NONE) {
171 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
174 ugd->hotspot_handle = NULL;
177 DBG(LOG_INFO, "TETHERING is enabled.\n");
184 * This function let the ug make a callback for setting tethering mode disabled
186 * @param[in] error the returned error code
187 * @param[in] type the type of tethering
188 * @param[in] code whether tethering mode is enabled
189 * @param[in] data the pointer to the user data
191 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
195 struct ug_data *ugd = (struct ug_data *)data;
196 tethering_error_e ret = TETHERING_ERROR_NONE;
197 tethering_h th = NULL;
198 bool is_wifi_enabled = false;
199 bool is_wifi_ap_enabled = false;
201 if (error != TETHERING_ERROR_NONE) {
202 if (code != TETHERING_DISABLED_BY_REQUEST) {
206 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
210 th = ugd->hotspot_handle;
212 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
213 is_wifi_ap_enabled = tethering_is_enabled(th, TETHERING_TYPE_RESERVED);
214 if (is_wifi_enabled || is_wifi_ap_enabled) {
215 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
216 DBG(LOG_ERROR, "is_wifi_enabled:%d is_wifi_ap_enabled:%d\n", is_wifi_enabled, is_wifi_ap_enabled);
220 DBG(LOG_INFO, "Mobile hotspot is deactivated\n");
221 wfd_client_swtch_force(ugd, TRUE);
223 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
224 if (ret != TETHERING_ERROR_NONE) {
225 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
228 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_RESERVED);
229 if (ret != TETHERING_ERROR_NONE) {
230 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
233 /* Destroy tethering handle */
234 ret = tethering_destroy(th);
235 if (ret != TETHERING_ERROR_NONE) {
236 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
239 ugd->hotspot_handle = NULL;
242 DBG(LOG_INFO, "TETHERING is disabled.\n");
249 * This function let the ug turn AP on
250 * @return If success, return 0, else return -1
251 * @param[in] data the pointer to the main data structure
253 int wfd_mobile_ap_on(void *data)
256 struct ug_data *ugd = (struct ug_data *)data;
257 tethering_error_e ret = TETHERING_ERROR_NONE;
258 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
260 if (NULL == ugd->hotspot_handle) {
261 ret = tethering_create(&(ugd->hotspot_handle));
262 if (TETHERING_ERROR_NONE != ret) {
263 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
264 ugd->hotspot_handle = NULL;
267 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
270 ret = tethering_set_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __enabled_cb, ugd);
271 if (ret != TETHERING_ERROR_NONE) {
272 DBG(LOG_ERROR, "tethering_set_enabled_cb is failed\n", ret);
276 /* Enable tethering */
277 ret = tethering_enable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
278 if (ret != TETHERING_ERROR_NONE) {
279 DBG(LOG_ERROR, "Failed to turn on mobile hotspot. [%d]\n", ret);
282 DBG(LOG_INFO, "Succeeded to turn on mobile hotspot\n");
285 ugd->is_hotspot_off = FALSE;
292 * This function let the ug turn AP off
293 * @return If success, return 0, else return -1
294 * @param[in] data the pointer to the main data structure
296 int wfd_mobile_ap_off(void *data)
299 struct ug_data *ugd = (struct ug_data *)data;
300 WFD_RETV_IF(ugd == NULL || ugd->hotspot_handle == NULL, -1, "Incorrect parameter(NULL)\n");
301 tethering_error_e ret = TETHERING_ERROR_NONE;
302 bool is_wifi_enabled = false;
303 bool is_wifi_ap_enabled = false;
305 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
306 is_wifi_ap_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
308 if (is_wifi_enabled) {
310 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __disabled_cb, ugd);
311 if (ret != TETHERING_ERROR_NONE) {
312 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
315 /* Disable tethering */
316 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
317 } else if (is_wifi_ap_enabled) {
318 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_RESERVED, __disabled_cb, ugd);
319 if (ret != TETHERING_ERROR_NONE) {
320 DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
323 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
326 if (ret != TETHERING_ERROR_NONE) {
327 DBG(LOG_ERROR, "Failed to turn off mobile hotspot. [%d]\n", ret);
330 DBG(LOG_INFO, "Succeeded to turn off mobile hotspot\n");
333 ugd->is_hotspot_off = TRUE;
339 void wfd_client_free_raw_discovered_peers(struct ug_data *ugd)
342 WFD_RET_IF(ugd->raw_discovered_peer_list == NULL, "Incorrect parameter(NULL)\n");
344 g_list_free(ugd->raw_discovered_peer_list);
345 ugd->raw_discovered_peer_list = NULL;
351 * This function let the ug find the peer by mac address
352 * @return the found peer
353 * @param[in] data the pointer to the main data structure
354 * @param[in] mac_addr the pointer to mac address
356 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
359 struct ug_data *ugd = (struct ug_data *)data;
360 wifi_direct_discovered_peer_info_s *peer_info = NULL;
361 GList *iterator = NULL;
363 WFD_RETV_IF(ugd == NULL, NULL, "Incorrect parameter(NULL)\n");
365 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
366 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
367 if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH)) {
368 return &ugd->raw_multi_selected_peers[i];
372 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
373 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
374 return (device_type_s *)iterator->data;
380 * In case, device is not in raw discovered list, then get peer info.
381 * There could be situation in which device is not yet discovered and
382 * connected process started.
384 if (WIFI_DIRECT_ERROR_NONE != wifi_direct_get_peer_info((char *)mac_addr, &peer_info) ||
386 DBG(LOG_ERROR, "Peer Not Found !!!");
390 /* Update peer list */
391 DBG(LOG_INFO, "Update Peer info");
392 _wfd_discoverd_peer_cb(peer_info, (void *)ugd);
394 /* Get the device from peer list */
395 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
396 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
397 return (device_type_s *)iterator->data;
406 * This function let the ug make a callback for registering activation event
408 * @param[in] error_code the returned error code
409 * @param[in] device_state the state of device
410 * @param[in] user_data the pointer to the main data structure
412 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
416 struct ug_data *ugd = (struct ug_data *)user_data;
417 wfd_refresh_wifi_direct_state(ugd);
419 switch (device_state) {
420 case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
421 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
422 if(ugd->scan_toolbar == NULL) {
423 scan_button_create(ugd);
425 if (error_code != WIFI_DIRECT_ERROR_NONE) {
426 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
427 if (WIFI_DIRECT_ERROR_AUTH_FAILED == error_code) {
428 wfd_ug_warn_popup(ugd, _("IDS_COM_POP_SECURITY_POLICY_RESTRICTS_USE_OF_WI_FI"), POPUP_TYPE_ACTIVATE_FAIL_POLICY_RESTRICTS);
430 wfd_ug_warn_popup(ugd, _("IDS_COM_POP_FAILED"), POPUP_TYPE_ACTIVATE_FAIL);
433 #ifdef WFD_ON_OFF_GENLIST
435 wfd_ug_refresh_on_off_check(ugd);
440 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
441 #ifdef WFD_ON_OFF_GENLIST
443 wfd_ug_refresh_on_off_check(ugd);
445 wfg_ug_act_popup_remove(ugd);
447 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
448 DBG(LOG_INFO, "Background mode\n");
452 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
453 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
455 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
457 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
459 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
460 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
461 if (res != WIFI_DIRECT_ERROR_NONE) {
462 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
463 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
464 wifi_direct_cancel_discovery();
468 case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
469 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
470 if (error_code != WIFI_DIRECT_ERROR_NONE) {
471 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
472 wfd_ug_warn_popup(ugd, _("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_DEACTIVATE_FAIL);
473 #ifdef WFD_ON_OFF_GENLIST
475 wfd_ug_refresh_on_off_check(ugd);
480 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
483 ctxpopup_dismissed_cb(ugd, NULL, NULL);
487 * When multi-connect is on ongoing and deactivte happened destroy
490 if (ugd->disconnect_btn) {
491 Evas_Object *content;
492 content = elm_object_part_content_unset(ugd->layout, "button.next");
493 WFD_IF_DEL_OBJ(content);
494 ugd->disconnect_btn = NULL;
495 elm_object_part_content_set(ugd->layout, "button.big",
499 /* When connect is on ongoing and deactivte happened refresh scan */
500 if (ugd->scan_toolbar) {
501 wfd_ug_view_refresh_button(ugd->scan_toolbar,
502 "IDS_WIFI_SK4_SCAN", FALSE);
504 /* Delete pop-up when deactivate happens */
505 WFD_IF_DEL_OBJ(ugd->act_popup);
506 /* Remove timeout handlers */
507 if (ugd->timer_stop_progress_bar > 0)
508 g_source_remove(ugd->timer_stop_progress_bar);
510 if (ugd->timer_delete_not_alive_peer > 0)
511 g_source_remove(ugd->timer_delete_not_alive_peer);
513 if (ugd->g_source_multi_connect_next > 0)
514 g_source_remove(ugd->g_source_multi_connect_next);
516 if (ugd->timer_multi_reset > 0)
517 g_source_remove(ugd->timer_multi_reset);
519 /* Delete warn popups for Airplane mode */
520 if (NULL != ugd->warn_popup) {
521 evas_object_del( ugd->warn_popup);
522 ugd->warn_popup = NULL;
525 #ifdef WFD_ON_OFF_GENLIST
527 wfd_ug_refresh_on_off_check(ugd);
530 * when deactivated, clear all the
531 * discovered peers and connected peers
533 wfd_client_free_raw_discovered_peers(ugd);
534 if (ugd->raw_connected_peer_cnt > 0) {
535 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
538 ugd->raw_discovered_peer_cnt = 0;
539 ugd->raw_connected_peer_cnt = 0;
541 wfd_free_nodivice_item(ugd);
542 wfd_ug_view_init_genlist(ugd, true);
544 if (ugd->multi_navi_item != NULL) {
545 elm_naviframe_item_pop(ugd->naviframe);
548 if (TRUE == ugd->is_hotspot_off && TRUE == ugd->is_hotspot_locally_disabled) {
549 if (0 == wfd_mobile_ap_on(ugd)) {
550 ugd->is_hotspot_locally_disabled = FALSE;
554 if(ugd->scan_toolbar) {
555 evas_object_del(ugd->scan_toolbar);
556 ugd->scan_toolbar = NULL;
563 /*if (ugd->scan_toolbar) {
564 wfd_ug_view_refresh_button(ugd->scan_toolbar, _("IDS_WIFI_SK4_SCAN"), TRUE);
567 if (ugd->multiconn_scan_stop_btn) {
568 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
572 elm_object_disabled_set(ugd->back_btn, FALSE);
580 * This function let the ug make a callback for discovering peer
582 * @param[in] peer the pointer to the discovered peer
583 * @param[in] user_data the pointer to the main data structure
585 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
588 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
590 struct ug_data *ugd = (struct ug_data *)user_data;
591 int peer_cnt = ugd->raw_discovered_peer_cnt;
592 device_type_s *peer_tmp = g_new(device_type_s, 1);
595 DBG_SECURE(LOG_INFO, "%dth discovered peer. [%s] ["MACSECSTR"]\n", peer_cnt,
596 peer->device_name, MAC2SECSTR(peer->mac_address));
598 if (ugd->device_filter < 0 || peer->primary_device_type == ugd->device_filter) {
599 strncpy(peer_tmp->ssid, peer->device_name, sizeof(peer_tmp->ssid) - 1);
600 peer_tmp->ssid[SSID_LENGTH - 1] = '\0';
601 peer_tmp->category = peer->primary_device_type;
602 peer_tmp->sub_category = peer->secondary_device_type;
603 strncpy(peer_tmp->mac_addr, peer->mac_address, MAC_LENGTH - 1);
604 peer_tmp->mac_addr[MAC_LENGTH - 1] = '\0';
605 strncpy(peer_tmp->if_addr, peer->interface_address, MAC_LENGTH - 1);
606 peer_tmp->if_addr[MAC_LENGTH - 1] = '\0';
607 peer_tmp->is_group_owner = peer->is_group_owner;
608 peer_tmp->is_persistent_group_owner = peer->is_persistent_group_owner;
609 peer_tmp->is_connected = peer->is_connected;
610 peer_tmp->dev_sel_state = FALSE;
612 if (TRUE == peer->is_connected) {
613 peer_tmp->conn_status = PEER_CONN_STATUS_CONNECTED;
615 peer_tmp->conn_status = PEER_CONN_STATUS_DISCONNECTED;
618 ugd->raw_discovered_peer_list = g_list_append(ugd->raw_discovered_peer_list, peer_tmp);
619 DBG(LOG_INFO, "\tSSID: [%s]\n", peer_tmp->ssid);
620 DBG(LOG_INFO, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peer_tmp->category);
621 DBG(LOG_INFO, "\tStatus: [%d]\n", peer_tmp->conn_status);
622 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
623 ugd->raw_discovered_peer_cnt++;
625 DBG(LOG_INFO, "Unavailable WiFi-Direct Device\n");
628 WFD_IF_FREE_MEM(peer->device_name);
629 WFD_IF_FREE_MEM(peer->mac_address);
630 WFD_IF_FREE_MEM(peer->interface_address);
632 if (NULL != peer->service_list)
634 for (i=0; i<peer->service_count && peer->service_list[i] != NULL; i++) {
635 free(peer->service_list[i]);
637 WFD_IF_FREE_MEM(peer->service_list);
640 WFD_IF_FREE_MEM(peer);
647 * This function let the ug make a callback for connected peer
649 * @param[in] peer the pointer to the connected peer
650 * @param[in] user_data the pointer to the main data structure
652 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
655 WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
657 struct ug_data *ugd = (struct ug_data *)user_data;
658 int peer_cnt = ugd->raw_connected_peer_cnt;
661 DBG_SECURE(LOG_INFO, "%dth connected peer. [%s] ["MACSECSTR"]\n", peer_cnt,
662 peer->device_name, MAC2SECSTR(peer->mac_address));
665 * check wether ug needs to exit
666 * automatically after successed connection
669 char services[256] = {0,};
670 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
671 if (peer->service_count>0) {
672 unsigned int len = 0;
673 for (i=0; i<peer->service_count && peer->service_list != NULL; i++) {
674 snprintf(services + len, 256-len, "%s ", peer->service_list[i]);
675 len = len + strlen(peer->service_list[i]) + 1;
677 DBG(LOG_INFO, "\tServices: [%s]\n", services);
680 strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid) - 1);
681 ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
682 ugd->raw_connected_peers[peer_cnt].sub_category = peer->secondary_device_type;
683 strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH - 1);
684 strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH - 1);
685 ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
687 DBG(LOG_INFO, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
688 DBG(LOG_INFO, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
689 DBG(LOG_INFO, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
691 ugd->raw_connected_peer_cnt++;
694 bool is_group_owner = FALSE;
695 error = wifi_direct_is_group_owner(&is_group_owner);
696 if (error != WIFI_DIRECT_ERROR_NONE) {
697 DBG(LOG_ERROR, "Fail to get group_owner_state. ret=[%d]", error);
701 if (FALSE == is_group_owner) {
704 app_control_h control = NULL;
705 ret = app_control_create(&control);
707 DBG(LOG_ERROR, "Failed to create control");
711 if(peer->ip_address != NULL && strlen(services) != 0 ) {
712 app_control_add_extra_data(control, "ip_address", peer->ip_address);
713 app_control_add_extra_data(control, "wfds", services);
714 ug_send_result(ugd->ug, control);
716 app_control_destroy(control);
719 WFD_IF_FREE_MEM(peer->device_name);
720 WFD_IF_FREE_MEM(peer->mac_address);
721 WFD_IF_FREE_MEM(peer->interface_address);
723 if (NULL != peer->service_list)
725 for (i=0; i<peer->service_count && peer->service_list[i] != NULL; i++) {
726 free(peer->service_list[i]);
728 WFD_IF_FREE_MEM(peer->service_list);
731 WFD_IF_FREE_MEM(peer);
738 * This function let the ug get the found peers
739 * @return If success, return 0, else return -1
740 * @param[in] ugd the pointer to the main data structure
742 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
746 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
748 ugd->raw_discovered_peer_cnt = 0;
749 wfd_client_free_raw_discovered_peers(ugd);
750 res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
751 if (res != WIFI_DIRECT_ERROR_NONE) {
752 ugd->raw_discovered_peer_cnt = 0;
753 DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
761 * This function let the ug get the connecting peer
762 * @return If success, return 0, else return -1
763 * @param[in] ugd the pointer to the main data structure
765 int wfd_ug_get_connecting_peer(struct ug_data *ugd)
769 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
770 char *mac_addr = NULL;
771 GList *iterator = NULL;
773 ugd->mac_addr_connecting = NULL;
774 res = wifi_direct_get_connecting_peer(&mac_addr);
775 if (res != WIFI_DIRECT_ERROR_NONE) {
776 DBG(LOG_ERROR, "Get connecting device mac failed: %d\n", res);
779 DBG_SECURE(LOG_INFO, "Mac Addr Connecting: ["MACSECSTR"]\n",
780 MAC2SECSTR(mac_addr));
781 ugd->mac_addr_connecting = mac_addr;
783 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
784 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
785 ((device_type_s *)iterator->data)->conn_status = PEER_CONN_STATUS_CONNECTING;
796 * This function let the ug get the connected peers
797 * @return If success, return 0, else return -1
798 * @param[in] ugd the pointer to the main data structure
800 int wfd_ug_get_connected_peers(struct ug_data *ugd)
804 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
806 ugd->raw_connected_peer_cnt = 0;
807 res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
808 if (res != WIFI_DIRECT_ERROR_NONE) {
809 ugd->raw_connected_peer_cnt = 0;
810 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
818 * This function let the ug exits automatically after successed connection
820 * @param[in] user_data the pointer to the main data structure
822 void _wfd_ug_auto_exit(void *user_data)
825 struct ug_data *ugd = (struct ug_data *)user_data;
826 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
829 deinit_wfd_client(ugd);
835 gboolean wfd_delete_not_alive_peer_cb(void *user_data)
838 struct ug_data *ugd = (struct ug_data *)user_data;
839 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
841 delete_not_alive_peers(ugd, &ugd->gl_avlb_peers_start, &ugd->gl_available_peer_cnt);
842 delete_not_alive_peers(ugd, &ugd->gl_busy_peers_start, &ugd->gl_busy_peer_cnt);
843 delete_not_alive_peers(ugd, &ugd->multi_conn_dev_list_start, &ugd->gl_available_dev_cnt_at_multiconn_view);
844 wfd_ug_view_init_genlist(ugd, false);
845 wfd_update_multiconnect_device(ugd, false);
851 gboolean wfd_delete_progressbar_cb(void *user_data)
854 struct ug_data *ugd = (struct ug_data *)user_data;
855 WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
857 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
858 if (ugd->raw_discovered_peer_cnt == 0 &&
859 ugd->nodevice_title_item == NULL &&
860 ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE &&
861 ugd->gl_available_peer_cnt == 0) {
862 _create_no_device_genlist(ugd);
865 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
866 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
868 if (0 == ugd->gl_available_dev_cnt_at_multiconn_view) {
869 _create_no_device_multiconnect_genlist(ugd);
872 wfd_refresh_wifi_direct_state(ugd);
873 if (WIFI_DIRECT_STATE_CONNECTING != ugd->wfd_status &&
874 WIFI_DIRECT_STATE_DISCONNECTING != ugd->wfd_status) {
875 if (ugd->scan_toolbar) {
876 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
877 evas_object_data_set(ugd->toolbar, "scan", "scan");
880 if (ugd->multiconn_layout) {
881 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
882 DBG(LOG_INFO, "Multiconn button text IDS_WIFI_SK4_SCAN \n");
892 * This function let the ug make a callback for registering discover event
894 * @param[in] error_code the returned error code
895 * @param[in] discovery_state the state of discover
896 * @param[in] user_data the pointer to the main data structure
898 void discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
902 struct ug_data *ugd = (struct ug_data *)user_data;
905 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
909 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
913 DBG(LOG_INFO, "Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
915 if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
916 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
917 ugd->title_content_mode = TITLE_CONTENT_TYPE_SCANNING;
918 wfd_cancel_progressbar_stop_timer(ugd);
919 ugd->timer_stop_progress_bar = g_timeout_add(1000*30, wfd_delete_progressbar_cb, ugd);
920 /* clear all the previous discovered peers */
921 wfd_client_free_raw_discovered_peers(ugd);
923 ugd->raw_discovered_peer_cnt = 0;
924 wfd_ug_view_init_genlist(ugd, false);
926 if (ugd->avlbl_wfd_item == NULL) {
927 _create_available_dev_genlist(ugd);
930 wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
931 /* clear not alive peers after 5 secs */
932 wfd_cancel_not_alive_delete_timer(ugd);
933 ugd->timer_delete_not_alive_peer = g_timeout_add(1000*5, wfd_delete_not_alive_peer_cb, ugd);
934 set_not_alive_peers(ugd->gl_avlb_peers_start);
935 set_not_alive_peers(ugd->gl_busy_peers_start);
936 set_not_alive_peers(ugd->multi_conn_dev_list_start);
938 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
939 if (ugd->wfd_discovery_status != WIFI_DIRECT_DISCOVERY_NONE) {
940 wfd_ug_get_discovered_peers(ugd);
941 wfd_ug_update_available_peers(ugd);
942 wfd_update_multiconnect_device(ugd, false);
944 } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FINISHED) {
945 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
946 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_FULL_SCAN_START;
947 ret = wifi_direct_start_discovery_specific_channel(false, 0, WIFI_DIRECT_DISCOVERY_FULL_SCAN);
948 if (ret != WIFI_DIRECT_ERROR_NONE) {
949 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
950 DBG(LOG_ERROR, "Failed to start discovery with full scan. [%d]\n", ret);
951 wifi_direct_cancel_discovery();
956 if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state &&
957 ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
958 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
959 if (!ugd->conn_wfd_item) {
960 elm_object_part_content_set(ugd->layout, "button.big", ugd->scan_toolbar);
962 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK_STOP", TRUE);
963 if (ugd->multiconn_scan_stop_btn) {
964 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK_STOP", TRUE);
973 * This function let the ug make a callback for registering connection event
975 * @param[in] error_code the returned error code
976 * @param[in] connection_state the state of connection
977 * @param[in] mac_address the mac address of peer
978 * @param[in] user_data the pointer to the main data structure
980 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
983 struct ug_data *ugd = (struct ug_data *)user_data;
984 device_type_s *peer = NULL;
988 if (mac_address == NULL) {
989 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
993 DBG_SECURE(LOG_INFO, "Connection event [%d], error_code [%d], multi_connect_mode [%d] mac ["MACSECSTR"]\n",
994 connection_state, error_code, ugd->multi_connect_mode, MAC2SECSTR(mac_address));
996 /* when not in connection, mac_address is empty */
997 if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
998 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
1000 if (NULL == peer || '\0' == peer->ssid[0]) {
1001 DBG(LOG_ERROR, "invalid peer from connection !!\n");
1002 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1003 goto refresh_button;
1007 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
1008 switch (connection_state) {
1009 case WIFI_DIRECT_CONNECTION_RSP:
1010 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
1011 ugd->mac_addr_connecting = NULL;
1012 if (error_code == WIFI_DIRECT_ERROR_NONE) {
1013 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1014 wfd_ug_get_connected_peers(ugd);
1015 wfd_ug_update_connected_peers(ugd);
1017 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1018 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
1019 if ( peer != NULL) {
1020 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1021 wfd_ug_view_refresh_glitem(peer->gl_item);
1024 /* connect the next peer */
1025 ugd->g_source_multi_connect_next = g_timeout_add(500, wfd_multi_connect_next_cb, ugd);
1027 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1028 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1029 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1030 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
1032 if ( peer != NULL) {
1033 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1034 wfd_ug_view_refresh_glitem(peer->gl_item);
1037 wfd_ug_update_toolbar(ugd);
1039 case WIFI_DIRECT_GROUP_CREATED:
1040 DBG(LOG_INFO, "MULTI: WIFI_DIRECT_GROUP_CREATED\n");
1041 wfd_cancel_progressbar_stop_timer(ugd);
1042 wfd_delete_progressbar_cb(ugd);
1044 wfd_ug_view_init_genlist(ugd, true);
1045 wfd_ug_view_update_multiconn_peers(ugd);
1046 wfd_multi_connect_next_cb(ugd);
1052 switch (connection_state) {
1053 case WIFI_DIRECT_CONNECTION_RSP:
1054 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_RSP\n");
1055 wfd_delete_progressbar_cb(ugd);
1057 if (ugd->act_popup) {
1058 evas_object_del(ugd->act_popup);
1059 ugd->act_popup = NULL;
1061 ugd->mac_addr_connecting = NULL;
1063 if (error_code == WIFI_DIRECT_ERROR_NONE) {
1064 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1065 wfd_ug_get_connected_peers(ugd);
1067 /* when auto_exit and not multi-connect*/
1068 if ((ugd->is_auto_exit)&&(ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE)) {
1069 _wfd_ug_auto_exit(ugd);
1072 if(ugd->ctxpopup != NULL && ugd->more_btn_multiconnect_item) {
1073 elm_object_item_disabled_set(ugd->more_btn_multiconnect_item, TRUE);
1076 wfd_ug_update_connected_peers(ugd);
1078 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1079 wfd_ug_update_failed_peers(ugd);
1082 wfd_ug_update_toolbar(ugd);
1084 case WIFI_DIRECT_DISASSOCIATION_IND:
1085 DBG(LOG_INFO, "WIFI_DIRECT_DISASSOCIATION_IND\n");
1086 /* remove any possible popup */
1087 WFD_IF_DEL_OBJ(ugd->act_popup);
1088 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
1090 /* change the multi connection mode, it can be connected now */
1091 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1092 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1095 /* if other peer disconnected, get connected peers and update */
1096 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
1097 wfd_ug_get_connected_peers(ugd);
1098 wfd_ug_update_available_peers(ugd);
1100 case WIFI_DIRECT_DISCONNECTION_RSP:
1101 case WIFI_DIRECT_DISCONNECTION_IND:
1102 DBG(LOG_INFO, "WIFI_DIRECT_DISCONNECTION_X\n");
1103 WFD_IF_DEL_OBJ(ugd->act_popup);
1105 Evas_Object *content;
1106 content = elm_object_part_content_unset(ugd->layout, "button.next");
1107 WFD_IF_DEL_OBJ(content);
1108 /* when disconnection, clear all the connected peers */
1109 if (ugd->raw_connected_peer_cnt > 0) {
1110 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
1113 ugd->raw_connected_peer_cnt = 0;
1114 wfd_ug_view_init_genlist(ugd, true);
1115 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1116 DBG(LOG_INFO, "Background mode\n");
1120 if (ugd->is_paused == false) {
1121 /* start discovery again */
1122 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1123 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1124 if (res != WIFI_DIRECT_ERROR_NONE) {
1125 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1126 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1127 wifi_direct_cancel_discovery();
1132 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1133 DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1134 wfd_ug_update_toolbar(ugd);
1135 wfd_cancel_progressbar_stop_timer(ugd);
1136 wfd_delete_progressbar_cb(ugd);
1138 if (ugd->multi_navi_item) {
1139 elm_naviframe_item_pop(ugd->naviframe);
1142 ugd->mac_addr_connecting = peer->mac_addr;
1143 ugd->is_conn_incoming = FALSE;
1144 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1145 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, peer->mac_addr);
1147 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1148 wfd_ug_view_refresh_glitem(peer->gl_item);
1150 wfd_ug_get_discovered_peers(ugd);
1151 wfd_ug_update_available_peers(ugd);
1155 case WIFI_DIRECT_CONNECTION_REQ:
1156 case WIFI_DIRECT_CONNECTION_WPS_REQ:
1157 ugd->mac_addr_connecting = peer->mac_addr;
1158 ugd->is_conn_incoming = TRUE;
1159 DBG(LOG_INFO, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
1161 case WIFI_DIRECT_GROUP_DESTROYED:
1162 wfd_ug_update_toolbar(ugd);
1163 if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1164 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1166 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1167 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1168 if (res != WIFI_DIRECT_ERROR_NONE) {
1169 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1170 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1171 wifi_direct_cancel_discovery();
1182 /* refresh the scan button */
1183 wfd_refresh_wifi_direct_state(ugd);
1184 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
1185 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
1186 res = wifi_direct_is_group_owner(&owner);
1187 if (res == WIFI_DIRECT_ERROR_NONE) {
1189 if (ugd->scan_toolbar) {
1190 evas_object_data_set(ugd->toolbar, "scan", "scan");
1193 if (ugd->multiconn_scan_stop_btn) {
1194 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1198 DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
1201 if (ugd->scan_toolbar) {
1202 evas_object_data_set(ugd->toolbar, "scan", "scan");
1205 if (ugd->multiconn_scan_stop_btn) {
1206 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
1215 * This function let the ug make a callback for registering ip assigned event
1217 * @param[in] mac_address the mac address of peer
1218 * @param[in] ip_address the ip address of peer
1219 * @param[in] interface_address the interface address
1220 * @param[in] user_data the pointer to the main data structure
1222 void _ip_assigned_cb(const char *mac_address, const char *ip_address, const char *interface_address, void *user_data)
1227 DBG(LOG_ERROR, "The user_data is NULL\n");
1231 struct ug_data *ugd = (struct ug_data *)user_data;
1233 if (!ip_address || 0 == strncmp(ip_address, "0.0.0.0", 7)) {
1234 DBG(LOG_ERROR,"ip address is invalid.\n");
1238 ugd->peer_ip_address = strdup(ip_address);
1241 /* to send ip_addr*/
1243 app_control_h control = NULL;
1244 ret = app_control_create(&control);
1246 DBG(LOG_ERROR, "Failed to create control");
1249 app_control_add_extra_data(control, "ip_address", ugd->peer_ip_address);
1250 app_control_add_extra_data(control, "wfds", ugd->service_name);
1251 ug_send_result(ugd->ug, control);
1252 app_control_destroy(control);
1254 /* when auto_exit and not multi-connect*/
1255 if ((ugd->is_auto_exit)&&(ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE)) {
1256 _wfd_ug_auto_exit(ugd);
1263 * This function let the ug get wi-fi direct status from vconf
1264 * @return If success, return the wfd status, else return -1
1267 int wfd_get_vconf_status()
1270 int wifi_direct_state = 0;
1272 /* get wifi direct status from vconf */
1273 if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
1274 DBG(LOG_ERROR, "Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
1277 DBG(LOG_INFO, "WiFi Direct State [%d]", wifi_direct_state);
1280 return wifi_direct_state;
1284 * This function let the ug get device name from vconf
1285 * @return If success, return 0, else return -1
1286 * @param[in] data the pointer to the main data structure
1288 int wfd_get_vconf_device_name(void *data)
1291 struct ug_data *ugd = (struct ug_data *)data;
1292 char *dev_name = NULL;
1294 /* get device name from vconf */
1295 dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1296 if (dev_name == NULL) {
1297 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1298 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
1302 ugd->dev_name = strdup(dev_name);
1303 WFD_IF_FREE_MEM(dev_name);
1310 * This function let the ug refresh current status of wi-fi direct
1311 * @return If success, return 0, else return -1
1312 * @param[in] data the pointer to the main data structure
1314 int wfd_refresh_wifi_direct_state(void *data)
1317 struct ug_data *ugd = (struct ug_data *)data;
1319 wifi_direct_state_e wfd_status;
1321 res = wifi_direct_get_state(&wfd_status);
1322 if (res != WIFI_DIRECT_ERROR_NONE) {
1323 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
1327 DBG(LOG_INFO, "WFD status [%d]", wfd_status);
1328 ugd->wfd_status = wfd_status;
1334 void wfd_init_ug_by_status(void *user_data)
1337 struct ug_data *ugd = (struct ug_data *)user_data;
1341 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
1345 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) {
1346 //wfd_ug_get_discovered_peers(ugd);
1347 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1350 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
1351 wfd_ug_get_connected_peers(ugd);
1352 wfd_ug_update_connected_peers(ugd);
1353 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1354 wfd_ug_get_discovered_peers(ugd);
1355 wfd_ug_update_available_peers(ugd);
1356 wfd_ug_update_toolbar(ugd);
1359 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1360 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1361 wfd_ug_get_discovered_peers(ugd);
1362 wfd_ug_get_connecting_peer(ugd);
1363 wfd_ug_update_available_peers(ugd);
1364 wfd_ug_update_toolbar(ugd);
1367 if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED ||
1368 ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1369 /* start discovery */
1370 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1371 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1372 if (res != WIFI_DIRECT_ERROR_NONE) {
1373 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1374 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1375 wifi_direct_cancel_discovery();
1383 * This function let the ug do initialization
1384 * @return If success, return 0, else return -1
1385 * @param[in] data the pointer to the main data structure
1387 int init_wfd_client(void* data)
1390 WFD_RETV_IF(data == NULL, -1, "Incorrect parameter(NULL)\n");
1391 struct ug_data *ugd = (struct ug_data *)data;
1394 res = wifi_direct_initialize();
1395 if (res != WIFI_DIRECT_ERROR_NONE) {
1396 if (res != WIFI_DIRECT_ERROR_ALREADY_INITIALIZED) {
1397 DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
1400 DBG(LOG_ERROR, "Already registered\n");
1404 res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1405 if (res != WIFI_DIRECT_ERROR_NONE) {
1406 DBG(LOG_ERROR, "Failed to register _cb_activation. error code = [%d]\n", res);
1410 res = wifi_direct_set_discovery_state_changed_cb(discover_cb, (void *)ugd);
1411 if (res != WIFI_DIRECT_ERROR_NONE) {
1412 DBG(LOG_ERROR, "Failed to register _cb_discover. error code = [%d]\n", res);
1416 res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1417 if (res != WIFI_DIRECT_ERROR_NONE) {
1418 DBG(LOG_ERROR, "Failed to register _cb_connection. error code = [%d]\n", res);
1422 res = wifi_direct_set_client_ip_address_assigned_cb(_ip_assigned_cb, (void *)ugd);
1423 if (res != WIFI_DIRECT_ERROR_NONE) {
1424 DBG(LOG_ERROR, "Failed to register _ip_assigned_cb. error code = [%d]\n", res);
1428 /* update WFD status */
1429 wfd_refresh_wifi_direct_state(ugd);
1430 #ifdef WFD_ON_OFF_GENLIST
1431 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1433 wfd_ug_refresh_on_off_check(ugd);
1439 DBG(LOG_INFO, "WFD link status. [%d]\n", ugd->wfd_status);
1440 ugd->is_init_ok = TRUE;
1441 wfd_init_ug_by_status(ugd);
1447 #ifdef WFD_DBUS_LAUNCH
1448 void wfd_gdbus_callback(GObject *source_object, GAsyncResult *result, gpointer user_data)
1451 struct ug_data *ugd = (struct ug_data *)user_data;
1452 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1455 GError *error = NULL;
1456 GVariant *return_data;
1458 g_object_unref(ugd->dbus_cancellable);
1459 ugd->dbus_cancellable = NULL;
1460 ugd->conn = G_DBUS_CONNECTION (source_object);
1461 return_data = g_dbus_connection_call_finish(ugd->conn, result, &error);
1463 if (error != NULL) {
1464 DBG(LOG_ERROR,"DBus action failed. Error Msg [%s]\n", error->message);
1465 g_clear_error(&error);
1467 DBG(LOG_INFO, "error msg is NULL\n");
1471 g_variant_unref(return_data);
1474 g_object_unref(ugd->conn);
1478 res = init_wfd_client(ugd);
1479 WFD_RET_IF(res != 0, "Failed to initialize WFD client library\n");
1481 /* Activate WiFi Direct */
1483 DBG(LOG_INFO, "Activating WiFi Direct...");
1484 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1485 res = wfd_client_switch_on(ugd);
1486 WFD_RET_IF(res != 0, "Failed to activate WFD\n");
1493 int launch_wifi_direct_manager(void *data)
1498 GError *error = NULL;
1500 struct ug_data *ugd = (struct ug_data *)data;
1501 WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
1503 ugd->dbus_cancellable = g_cancellable_new();
1505 addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
1506 WFD_RETV_IF(addr == NULL, -1, "Fail to get dbus addr.\n");
1508 ugd->conn = g_dbus_connection_new_for_address_sync(addr,G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
1509 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, NULL, NULL, NULL);
1511 if(ugd->conn == NULL) {
1512 DBG(LOG_ERROR,"g_dbus_conn is NULL\n");
1515 g_dbus_connection_call(ugd->conn, "net.netconfig", "/net/netconfig/wifi","net.netconfig.wifi",
1516 "LaunchDirect", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, ugd->dbus_cancellable, wfd_gdbus_callback, data);
1524 void wfd_client_destroy_tethering(struct ug_data *ugd)
1528 tethering_error_e ret = TETHERING_ERROR_NONE;
1530 if (ugd->hotspot_handle != NULL) {
1531 /* Deregister cbs */
1532 ret = tethering_unset_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1533 if (ret != TETHERING_ERROR_NONE) {
1534 DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
1537 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1538 if (ret != TETHERING_ERROR_NONE) {
1539 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1542 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
1543 if (ret != TETHERING_ERROR_NONE) {
1544 DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1547 /* Destroy tethering handle */
1548 ret = tethering_destroy(ugd->hotspot_handle);
1549 if (ret != TETHERING_ERROR_NONE) {
1550 DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
1553 ugd->hotspot_handle = NULL;
1560 * This function let the ug do de-initialization
1561 * @return If success, return 0, else return -1
1562 * @param[in] data the pointer to the main data structure
1564 int deinit_wfd_client(void *data)
1567 struct ug_data *ugd = (struct ug_data *)data;
1570 wfd_refresh_wifi_direct_state(ugd);
1572 if ((WIFI_DIRECT_STATE_DISCOVERING == ugd->wfd_status) &&
1573 (WIFI_DIRECT_ERROR_NONE != wifi_direct_cancel_discovery())) {
1574 DBG(LOG_ERROR, "Failed to send cancel discovery state [%d]\n", ugd->wfd_status);
1577 wfd_cancel_progressbar_stop_timer(ugd);
1578 wfd_cancel_not_alive_delete_timer(ugd);
1580 if(ugd->timer_multi_reset > 0) {
1581 g_source_remove(ugd->timer_multi_reset);
1583 ugd->timer_multi_reset = 0;
1585 if (ugd->g_source_multi_connect_next > 0) {
1586 g_source_remove(ugd->g_source_multi_connect_next);
1588 ugd->g_source_multi_connect_next = 0;
1590 res = wifi_direct_unset_discovery_state_changed_cb();
1591 if (res != WIFI_DIRECT_ERROR_NONE) {
1592 DBG(LOG_ERROR, "Failed to unset discovery state changed cb. [%d]\n", res);
1595 wifi_direct_unset_device_state_changed_cb();
1596 if (res != WIFI_DIRECT_ERROR_NONE) {
1597 DBG(LOG_ERROR, "Failed to unset device state changed cb. [%d]\n", res);
1600 wifi_direct_unset_connection_state_changed_cb();
1601 if (res != WIFI_DIRECT_ERROR_NONE) {
1602 DBG(LOG_ERROR, "Failed to unset connection state changed cb. [%d]\n", res);
1605 wifi_direct_unset_client_ip_address_assigned_cb();
1606 if (res != WIFI_DIRECT_ERROR_NONE) {
1607 DBG(LOG_ERROR, "Failed to unset client ip address assigned cb. [%d]\n", res);
1610 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING &&
1611 NULL != ugd->mac_addr_connecting) {
1612 if (ugd->is_conn_incoming) {
1613 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
1614 res = wifi_direct_reject_connection(ugd->mac_addr_connecting);
1615 if (res != WIFI_DIRECT_ERROR_NONE) {
1616 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", res);
1619 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
1620 res = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
1621 if (res != WIFI_DIRECT_ERROR_NONE) {
1622 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", res);
1625 ugd->mac_addr_connecting = NULL;
1629 res = wifi_direct_deinitialize();
1630 if (res != WIFI_DIRECT_ERROR_NONE) {
1631 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
1634 /* release vconf, hotspot.. */
1635 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1636 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1638 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
1641 res = net_deregister_client();
1642 if (res != NET_ERR_NONE) {
1643 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
1645 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1648 wfd_client_destroy_tethering(ugd);
1655 * This function let the ug turn wi-fi direct on
1656 * @return If success, return 0, else return -1
1657 * @param[in] data the pointer to the main data structure
1659 int wfd_client_switch_on(void *data)
1662 struct ug_data *ugd = (struct ug_data *)data;
1665 bool is_wifi_enabled = false;
1666 bool is_wifi_ap_enabled = false;
1669 if(!ugd->is_init_ok) {
1670 DBG(LOG_ERROR, "device is initializing, please wait\n");
1674 wfd_refresh_wifi_direct_state(ugd);
1675 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1677 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1679 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1681 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1683 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
1686 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1688 ugd->hotspot_handle = NULL;
1689 res = tethering_create(&(ugd->hotspot_handle));
1690 if (res != TETHERING_ERROR_NONE) {
1691 DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", res);
1694 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
1697 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1698 is_wifi_ap_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_RESERVED);
1700 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1701 if (wifi_state > VCONFKEY_WIFI_OFF) {
1702 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1703 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_CONNECTION_CONTINUE_Q"), POPUP_TYPE_WIFI_OFF);
1705 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1707 if (is_wifi_enabled || is_wifi_ap_enabled) {
1708 DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1709 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_TETHERING_CONTINUE_Q"), POPUP_TYPE_HOTSPOT_OFF);
1713 res = wifi_direct_activate();
1714 if (res != WIFI_DIRECT_ERROR_NONE) {
1715 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1716 wfd_ug_warn_popup(ugd, _("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1717 #ifdef WFD_ON_OFF_GENLIST
1718 wfd_ug_refresh_on_off_check(ugd);
1723 #ifdef WFD_ON_OFF_GENLIST
1724 if (ugd->on_off_check) {
1725 elm_check_state_set(ugd->on_off_check, TRUE);
1726 elm_object_disabled_set(ugd->on_off_check, TRUE);
1729 /* while activating, disable the buttons */
1730 if (ugd->scan_toolbar == NULL) {
1731 scan_button_create(ugd);
1734 if (ugd->scan_toolbar) {
1735 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1738 if (ugd->multiconn_scan_stop_btn) {
1739 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1742 if (ugd->back_btn) {
1743 elm_object_disabled_set(ugd->back_btn, TRUE);
1747 DBG(LOG_INFO, "Wi-Fi Direct is already activated\n");
1755 * This function let the ug turn wi-fi direct off
1756 * @return If success, return 0, else return -1
1757 * @param[in] data the pointer to the main data structure
1759 int wfd_client_switch_off(void *data)
1762 struct ug_data *ugd = (struct ug_data *)data;
1765 wfd_ug_view_free_peers(ugd);
1766 wfd_free_nodivice_item(ugd);
1768 wfd_refresh_wifi_direct_state(ugd);
1769 DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1771 if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1772 DBG(LOG_INFO, "Wi-Fi Direct is already deactivated\n");
1775 wfd_client_destroy_tethering(ugd);
1777 wfd_cancel_progressbar_stop_timer(ugd);
1778 wfd_cancel_not_alive_delete_timer(ugd);
1780 if(ugd->timer_multi_reset > 0) {
1781 g_source_remove(ugd->timer_multi_reset);
1783 ugd->timer_multi_reset = 0;
1785 if (ugd->g_source_multi_connect_next > 0) {
1786 g_source_remove(ugd->g_source_multi_connect_next);
1788 ugd->g_source_multi_connect_next = 0;
1790 /*if connected, disconnect all devices*/
1791 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1792 res = wifi_direct_disconnect_all();
1793 if (res != WIFI_DIRECT_ERROR_NONE) {
1794 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1799 res = wifi_direct_deactivate();
1800 if (res != WIFI_DIRECT_ERROR_NONE) {
1801 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1802 wfd_ug_warn_popup(ugd, _("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE_DEACTIVATE_FAIL);
1803 #ifdef WFD_ON_OFF_GENLIST
1804 wfd_ug_refresh_on_off_check(ugd);
1809 /* while deactivating, disable the buttons */
1810 if (ugd->scan_toolbar) {
1811 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1812 evas_object_del(ugd->scan_toolbar);
1813 ugd->scan_toolbar = NULL;
1816 if (ugd->multiconn_scan_stop_btn) {
1817 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1820 if (ugd->multi_connect_toolbar_item) {
1821 elm_object_item_disabled_set(ugd->multi_connect_toolbar_item, TRUE);
1824 if (ugd->back_btn) {
1825 elm_object_disabled_set(ugd->back_btn, TRUE);
1833 #ifdef WFD_ON_OFF_GENLIST
1835 * This function let the ug turn wi-fi direct on/off forcely
1836 * @return If success, return 0, else return -1
1837 * @param[in] data the pointer to the main data structure
1838 * @param[in] onoff whether to turn on/off wi-fi direct
1840 int wfd_client_swtch_force(void *data, int onoff)
1843 struct ug_data *ugd = (struct ug_data *)data;
1847 res = wifi_direct_activate();
1848 if (res != WIFI_DIRECT_ERROR_NONE) {
1849 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1850 wfd_ug_warn_popup(ugd, _("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1851 wfd_ug_refresh_on_off_check(ugd);
1855 res = wifi_direct_deactivate();
1856 if (res != WIFI_DIRECT_ERROR_NONE) {
1857 DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1858 wfd_ug_warn_popup(ugd, _("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE);
1859 wfd_ug_refresh_on_off_check(ugd);
1870 * This function let the ug create a group
1871 * @return If success, return 0, else return -1
1873 int wfd_client_group_add()
1878 res = wifi_direct_create_group();
1879 if (res != WIFI_DIRECT_ERROR_NONE) {
1880 DBG(LOG_ERROR, "Failed to add group");
1890 * This function let the ug connect to the device by mac address
1891 * @return If success, return 0, else return -1
1892 * @param[in] mac_addr the pointer to the mac address of device
1894 int wfd_client_connect(const char *mac_addr)
1899 DBG_SECURE(LOG_INFO, "connect to peer=["MACSECSTR"]\n", MAC2SECSTR(mac_addr));
1900 res = wifi_direct_connect((char *)mac_addr);
1901 if (res != WIFI_DIRECT_ERROR_NONE) {
1902 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
1911 * This function let the ug disconnect to the device by mac address
1912 * @return If success, return 0, else return -1
1913 * @param[in] mac_addr the pointer to the mac address of device
1915 int wfd_client_disconnect(const char *mac_addr)
1920 wifi_direct_cancel_discovery();
1922 * No need to handle return in cancel discovery as there maybe case
1923 * when framework can return failure.
1926 if (mac_addr == NULL) {
1927 res = wifi_direct_disconnect_all();
1928 if (res != WIFI_DIRECT_ERROR_NONE) {
1929 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1933 res = wifi_direct_disconnect((char *)mac_addr);
1934 if (res != WIFI_DIRECT_ERROR_NONE) {
1935 DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
1945 * This function let the ug set the intent of a group owner
1946 * @return If success, return 0, else return -1
1947 * @param[in] go_intent the intent parameter
1949 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1954 res = wifi_direct_set_group_owner_intent(go_intent);
1955 if (res != WIFI_DIRECT_ERROR_NONE) {
1956 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);