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 <ui-gadget-module.h>
27 #include <app_control.h>
28 #include <wifi-direct.h>
29 #include <efl_extension.h>
32 #include "wfd_ug_view.h"
33 #include "wfd_client.h"
35 void scan_button_create(struct ug_data *ugd)
40 btn = elm_button_add(ugd->layout);
41 /* Use "bottom" style button */
42 elm_object_style_set(btn, "bottom");
43 elm_object_domain_translatable_text_set(btn, PACKAGE, "IDS_WIFI_SK4_SCAN");
44 ugd->scan_toolbar = btn;
45 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
46 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN",
49 evas_object_smart_callback_add(btn, "clicked",_scan_btn_cb, (void *)ugd);
50 /* Set button into "toolbar" swallow part */
51 elm_object_part_content_set(ugd->layout, "button.big", btn);
52 evas_object_show(ugd->scan_toolbar);
58 * This function let the ug call it when click 'back' button
60 * @param[in] data the pointer to the main data structure
61 * @param[in] obj the pointer to the evas object
62 * @param[in] event_info the pointer to the event information
64 Eina_Bool _back_btn_cb(void *data, Elm_Object_Item *it)
67 struct ug_data *ugd = (struct ug_data *) data;
68 WFD_RETV_IF(ugd == NULL, FALSE, "The param is NULL\n");
71 app_control_h control = NULL;
73 #ifdef WFD_DBUS_LAUNCH
74 if (ugd->dbus_cancellable != NULL) {
75 g_cancellable_cancel(ugd->dbus_cancellable);
76 g_object_unref(ugd->dbus_cancellable);
77 ugd->dbus_cancellable = NULL;
79 g_object_unref(ugd->conn);
82 DBG(LOG_INFO, "Cancel dbus call");
86 wfd_refresh_wifi_direct_state(ugd);
87 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
88 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
92 if (NULL != ugd->mac_addr_connecting) {
93 if (ugd->is_conn_incoming) {
94 DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
95 ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
96 if (ret != WIFI_DIRECT_ERROR_NONE) {
97 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
100 DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
101 ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
102 if (ret != WIFI_DIRECT_ERROR_NONE) {
103 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
106 ugd->mac_addr_connecting = NULL;
109 if (ugd->raw_connected_peer_cnt == 0) {
110 ret = wifi_direct_is_group_owner(&owner);
111 if (ret == WIFI_DIRECT_ERROR_NONE) {
113 wifi_direct_destroy_group();
119 wfd_ug_view_free_peers(ugd);
120 ret = app_control_create(&control);
122 DBG(LOG_ERROR, "Failed to create control");
124 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) {
125 app_control_add_extra_data(control, "Connection", "TRUE");
127 app_control_add_extra_data(control, "Connection", "FALSE");
130 ug_send_result(ugd->ug, control);
131 app_control_destroy(control);
134 ug_destroy_me(ugd->ug);
139 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
143 if(ugd->timer_stop_progress_bar > 0) {
144 g_source_remove(ugd->timer_stop_progress_bar);
146 ugd->timer_stop_progress_bar = 0;
151 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
155 if(ugd->timer_delete_not_alive_peer > 0) {
156 g_source_remove(ugd->timer_delete_not_alive_peer);
158 ugd->timer_delete_not_alive_peer = 0;
164 * This function let the ug call it when click failed devices item
166 * @param[in] data the pointer to the main data structure
167 * @param[in] obj the pointer to the evas object
168 * @param[in] event_info the pointer to the event information
170 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
174 struct ug_data *ugd = wfd_get_ug_data();
178 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
182 if (ugd->display_timer != NULL) {
183 ecore_timer_del(ugd->display_timer);
184 ugd->display_timer = NULL;
187 wfd_refresh_wifi_direct_state(ugd);
188 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
190 /* if connected, show the popup*/
191 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
192 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
194 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
195 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
196 if (ret != WIFI_DIRECT_ERROR_NONE) {
197 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
198 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
199 wifi_direct_cancel_discovery();
208 * This function let the ug call it when click 'scan' button
210 * @param[in] data the pointer to the main data structure
211 * @param[in] obj the pointer to the evas object
212 * @param[in] event_info the pointer to the event information
214 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
218 struct ug_data *ugd = (struct ug_data *) data;
220 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
224 const char *btn_text = NULL;
225 btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
226 DBG(LOG_INFO, "Button text=%s",btn_text);
228 if (!g_strcmp0(elm_object_text_get(obj), _("IDS_WIFI_SK4_SCAN"))) {
229 wfd_refresh_wifi_direct_state(ugd);
230 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
231 /* if connected, show the popup*/
232 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
233 wfd_ug_act_popup(ugd, _("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
234 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
235 wfd_client_switch_on(ugd);
239 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
240 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
241 if (ret != WIFI_DIRECT_ERROR_NONE) {
242 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
243 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
244 wifi_direct_cancel_discovery();
247 } else if (!g_strcmp0(elm_object_text_get(obj), _("IDS_WIFI_SK_STOP"))) {
248 DBG(LOG_INFO, "Stop pressed.\n");
249 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
250 wfd_cancel_progressbar_stop_timer(ugd);
251 wfd_delete_progressbar_cb(ugd);
252 wfd_cancel_not_alive_delete_timer(ugd);
253 } else if (0 == strcmp(_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
254 DBG(LOG_INFO, "Cancel Connection");
255 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
257 DBG(LOG_INFO, "Invalid Case\n");
263 void wfd_check_gl_busy_peers(struct ug_data *ugd)
266 if (ugd->gl_busy_peer_cnt == 0) {
267 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
272 void wfd_check_gl_available_peers(struct ug_data *ugd)
275 if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL) {
276 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
282 * This function let the ug free some peer in genlist
284 * @param[in] start_pos the start position of peers list
285 * @param[in] mac_addr the mac_addr of peer for free
286 * @param[in] cnt the count of gl peers in list
288 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
291 device_type_s *peer = *start_pos;
292 device_type_s *peer_tmp = peer;
295 DBG(LOG_INFO, "no peer in genlist");
300 if(strcmp(peer->mac_addr, mac_addr)) {
304 if(peer->next != NULL) {
305 peer_tmp->next = peer->next;
308 peer_tmp->next = NULL;
314 if (peer == *start_pos) {
315 DBG(LOG_INFO, "the head is free");
316 *start_pos = peer->next;
321 WFD_IF_DEL_ITEM(peer->gl_item);
329 * This function let the ug call it when click avaliable peer to connect
331 * @param[in] data the pointer to the main data structure
332 * @param[in] obj the pointer to the evas object
333 * @param[in] event_info the pointer to the event information
335 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
340 char txt[MAX_POPUP_TEXT_SIZE] = {0,};
341 char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
342 bool is_peer_alive = false;
343 struct ug_data *ugd = wfd_get_ug_data();
344 device_type_s *peer = (device_type_s *)data;
345 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
348 DBG(LOG_ERROR, "NULL parameters.\n");
352 wfd_ug_get_connected_peers(ugd);
353 DBG(LOG_INFO, "No of connected peers= %d",ugd->raw_connected_peer_cnt);
355 if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
356 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, _("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME"), MAX_CONNECTED_PEER_NUM);
357 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
359 elm_genlist_item_selected_set(item, EINA_FALSE);
364 if (ugd->disconnect_btn) {
365 Evas_Object *content;
366 content = elm_object_part_content_unset(ugd->layout, "button.next");
367 WFD_IF_DEL_OBJ(content);
368 ugd->disconnect_btn = NULL;
369 elm_object_part_content_set(ugd->layout, "button.big",
374 elm_genlist_item_selected_set(item, EINA_FALSE);
377 GList *iterator = NULL;
379 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
380 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
381 /* peer is found in last discovery */
382 is_peer_alive = true;
387 if (!is_peer_alive) {
388 /* peer exists only in genlist, waiting to be deleted */
389 device_type_s *peer_start = ugd->gl_avlb_peers_start;
390 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
391 if(!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
392 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
393 sprintf(txt, "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
394 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
395 wfd_check_gl_available_peers(ugd);
396 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
402 wfd_cancel_not_alive_delete_timer(ugd);
405 wfd_refresh_wifi_direct_state(ugd);
407 if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
408 peer->is_group_owner == TRUE) {
409 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
410 MAC2SECSTR(peer->mac_addr));
412 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
413 DBG(LOG_DEBUG, "It's in connecting status now.\n");
417 ugd->mac_addr_connecting = peer->mac_addr;
418 res = wfd_client_connect((const char *)peer->mac_addr);
420 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
430 * This function let the ug call it when click busy peer
432 * @param[in] data the pointer to the main data structure
433 * @param[in] obj the pointer to the evas object
434 * @param[in] event_info the pointer to the event information
436 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
439 struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
440 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
443 elm_genlist_item_selected_set(item, EINA_FALSE);
447 DBG(LOG_ERROR, "Data is NULL\n");
451 wfd_ug_warn_popup(ugd, _("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
456 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
458 struct ug_data *ugd = (struct ug_data *) data;
461 DBG(LOG_ERROR, "The param is NULL\n");
466 evas_object_del(ugd->ctxpopup);
467 ugd->ctxpopup = NULL;
471 void _ctxpopup_move()
475 int win_w = 0, win_h = 0;
476 int move_x = 0, move_y = 0;
478 struct ug_data *ugd = wfd_get_ug_data();
480 if (!ugd || !ugd->win) {
481 DBG(LOG_ERROR, "NULL parameters.\n");
485 if (!ugd->ctxpopup) {
486 DBG(LOG_INFO, "NULL parameters.\n");
490 elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
491 changed_ang = elm_win_rotation_get(ugd->win);
493 switch (changed_ang) {
516 evas_object_move(ugd->ctxpopup, move_x, move_y);
521 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
524 struct ug_data *ugd = (struct ug_data *) data;
525 WFD_RET_IF(ugd == NULL, "The param is NULL\n");
526 WFD_IF_DEL_OBJ(ugd->ctxpopup);
529 wfd_client_free_raw_discovered_peers(ugd);
530 ugd->raw_discovered_peer_cnt = 0;
531 wfd_create_multiconnect_view(ugd);
532 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
533 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
534 if (ret != WIFI_DIRECT_ERROR_NONE) {
535 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
536 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
537 wifi_direct_cancel_discovery();
543 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
547 Evas_Object *naviframe = (Evas_Object *)data;
548 Elm_Object_Item *multi_connect_item = NULL;
549 Elm_Object_Item *rename_item = NULL;
550 struct ug_data *ugd = wfd_get_ug_data();
552 if (!naviframe || !ugd) {
553 DBG(LOG_ERROR, "NULL parameters.\n");
557 ugd->more_btn_multiconnect_item = NULL;
560 evas_object_del(ugd->ctxpopup);
563 ugd->ctxpopup = elm_ctxpopup_add(naviframe);
564 elm_object_style_set(ugd->ctxpopup, "more/default");
565 eext_object_event_callback_add(ugd->ctxpopup, EA_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
566 eext_object_event_callback_add(ugd->ctxpopup, EA_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
567 evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
568 elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
570 elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
571 ELM_CTXPOPUP_DIRECTION_LEFT,
572 ELM_CTXPOPUP_DIRECTION_RIGHT,
573 ELM_CTXPOPUP_DIRECTION_DOWN);
577 multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
578 elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
579 ugd->more_btn_multiconnect_item = multi_connect_item;
581 wfd_refresh_wifi_direct_state(ugd);
582 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
583 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
584 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
585 ugd->raw_connected_peer_cnt > 0) {
586 elm_object_item_disabled_set(multi_connect_item, TRUE);
589 rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
590 elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
591 evas_object_show(ugd->ctxpopup);
597 * This function make items into group
599 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
603 if (count < 1 || pre_item == NULL) {
607 Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
613 elm_object_item_signal_emit(item, "elm,state,normal", "");
617 for (i = 0; i < count; i++) {
619 elm_object_item_signal_emit(item, "elm,state,top", "");
620 } else if (i == count - 1) {
621 elm_object_item_signal_emit(item, "elm,state,bottom", "");
623 elm_object_item_signal_emit(item, "elm,state,center", "");
626 item = elm_genlist_item_next_get(item);
632 * This function let the ug call it when unresized event is received
634 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
637 struct ug_data *ugd = (struct ug_data *)data;
639 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
640 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
641 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
642 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
643 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
648 * This function let the ug call it when resized event is received
650 * @param[in] data the pointer to the main data structure
651 * @param[in] obj the pointer to the evas object
652 * @param[in] event_info the pointer to the event information
654 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
658 if (!data || !event_info) {
659 DBG(LOG_ERROR, "Invalid parameters");
663 struct ug_data *ugd = (struct ug_data *)data;
664 #ifdef ACCESSIBILITY_FEATURE
665 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
666 int index = elm_genlist_item_index_get(item);
670 _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
671 _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
672 _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
673 _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
674 _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
676 #ifdef ACCESSIBILITY_FEATURE
678 if (GENLIST_HEADER_POS == index && item != NULL) {
679 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
681 Eina_Bool state = elm_check_state_get(check);
683 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
685 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
689 Evas_Object *ao = NULL;
690 ao = elm_object_item_access_object_get(item);
691 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
694 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
697 DBG(LOG_ERROR, "index = %d, get check box fail!", index);
706 * This function let the ug call it when click 'disconnect' button
708 * @param[in] data the pointer to the main data structure
709 * @param[in] obj the pointer to the evas object
710 * @param[in] event_info the pointer to the event information
712 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
715 struct ug_data *ugd = (struct ug_data *)data;
716 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
718 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
724 * This function let the ug call it when click "cancel connection" button
726 * @param[in] data the pointer to the main data structure
727 * @param[in] obj the pointer to the evas object
728 * @param[in] event_info the pointer to the event information
730 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
733 struct ug_data *ugd = (struct ug_data *)data;
734 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
736 wfd_ug_act_popup(ugd, _("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
743 * This function let the ug update the genlist item
745 * @param[in] gl_item the pointer to genlist item
747 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
750 if (gl_item != NULL) {
751 elm_genlist_item_update(gl_item);
757 * This function let the ug refresh the attributes of button
759 * @param[in] tb_item the pointer to the toolbar button
760 * @param[in] text the pointer to the text of button
761 * @param[in] enable whether the button is disabled
763 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
768 if (NULL == tb_item || NULL == text) {
769 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
773 DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
774 elm_object_domain_translatable_part_text_set(tb_item, "default",
776 elm_object_disabled_set(tb_item, !enable);
782 * This function let the ug know whether current device is connected by me
783 * @return If connected, return TRUE, else return FALSE
784 * @param[in] ugd the pointer to the main data structure
785 * @param[in] dev the pointer to the device
787 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
792 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
793 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
794 dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
804 * This function let the ug know whether current device is connected by other peer
805 * @return If connected, return TRUE, else return FALSE
806 * @param[in] ugd the pointer to the main data structure
807 * @param[in] dev the pointer to the device
809 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
813 if (ugd->I_am_group_owner == TRUE) {
814 if (dev->is_connected || dev->is_group_owner) {
820 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE) {
824 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE) {
828 if (dev->is_connected == FALSE) {
838 * This function let the ug calculate how many devices are avaliable
840 * @param[in] ugd the pointer to the main data structure
841 * @param[in] dev the pointer to the number of avaliable devices
843 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
846 GList *iterator = NULL;
848 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
849 /* Not include the device which is connected with me */
850 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
853 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
854 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) {
855 (*no_of_available_dev)++;
864 * This function let the ug calculate how many devices are busy
866 * @param[in] ugd the pointer to the main data structure
867 * @param[in] dev the pointer to the number of busy devices
869 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
872 GList *iterator = NULL;
874 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
875 /* Not include the device which is connected with me */
876 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
879 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data)) {
889 * This function let the ug calculate how many devices are connected failed
891 * @param[in] ugd the pointer to the main data structure
892 * @param[in] dev the pointer to the number of connected failed devices
894 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
897 GList *iterator = NULL;
899 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
900 /* Not include the device which is connected with me */
901 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
904 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
905 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
906 (*no_of_connect_failed_dev)++;
915 * This function let the ug create the main genlist
916 * @return the main genlist
917 * @param[in] data the pointer to the main data structure
919 static Evas_Object *_create_basic_genlist(void *data)
922 struct ug_data *ugd = (struct ug_data *) data;
923 Evas_Object *genlist;
925 genlist = elm_genlist_add(ugd->layout);
926 elm_genlist_homogeneous_set(genlist, EINA_TRUE);
927 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
928 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
930 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
932 /* Wifi ON/OFF toggle button */
933 #ifdef WFD_ON_OFF_GENLIST
934 ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
935 NULL, ELM_GENLIST_ITEM_NONE,_onoff_changed_cb, ugd);
936 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
939 evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
940 evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
941 ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
942 ELM_GENLIST_ITEM_NONE, NULL, NULL);
943 if(ugd->device_name_item != NULL)
944 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
951 * This function let the ug create no device item to append the genlist
952 * @return the main item
953 * @param[in] data the pointer to the main data structure
955 Evas_Object *_create_no_device_genlist(void *data)
958 struct ug_data *ugd = (struct ug_data *) data;
959 Elm_Object_Item *last_item = NULL;
962 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
964 if (ugd->conn_wfd_item != NULL) {
965 last_item = ugd->conn_wfd_item;
966 for (i = 0; i < ugd->gl_connected_peer_cnt; i++) {
967 last_item = elm_genlist_item_next_get(last_item);
970 last_item = ugd->device_name_item;
973 ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
974 &title_no_device_itc, (void *)ugd, NULL, last_item,
975 ELM_GENLIST_ITEM_NONE, NULL, NULL);
976 if(ugd->nodevice_title_item != NULL)
977 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
979 ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
980 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
981 if(ugd->nodevice_item != NULL)
982 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
989 * This function let the ug create busy device list
991 * @param[in] data the pointer to the main data structure
993 int _create_busy_dev_list(void *data)
996 struct ug_data *ugd = (struct ug_data *) data;
998 ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
999 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1000 if(ugd->busy_wfd_item != NULL)
1001 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1006 void wfd_free_nodivice_item(struct ug_data *ugd)
1009 WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1010 WFD_IF_DEL_ITEM(ugd->nodevice_item);
1015 * This function let the ug create avaliable device list
1017 * @param[in] data the pointer to the main data structure
1019 int _create_available_dev_genlist(void *data)
1023 struct ug_data *ugd = (struct ug_data *) data;
1024 Elm_Object_Item *last_item = NULL;
1026 wfd_free_nodivice_item(ugd);
1028 if (ugd->conn_wfd_item != NULL) {
1029 last_item = ugd->conn_wfd_item;
1030 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1031 last_item = elm_genlist_item_next_get(last_item);
1034 last_item = ugd->device_name_item;
1037 ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1038 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1039 if(ugd->avlbl_wfd_item != NULL) {
1040 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1041 elm_genlist_item_update(ugd->avlbl_wfd_item);
1048 * This function let the ug create multi connect device list
1050 * @param[in] data the pointer to the main data structure
1052 static int _create_multi_connect_dev_genlist(void *data)
1055 struct ug_data *ugd = (struct ug_data *) data;
1057 ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1058 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1059 if(ugd->multi_connect_wfd_item != NULL)
1060 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1066 * This function let the ug create connected device list
1068 * @param[in] data the pointer to the main data structure
1070 int _create_connected_dev_genlist(void *data)
1073 struct ug_data *ugd = (struct ug_data *) data;
1075 ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1076 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1077 if(ugd->conn_wfd_item != NULL) {
1078 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1079 elm_genlist_item_update(ugd->conn_wfd_item);
1087 * This function let the ug create connected falied device list
1089 * @param[in] data the pointer to the main data structure
1091 int _create_connected_failed_dev_genlist(void *data)
1094 struct ug_data *ugd = (struct ug_data *) data;
1095 Elm_Object_Item *last_item = NULL;
1098 if (ugd->avlbl_wfd_item != NULL) {
1099 last_item = ugd->avlbl_wfd_item;
1100 for (i=0; i<ugd->gl_available_peer_cnt; i++) {
1101 last_item = elm_genlist_item_next_get(last_item);
1103 } else if (ugd->conn_wfd_item != NULL) {
1104 last_item = ugd->conn_wfd_item;
1105 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1106 last_item = elm_genlist_item_next_get(last_item);
1109 last_item = ugd->device_name_item;
1112 ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1113 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1114 if(ugd->conn_failed_wfd_item != NULL)
1115 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1121 * This function let the ug make the display callback for connect failed peers
1122 * @return if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1123 * @param[in] data the pointer to the user data
1125 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1130 struct ug_data *ugd = (struct ug_data *) user_data;
1133 DBG(LOG_ERROR, "NULL parameters.\n");
1134 return ECORE_CALLBACK_CANCEL;
1137 if (ugd->avlbl_wfd_item == NULL) {
1138 _create_available_dev_genlist(ugd);
1141 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1142 DBG(LOG_INFO, "Background mode\n");
1143 ugd->display_timer = NULL;
1144 return ECORE_CALLBACK_CANCEL;
1147 /* check the timeout, if not timeout, keep the cb */
1148 interval = time(NULL) - ugd->last_display_time;
1149 if (interval < MAX_DISPLAY_TIME_OUT) {
1150 return ECORE_CALLBACK_RENEW;
1153 if (ugd->is_paused == false) {
1154 DBG(LOG_INFO, "Not Paused");
1155 /* start discovery again */
1156 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1157 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1158 if (res != WIFI_DIRECT_ERROR_NONE) {
1159 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1160 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1161 wifi_direct_cancel_discovery();
1165 ugd->display_timer = NULL;
1167 return ECORE_CALLBACK_CANCEL;
1170 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1173 device_type_s *peer_for_free = NULL;
1174 device_type_s *peer = gl_peers_start;
1176 while (peer != NULL && peer->gl_item != NULL) {
1177 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1178 elm_object_item_del(peer->gl_item);
1179 peer->gl_item = NULL;
1180 peer_for_free = peer;
1182 free(peer_for_free);
1187 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1190 if (ugd->gl_connected_peer_cnt == 0) {
1191 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1197 * This function let the ug free the peers
1199 * @param[in] data the pointer to the main data structure
1201 void wfd_ug_view_free_peers(void *data)
1205 struct ug_data *ugd = (struct ug_data *) data;
1207 ugd->gl_connected_peer_cnt = 0;
1209 if (ugd->gl_conn_peers_start != NULL) {
1210 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1211 ugd->gl_conn_peers_start = NULL;
1214 ugd->gl_available_peer_cnt = 0;
1216 if (ugd->gl_avlb_peers_start != NULL) {
1217 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1218 ugd->gl_avlb_peers_start = NULL;
1221 ugd->gl_busy_peer_cnt = 0;
1223 if (ugd->gl_busy_peers_start != NULL) {
1224 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1225 ugd->gl_busy_peers_start = NULL;
1228 ugd->gl_multi_connect_peer_cnt = 0;
1230 if (ugd->gl_mul_conn_peers_start != NULL) {
1231 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1232 ugd->gl_mul_conn_peers_start = NULL;
1235 if (ugd->gl_connected_peer_cnt == 0) {
1236 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1239 if (ugd->display_timer != NULL) {
1240 ecore_timer_del(ugd->display_timer);
1241 ugd->display_timer = NULL;
1244 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1245 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1246 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1247 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1252 void wfd_ug_update_toolbar(struct ug_data *ugd)
1255 int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1258 wfd_refresh_wifi_direct_state(ugd);
1259 if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1260 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1261 if( ugd->multi_connect_wfd_item != NULL) {
1262 DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1263 btn = elm_button_add(ugd->layout);
1264 /* Use "bottom" style button */
1265 elm_object_style_set(btn, "bottom");
1266 elm_object_domain_translatable_text_set(btn, PACKAGE,
1267 "IDS_WIFI_SK2_CANCEL_CONNECTION");
1268 evas_object_smart_callback_add(btn, "clicked",
1269 _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1270 /* Set button into "toolbar" swallow part */
1271 elm_object_part_content_set(ugd->layout, "button.next", btn);
1272 ugd->disconnect_btn = btn;
1273 evas_object_show(ugd->disconnect_btn);
1274 elm_object_part_content_set(ugd->layout, "button.prev",
1276 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1277 "IDS_WIFI_SK4_SCAN", FALSE);
1278 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1279 DBG(LOG_INFO, "button: disconnect button added\n");
1281 DBG(LOG_INFO, "scan_toolbar\n");
1282 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1283 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1284 "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1285 evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1286 DBG(LOG_INFO, "button: stop connect button added\n");
1288 } else if (no_of_conn_dev > 0) {
1289 if (!ugd->multi_connect_toolbar_item) {
1290 btn = elm_button_add(ugd->layout);
1291 /* Use "bottom" style button */
1292 elm_object_style_set(btn, "bottom");
1293 elm_object_domain_translatable_text_set(btn, PACKAGE,
1294 "IDS_WIFI_SK_DISCONNECT");
1295 evas_object_smart_callback_add(btn, "clicked",
1296 _wfd_ug_disconnect_button_cb, (void *)ugd);
1297 /* Set button into "toolbar" swallow part */
1298 elm_object_part_content_set(ugd->layout, "button.next", btn);
1299 ugd->disconnect_btn = btn;
1300 evas_object_show(ugd->disconnect_btn);
1302 elm_object_part_content_set(ugd->layout, "button.prev",
1304 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1305 "IDS_WIFI_SK4_SCAN", TRUE);
1306 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1307 DBG(LOG_INFO, "button: disconnect button added\n");
1309 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1310 DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1311 Evas_Object *content;
1312 content = elm_object_part_content_unset(ugd->layout, "button.next");
1313 WFD_IF_DEL_OBJ(content);
1314 ugd->disconnect_btn = NULL;
1315 elm_object_part_content_set(ugd->layout, "button.big",
1318 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1319 "IDS_WIFI_SK4_SCAN", TRUE);
1320 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1321 DBG(LOG_INFO, "button: scan button added\n");
1327 * This function let the ug init the genlist
1329 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1332 struct ug_data *ugd = (struct ug_data *) data;
1333 int no_of_busy_dev = 0;
1334 int no_of_available_dev = 0;
1335 int no_of_conn_failed_dev = 0;
1337 if (is_free_all_peers) {
1338 wfd_ug_view_free_peers(ugd);
1341 if (ugd->gl_failed_peers_start != NULL) {
1342 DBG(LOG_INFO, "These are failed peers, must clear them");
1343 ugd->gl_connected_failed_peer_cnt = 0;
1344 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1345 ugd->gl_failed_peers_start = NULL;
1346 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1349 if (ugd->avlbl_wfd_item != NULL) {
1350 DBG(LOG_INFO, "There are available peers in genlist");
1351 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1355 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1356 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1357 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1363 * This function let the ug find a peer in genlist
1365 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1369 if (start_pos == NULL) {
1370 DBG(LOG_INFO, "no peer in genlist");
1374 device_type_s *peer = start_pos;
1376 while (peer != NULL) {
1377 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1378 peer->is_alive = true;
1379 DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1390 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1393 if (*start_pos == NULL) {
1394 DBG(LOG_INFO, "no peer in genlist");
1398 device_type_s *peer = *start_pos;
1399 device_type_s *peer_tmp = NULL;
1400 while (peer != NULL) {
1401 peer_tmp = peer->next;
1402 if(peer->is_alive == false) {
1403 free_gl_peer(start_pos, peer->mac_addr, cnt);
1408 // wfd_check_gl_available_peers(ugd);
1409 if (ugd->gl_busy_peer_cnt == 0) {
1410 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1416 void set_not_alive_peers(device_type_s *start_pos)
1419 if (start_pos == NULL) {
1420 DBG(LOG_INFO, "no peer in genlist");
1424 device_type_s *peer = start_pos;
1425 while (peer != NULL) {
1426 peer->is_alive = false;
1435 * This function let the ug get the insert position for next item
1437 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1441 device_type_s *peer_ite = NULL;
1442 Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1443 Elm_Object_Item *item = NULL;
1446 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1450 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1451 if(peer_ite->gl_item != NULL) {
1452 for(i=0; i < peer_cnt; i++) {
1453 if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1454 /* if peer_ite is greater than peer, return previous item */
1456 return elm_genlist_item_prev_get(head);
1458 item = elm_genlist_item_next_get(head);
1460 /* return the last item */
1464 peer_ite = (device_type_s *)elm_object_item_data_get(head);
1470 return elm_genlist_item_prev_get(head);
1474 * This function let the ug insert peer item to genlist
1476 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1477 device_type_s *peer_for_insert, void *callback)
1480 WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1481 device_type_s *peer = NULL;
1482 device_type_s *peer_ite = NULL;
1484 peer = (device_type_s *)malloc(sizeof(device_type_s));
1485 WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1487 memcpy(peer, peer_for_insert, sizeof(device_type_s));
1490 if(*start_pos == NULL) {
1493 peer_ite = *start_pos;
1494 while(peer_ite->next != NULL) {
1495 /* move pointer to the last peer */
1496 peer_ite = peer_ite->next;
1498 peer_ite->next = peer;
1501 peer->is_alive = true;
1502 peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1503 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1504 if (callback == NULL && peer->gl_item != NULL) {
1505 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1512 * This function let the ug update connected peers
1514 * @param[in] data the pointer to the main data structure
1516 void wfd_ug_update_connected_peers(void *data)
1520 struct ug_data *ugd = (struct ug_data *) data;
1523 bool is_group_owner = FALSE;
1524 Elm_Object_Item *item = NULL;
1526 res = wifi_direct_is_group_owner(&is_group_owner);
1527 if (res == WIFI_DIRECT_ERROR_NONE) {
1528 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1531 if (!ugd->conn_wfd_item) {
1532 _create_connected_dev_genlist(ugd);
1535 for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1536 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1537 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1538 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1539 &ugd->gl_available_peer_cnt);
1540 wfd_check_gl_available_peers(ugd);
1543 if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1544 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1545 &ugd->gl_multi_connect_peer_cnt);
1546 if (ugd->gl_multi_connect_peer_cnt == 0) {
1547 WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1548 WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1552 item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1553 ugd->gl_connected_peer_cnt);
1554 res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1555 &ugd->raw_connected_peers[i], NULL);
1559 ugd->gl_connected_peer_cnt++;
1563 /* if is not GO, free all available peers */
1564 if (is_group_owner == FALSE) {
1565 ugd->gl_available_peer_cnt = 0;
1566 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1568 if (ugd->gl_avlb_peers_start != NULL) {
1569 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1570 ugd->gl_avlb_peers_start = NULL;
1574 /* free busy peers */
1575 if (ugd->gl_busy_peers_start != NULL) {
1576 ugd->gl_busy_peer_cnt = 0;
1577 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1579 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1580 ugd->gl_busy_peers_start = NULL;
1588 * This function let the ug update the multi-connect peers
1590 * @param[in] data the pointer to the main data structure
1592 void wfd_ug_view_update_multiconn_peers(void *data)
1596 struct ug_data *ugd = (struct ug_data *) data;
1599 Elm_Object_Item *item = NULL;
1601 if (ugd->raw_multi_selected_peer_cnt > 0) {
1602 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1603 ugd->multi_connect_wfd_item == NULL) {
1604 _create_multi_connect_dev_genlist(ugd);
1607 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1608 if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1609 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1610 ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1611 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1612 &ugd->raw_multi_selected_peers[i], NULL);
1616 ugd->gl_multi_connect_peer_cnt++;
1625 * This function let the ug update the available and busy peers
1627 void wfd_ug_update_available_peers(void *data)
1631 struct ug_data *ugd = (struct ug_data *) data;
1632 int no_of_busy_dev = 0;
1633 int no_of_available_dev = 0;
1634 int no_of_conn_dev = 0;
1635 bool is_group_owner = FALSE;
1637 Elm_Object_Item *item = NULL;
1638 device_type_s *peer = NULL;
1639 GList *iterator = NULL;
1641 __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1642 __wfd_is_any_device_available(ugd, &no_of_available_dev);
1643 no_of_conn_dev = ugd->raw_connected_peer_cnt;
1645 res = wifi_direct_is_group_owner(&is_group_owner);
1646 if (res != WIFI_DIRECT_ERROR_NONE) {
1647 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1648 ugd->I_am_group_owner = FALSE;
1650 ugd->I_am_group_owner = is_group_owner;
1653 DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1654 if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1655 DBG(LOG_INFO, "There are available or busy peers\n");
1656 wfd_free_nodivice_item(ugd);
1659 if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1660 if (ugd->avlbl_wfd_item == NULL) {
1661 _create_available_dev_genlist(ugd);
1664 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1665 /* Not include the device which is connected with me */
1666 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1669 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1670 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1671 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1672 /* free disconnected gl peer */
1673 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1674 free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1675 &ugd->gl_connected_peer_cnt);
1678 /* free busy gl peer, which is available now */
1679 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1680 free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1681 if (ugd->gl_busy_peer_cnt == 0) {
1682 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1686 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL) {
1690 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1692 item = get_insert_postion((device_type_s *)iterator->data,
1693 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1694 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1695 (device_type_s *)iterator->data, _gl_peer_sel);
1699 ugd->gl_available_peer_cnt++;
1700 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1701 /* if peer is GO, free it */
1702 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1703 &ugd->gl_available_peer_cnt);
1709 wfd_check_gl_available_peers(ugd);
1710 wfd_check_gl_conn_peers(ugd);
1712 if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1713 if (ugd->busy_wfd_item == NULL) {
1714 _create_busy_dev_list(ugd);
1717 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1718 /* Not include the device which is connected with me */
1719 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1722 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1723 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1724 if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1725 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1726 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1727 &ugd->gl_available_peer_cnt);
1728 wfd_check_gl_available_peers(ugd);
1730 item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1731 ugd->gl_busy_peer_cnt);
1732 res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1733 (device_type_s *)iterator->data, _gl_busy_peer_sel);
1737 ugd->gl_busy_peer_cnt++;
1743 wfd_check_gl_busy_peers(ugd);
1749 * This function let the ug update the failed peers
1751 * @param[in] data the pointer to the main data structure
1753 void wfd_ug_update_failed_peers(void *data)
1756 struct ug_data *ugd = (struct ug_data *) data;
1757 int no_of_conn_failed_dev = 0;
1758 GList *iterator = NULL;
1760 __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1761 DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1763 if (no_of_conn_failed_dev == 0) {
1767 /* add timer for disappearing failed peers after N secs */
1768 if (NULL == ugd->display_timer) {
1769 ugd->last_display_time = time(NULL);
1770 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1773 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1774 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1775 ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1776 if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1777 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1778 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1779 &ugd->gl_available_peer_cnt);
1780 wfd_check_gl_available_peers(ugd);
1789 #ifdef WFD_ON_OFF_GENLIST
1791 * This function is called when user swipes on/off button
1793 * @param[in] data the pointer to the main data structure
1794 * @param[in] obj the pointer to the evas object
1795 * @param[in] event_info the pointer to the event information
1797 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1800 struct ug_data *ugd = (struct ug_data *)data;
1801 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1802 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1803 wfd_refresh_wifi_direct_state(ugd);
1804 if(ugd->device_name_item != NULL)
1805 elm_genlist_item_update(ugd->device_name_item);
1807 elm_object_disabled_set(ugd->on_off_check, TRUE);
1808 if(ugd->disconnect_btn) {
1809 Evas_Object *content;
1810 content = elm_object_part_content_unset(ugd->layout, "button.next");
1811 WFD_IF_DEL_OBJ(content);
1812 ugd->disconnect_btn = NULL;
1814 elm_object_part_content_set(ugd->layout, "button.big", ugd->scan_toolbar);
1816 /* turn on/off wfd */
1817 if (!ugd->wfd_onoff) {
1818 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1819 DBG(LOG_INFO, "wifi-direct switch on\n");
1820 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1822 wfd_client_switch_on(ugd);
1825 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1826 DBG(LOG_INFO, "wifi-direct switch off\n");
1827 elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1829 wfd_client_switch_off(ugd);
1836 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1839 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1840 WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1842 wfd_refresh_wifi_direct_state(ugd);
1843 if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1844 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING ) {
1845 elm_object_disabled_set(ugd->on_off_check, TRUE);
1847 elm_object_disabled_set(ugd->on_off_check, FALSE);
1849 if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1850 elm_check_state_set(ugd->on_off_check, TRUE);
1852 elm_check_state_set(ugd->on_off_check, FALSE);
1858 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1861 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1862 WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1864 Evas_Object *check = elm_check_add(ugd->naviframe);
1865 elm_object_style_set(check, "naviframe/title_on&off");
1866 elm_check_state_set(check, ugd->wfd_onoff);
1867 evas_object_propagate_events_set(check, EINA_FALSE);
1868 evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1869 elm_object_focus_allow_set(check, EINA_TRUE);
1870 elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1871 evas_object_show(check);
1872 ugd->on_off_check = check;
1879 * This function let the ug create the main view
1881 * @param[in] data the pointer to the main data structure
1883 void create_wfd_ug_view(void *data)
1886 struct ug_data *ugd = (struct ug_data *) data;
1887 WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1888 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1889 Evas_Object *more_btn;
1891 Evas_Object *layout;
1893 ugd->naviframe = elm_naviframe_add(ugd->base);
1894 elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1895 eext_object_event_callback_add(ugd->naviframe, EA_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1896 eext_object_event_callback_add(ugd->naviframe, EA_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1897 elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1899 ugd->back_btn = elm_button_add(ugd->naviframe);
1900 elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1901 evas_object_smart_callback_add(ugd->back_btn, "clicked", _back_btn_cb, (void *)ugd);
1902 elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1905 layout = elm_layout_add(ugd->naviframe);
1906 elm_layout_file_set(layout, WFD_UG_EDJ_PATH, "main_layout");
1907 ugd->layout = layout;
1909 ugd->genlist = _create_basic_genlist(ugd);
1910 if (ugd->genlist == NULL) {
1911 DBG(LOG_ERROR, "Failed to create basic genlist");
1914 elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
1916 elm_genlist_fx_mode_set(ugd->genlist, EINA_FALSE);
1917 evas_object_show(ugd->base);
1918 elm_object_focus_set(ugd->base, EINA_TRUE);
1920 ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
1921 ugd->back_btn, NULL, layout, NULL);
1922 elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
1924 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1925 more_btn = elm_button_add(ugd->naviframe);
1926 elm_object_style_set(more_btn, "naviframe/more/default");
1927 evas_object_smart_callback_add(more_btn, "clicked",
1928 _more_button_cb, ugd->win);
1929 elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
1933 wifi_direct_initialize();
1934 wifi_direct_get_state(&ugd->wfd_status);
1935 if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING) {
1936 scan_button_create(ugd);
1939 if (ugd->view_type && g_strcmp0(_(ugd->view_type), _("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
1941 ugd->raw_discovered_peer_cnt = 0;
1942 wfd_create_multiconnect_view(ugd);
1943 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1944 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1945 if (ret != WIFI_DIRECT_ERROR_NONE) {
1946 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1947 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
1948 wifi_direct_cancel_discovery();
1957 * This function let the ug destroy the main view
1959 * @param[in] data the pointer to the main data structure
1961 void destroy_wfd_ug_view(void *data)
1964 struct ug_data *ugd = (struct ug_data *) data;
1965 WFD_IF_DEL_ITEM(ugd->device_name_item);
1966 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1967 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1969 WFD_IF_DEL_OBJ(ugd->scan_toolbar);
1970 WFD_IF_DEL_OBJ(ugd->back_btn);
1971 WFD_IF_DEL_OBJ(ugd->toolbar);
1972 WFD_IF_DEL_OBJ(ugd->genlist);
1973 WFD_IF_DEL_OBJ(ugd->naviframe);