Tizen directory path migration
[apps/native/ug-wifi-direct.git] / ug-wifidirect / src / wfd_ug_main_view.c
1 /*
2 *  WiFi-Direct UG
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
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
9
10 * http://www.tizenopensource.org/license
11
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.
17 *
18 */
19
20
21 #include <libintl.h>
22 #include <glib.h>
23
24 #include <Elementary.h>
25 #include <vconf.h>
26 #include <ui-gadget-module.h>
27 #include <app_control.h>
28 #include <efl_extension.h>
29
30 #include "wfd_ug.h"
31 #include "wfd_ug_view.h"
32 #include "wfd_client.h"
33
34 void scan_button_create(struct ug_data *ugd)
35 {
36         __FUNC_ENTER__;
37
38         Evas_Object *btn_ly = NULL;
39         Evas_Object *btn = NULL;
40
41         btn_ly = elm_layout_add(ugd->layout);
42         elm_layout_file_set(btn_ly, WFD_UG_EDJ_PATH, "bottom_btn");
43         ugd->button_layout = btn_ly;
44
45         btn = elm_button_add(ugd->button_layout);
46         elm_object_style_set(btn, "bottom");
47         elm_object_domain_translatable_text_set(btn, PACKAGE, "IDS_WIFI_SK4_SCAN");
48         if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
49                 wfd_ug_view_refresh_button(btn, "IDS_WIFI_SK4_SCAN",
50                         FALSE);
51         }
52         evas_object_smart_callback_add(btn, "clicked",_scan_btn_cb, (void *)ugd);
53         elm_layout_content_set(ugd->button_layout, "button.big", btn);
54         ugd->scan_toolbar = btn;
55
56         elm_object_part_content_set(ugd->naviframe, "toolbar", ugd->button_layout);
57         evas_object_show(ugd->button_layout);
58
59         __FUNC_EXIT__;
60 }
61
62 /**
63  *      This function let the ug call it when click 'back' button
64  *      @return   void
65  *      @param[in] data the pointer to the main data structure
66  *      @param[in] obj the pointer to the evas object
67  *      @param[in] event_info the pointer to the event information
68  */
69 Eina_Bool _back_btn_cb(void *data, Elm_Object_Item *it)
70 {
71         __FUNC_ENTER__;
72         struct ug_data *ugd = (struct ug_data *) data;
73         WFD_RETV_IF(ugd == NULL, FALSE, "The param is NULL\n");
74         int ret = -1;
75         bool owner = FALSE;
76         app_control_h control = NULL;
77
78 #ifdef WFD_DBUS_LAUNCH
79         if (ugd->dbus_cancellable != NULL) {
80                 g_cancellable_cancel(ugd->dbus_cancellable);
81                 g_object_unref(ugd->dbus_cancellable);
82                 ugd->dbus_cancellable = NULL;
83                 if (ugd->conn) {
84                         g_object_unref(ugd->conn);
85                         ugd->conn = NULL;
86                 }
87                 DBG(LOG_INFO, "Cancel dbus call");
88         }
89 #endif
90
91         wfd_refresh_wifi_direct_state(ugd);
92         if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
93                 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
94                 goto cleanup;
95         }
96
97         if (NULL != ugd->mac_addr_connecting) {
98                 if (ugd->is_conn_incoming) {
99                         DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
100                         ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
101                         if (ret != WIFI_DIRECT_ERROR_NONE) {
102                                 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
103                         }
104                 } else {
105                         DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
106                         ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
107                         if (ret != WIFI_DIRECT_ERROR_NONE) {
108                                 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
109                         }
110                 }
111                 ugd->mac_addr_connecting = NULL;
112         }
113
114         if (ugd->raw_connected_peer_cnt == 0) {
115                 ret = wifi_direct_is_group_owner(&owner);
116                 if (ret == WIFI_DIRECT_ERROR_NONE) {
117                         if (owner) {
118                                 wifi_direct_destroy_group();
119                         }
120                 }
121         }
122
123 cleanup:
124         wfd_ug_view_free_peers(ugd);
125         ret = app_control_create(&control);
126         if (ret) {
127                 DBG(LOG_ERROR, "Failed to create control");
128         } else {
129                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) {
130                         app_control_add_extra_data(control, "Connection", "TRUE");
131                 } else {
132                         app_control_add_extra_data(control, "Connection", "FALSE");
133                 }
134
135                 ug_send_result(ugd->ug, control);
136                 app_control_destroy(control);
137         }
138
139         ug_destroy_me(ugd->ug);
140         __FUNC_EXIT__;
141         return FALSE;
142 }
143
144 /**
145  *      This function let the ug call it when click 'back' button
146  *      @return   void
147  *      @param[in] data the pointer to the main data structure
148  *      @param[in] obj the pointer to the evas object
149  *      @param[in] event_info the pointer to the event information
150  */
151 void _smart_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
152 {
153         __FUNC_ENTER__;
154         struct ug_data *ugd = (struct ug_data *) data;
155         int ret = -1;
156         bool owner = FALSE;
157         app_control_h control = NULL;
158
159         if(ugd == NULL) {
160                 DBG(LOG_ERROR, "The param is NULL");
161                 return;
162         }
163
164 #ifdef WFD_DBUS_LAUNCH
165         if (ugd->dbus_cancellable != NULL) {
166                 g_cancellable_cancel(ugd->dbus_cancellable);
167                 g_object_unref(ugd->dbus_cancellable);
168                 ugd->dbus_cancellable = NULL;
169                 if (ugd->conn) {
170                         g_object_unref(ugd->conn);
171                         ugd->conn = NULL;
172                 }
173                 DBG(LOG_INFO, "Cancel dbus call");
174         }
175 #endif
176
177         wfd_refresh_wifi_direct_state(ugd);
178         if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
179                 DBG(LOG_INFO, "WiFi direct is already deactivated\n");
180                 goto cleanup;
181         }
182
183         if (NULL != ugd->mac_addr_connecting) {
184                 if (ugd->is_conn_incoming) {
185                         DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
186                         ret = wifi_direct_reject_connection(ugd->mac_addr_connecting);
187                         if (ret != WIFI_DIRECT_ERROR_NONE) {
188                                 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", ret);
189                         }
190                 } else {
191                         DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
192                         ret = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
193                         if (ret != WIFI_DIRECT_ERROR_NONE) {
194                                 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", ret);
195                         }
196                 }
197                 ugd->mac_addr_connecting = NULL;
198         }
199
200         if (ugd->raw_connected_peer_cnt == 0) {
201                 ret = wifi_direct_is_group_owner(&owner);
202                 if (ret == WIFI_DIRECT_ERROR_NONE) {
203                         if (owner) {
204                                 wifi_direct_destroy_group();
205                         }
206                 }
207         }
208
209 cleanup:
210         wfd_ug_view_free_peers(ugd);
211         ret = app_control_create(&control);
212         if (ret) {
213                 DBG(LOG_ERROR, "Failed to create control");
214         } else {
215                 if (ugd->wfd_status > WIFI_DIRECT_STATE_CONNECTING) {
216                         app_control_add_extra_data(control, "Connection", "TRUE");
217                 } else {
218                         app_control_add_extra_data(control, "Connection", "FALSE");
219                 }
220
221                 ug_send_result(ugd->ug, control);
222                 app_control_destroy(control);
223         }
224
225         ug_destroy_me(ugd->ug);
226         __FUNC_EXIT__;
227         return;
228 }
229
230 void wfd_cancel_progressbar_stop_timer(struct ug_data *ugd)
231 {
232         __FUNC_ENTER__;
233
234         if(ugd->timer_stop_progress_bar > 0) {
235                 g_source_remove(ugd->timer_stop_progress_bar);
236         }
237         ugd->timer_stop_progress_bar = 0;
238
239         __FUNC_EXIT__;
240 }
241
242 void wfd_cancel_not_alive_delete_timer(struct ug_data *ugd)
243 {
244         __FUNC_ENTER__;
245
246         if(ugd->timer_delete_not_alive_peer > 0) {
247                 g_source_remove(ugd->timer_delete_not_alive_peer);
248         }
249         ugd->timer_delete_not_alive_peer = 0;
250
251         __FUNC_EXIT__;
252 }
253
254 /**
255  *      This function let the ug call it when click failed devices item
256  *      @return   void
257  *      @param[in] data the pointer to the main data structure
258  *      @param[in] obj the pointer to the evas object
259  *      @param[in] event_info the pointer to the event information
260  */
261 void _gl_failed_peer_cb(void *data, Evas_Object *obj, void *event_info)
262 {
263         __FUNC_ENTER__;
264
265         struct ug_data *ugd = wfd_get_ug_data();
266         int ret = -1;
267
268         if (NULL == ugd) {
269                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
270                 return;
271         }
272
273         if (ugd->display_timer != NULL) {
274                 ecore_timer_del(ugd->display_timer);
275                 ugd->display_timer = NULL;
276         }
277
278         wfd_refresh_wifi_direct_state(ugd);
279         DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
280
281         /* if connected, show the popup*/
282         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
283                 wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
284         } else {
285                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
286                 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
287                 if (ret != WIFI_DIRECT_ERROR_NONE) {
288                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
289                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
290                         wifi_direct_cancel_discovery();
291                 }
292         }
293
294         __FUNC_EXIT__;
295         return;
296 }
297
298 /**
299  *      This function let the ug call it when click 'scan' button
300  *      @return   void
301  *      @param[in] data the pointer to the main data structure
302  *      @param[in] obj the pointer to the evas object
303  *      @param[in] event_info the pointer to the event information
304  */
305 void _scan_btn_cb(void *data, Evas_Object *obj, void *event_info)
306 {
307         __FUNC_ENTER__;
308
309         struct ug_data *ugd = (struct ug_data *) data;
310         if (NULL == ugd) {
311                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
312                 return;
313         }
314         int ret = -1;
315         const char *btn_text = NULL;
316         btn_text = elm_object_part_text_get(ugd->scan_toolbar, "default");
317         DBG(LOG_INFO, "Button text=%s",btn_text);
318
319         if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK4_SCAN"))) {
320                 wfd_refresh_wifi_direct_state(ugd);
321                 DBG(LOG_INFO, "Start discovery again, status: %d\n", ugd->wfd_status);
322                 /* if connected, show the popup*/
323                 if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED || ugd->raw_connected_peer_cnt > 0) {
324                         wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_SO_THAT_SCANNING_CAN_START_CONTINUE_Q"), POP_TYPE_SCAN_AGAIN);
325                 } else if (WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status) {
326                         wfd_client_switch_on(ugd);
327                         __FUNC_EXIT__;
328                         return;
329                 } else {
330                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
331                         ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
332                         if (ret != WIFI_DIRECT_ERROR_NONE) {
333                                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
334                                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
335                                 wifi_direct_cancel_discovery();
336                         }
337                 }
338         } else if (!g_strcmp0(elm_object_text_get(obj), D_("IDS_WIFI_SK_STOP"))) {
339                 DBG(LOG_INFO, "Stop pressed.\n");
340                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_STOPPED;
341                 wfd_cancel_progressbar_stop_timer(ugd);
342                 wfd_delete_progressbar_cb(ugd);
343                 wfd_cancel_not_alive_delete_timer(ugd);
344         } else if (0 == strcmp(D_("IDS_WIFI_SK2_CANCEL_CONNECTION"), btn_text)) {
345                 DBG(LOG_INFO, "Cancel Connection");
346                 wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
347         } else {
348                 DBG(LOG_INFO, "Invalid Case\n");
349         }
350         __FUNC_EXIT__;
351         return;
352 }
353
354 void wfd_check_gl_busy_peers(struct ug_data *ugd)
355 {
356         __FUNC_ENTER__;
357         if (ugd->gl_busy_peer_cnt == 0) {
358                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
359         }
360         __FUNC_EXIT__;
361 }
362
363 void wfd_check_gl_available_peers(struct ug_data *ugd)
364 {
365         __FUNC_ENTER__;
366         if (ugd->gl_available_peer_cnt == 0 && ugd->avlbl_wfd_item != NULL) {
367                 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
368         }
369         __FUNC_EXIT__;
370 }
371
372 /**
373  *      This function let the ug free some peer in genlist
374  *      @return  void
375  *      @param[in] start_pos the start position of peers list
376  *      @param[in] mac_addr the mac_addr of peer for free
377  *      @param[in] cnt the count of gl peers in list
378  */
379 void free_gl_peer(device_type_s **start_pos, const char *mac_addr, int *cnt)
380 {
381         __FUNC_ENTER__;
382         device_type_s *peer = *start_pos;
383         device_type_s *peer_tmp = peer;
384
385         if (peer == NULL) {
386                 DBG(LOG_INFO, "no peer in genlist");
387                 return;
388         }
389
390         while (peer) {
391                 if(strcmp(peer->mac_addr, mac_addr)) {
392                         peer_tmp = peer;
393                         peer = peer->next;
394                 } else {
395                         if(peer->next != NULL) {
396                                 peer_tmp->next = peer->next;
397                                 break;
398                         } else {
399                                 peer_tmp->next = NULL;
400                                 break;
401                         }
402                 }
403         }
404
405         if (peer == *start_pos) {
406                 DBG(LOG_INFO, "the head is free");
407                 *start_pos = peer->next;
408         }
409
410         (*cnt)--;
411         if (peer) {
412                 WFD_IF_DEL_ITEM(peer->gl_item);
413                 peer->next = NULL;
414                 free(peer);
415         }
416         __FUNC_EXIT__;
417 }
418
419 /**
420  *      This function let the ug call it when click avaliable peer to connect
421  *      @return   void
422  *      @param[in] data the pointer to the main data structure
423  *      @param[in] obj the pointer to the evas object
424  *      @param[in] event_info the pointer to the event information
425  */
426 static void _gl_peer_sel(void *data, Evas_Object *obj, void *event_info)
427 {
428         __FUNC_ENTER__;
429
430         int res = -1;
431         char txt[MAX_POPUP_TEXT_SIZE] = {0,};
432         char popup_text[MAX_POPUP_TEXT_SIZE] = {0, };
433         bool is_peer_alive = false;
434         struct ug_data *ugd = wfd_get_ug_data();
435         device_type_s *peer = (device_type_s *)data;
436         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
437
438         if (!ugd || !peer) {
439                 DBG(LOG_ERROR, "NULL parameters.\n");
440                 return;
441         }
442
443         wfd_ug_get_connected_peers(ugd);
444         DBG(LOG_INFO, "No of connected peers= %d",ugd->raw_connected_peer_cnt);
445
446         if (ugd->raw_connected_peer_cnt >= MAX_CONNECTED_PEER_NUM) {
447                 snprintf(popup_text, MAX_POPUP_TEXT_SIZE, D_("IDS_ST_POP_YOU_CAN_CONNECT_UP_TO_PD_DEVICES_AT_THE_SAME_TIME"), MAX_CONNECTED_PEER_NUM);
448                 wfd_ug_warn_popup(ugd, popup_text, POP_TYPE_MULTI_CONNECT_POPUP);
449                 if (item) {
450                         elm_genlist_item_selected_set(item, EINA_FALSE);
451                 }
452                 return;
453         }
454
455         if (ugd->disconnect_btn) {
456                 Evas_Object *content;
457                 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
458                 WFD_IF_DEL_OBJ(content);
459                 ugd->disconnect_btn = NULL;
460                 elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
461         }
462
463         if (item) {
464                 elm_genlist_item_selected_set(item, EINA_FALSE);
465         }
466
467         GList *iterator = NULL;
468
469         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
470                 if (!strncmp(peer->mac_addr, (const char *)((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH)) {
471                         /* peer is found in last discovery */
472                         is_peer_alive = true;
473                         break;
474                 }
475         }
476
477         if (!is_peer_alive) {
478                 /* peer exists only in genlist, waiting to be deleted */
479                 device_type_s *peer_start = ugd->gl_avlb_peers_start;
480                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
481                         if(!strncmp(peer_start->mac_addr, peer->mac_addr, MAC_LENGTH)) {
482                                 DBG(LOG_INFO, "Device [%s] found in genlist, but it is already lost", ((device_type_s *)iterator->data)->ssid);
483                                 snprintf(txt, sizeof(txt), "Cannot find device %s", ((device_type_s *)iterator->data)->ssid);
484                                 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_available_peer_cnt);
485                                 wfd_check_gl_available_peers(ugd);
486                                 wfd_ug_warn_popup(ugd, txt, POPUP_TYPE_INFO);
487                                 return;
488                         }
489                 }
490         }
491
492         wfd_cancel_not_alive_delete_timer(ugd);
493
494         /* get WFD status */
495         wfd_refresh_wifi_direct_state(ugd);
496
497         if (PEER_CONN_STATUS_DISCONNECTED == peer->conn_status ||
498                 peer->is_group_owner == TRUE) {
499                 DBG_SECURE(LOG_DEBUG, "Connect with peer ["MACSECSTR"]\n",
500                         MAC2SECSTR(peer->mac_addr));
501
502                 if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status) {
503                         DBG(LOG_DEBUG, "It's in connecting status now.\n");
504                         return;
505                 }
506
507                 ugd->mac_addr_connecting = peer->mac_addr;
508                 res = wfd_client_connect((const char *)peer->mac_addr);
509                 if (res != 0) {
510                         DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
511                         return;
512                 }
513         }
514
515         __FUNC_EXIT__;
516         return;
517 }
518
519 /**
520  *      This function let the ug call it when click busy peer
521  *      @return   void
522  *      @param[in] data the pointer to the main data structure
523  *      @param[in] obj the pointer to the evas object
524  *      @param[in] event_info the pointer to the event information
525  */
526 static void _gl_busy_peer_sel(void *data, Evas_Object *obj, void *event_info)
527 {
528         __FUNC_ENTER__;
529         struct ug_data *ugd = (struct ug_data *)wfd_get_ug_data();
530         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
531
532         if (item) {
533                 elm_genlist_item_selected_set(item, EINA_FALSE);
534         }
535
536         if (NULL == ugd) {
537                 DBG(LOG_ERROR, "Data is NULL\n");
538                 return;
539         }
540
541         wfd_ug_warn_popup(ugd, D_("IDS_ST_POP_DEVICE_CONNECTED_TO_ANOTHER_DEVICE"), POP_TYPE_BUSY_DEVICE_POPUP);
542
543         __FUNC_EXIT__;
544 }
545
546 void ctxpopup_dismissed_cb(void *data, Evas_Object *obj, void *event_info)
547 {
548         struct ug_data *ugd = (struct ug_data *) data;
549
550         if (!ugd) {
551                 DBG(LOG_ERROR, "The param is NULL\n");
552                 return;
553         }
554
555         if (ugd->ctxpopup) {
556                 evas_object_del(ugd->ctxpopup);
557                 ugd->ctxpopup = NULL;
558         }
559 }
560
561 void _ctxpopup_move()
562 {
563         __FUNC_ENTER__;
564
565         int win_w = 0, win_h = 0;
566         int move_x = 0, move_y = 0;
567         int changed_ang = 0;
568         struct ug_data *ugd = wfd_get_ug_data();
569
570         if (!ugd || !ugd->win) {
571                 DBG(LOG_ERROR, "NULL parameters.\n");
572                 return;
573         }
574
575         if (!ugd->ctxpopup) {
576                 DBG(LOG_INFO, "NULL parameters.\n");
577                 return;
578         }
579
580         elm_win_screen_size_get(ugd->win, NULL, NULL, &win_w, &win_h);
581         changed_ang = elm_win_rotation_get(ugd->win);
582
583         switch (changed_ang) {
584                 case 0:
585                 case 180:
586                         move_x = win_w/2;
587                         move_y = win_h;
588                         break;
589
590                 case 90:
591                         move_x = win_h/2;
592                         move_y = win_w;
593                         break;
594
595                 case 270:
596                         move_x = win_h/2;
597                         move_y = win_w;
598                         break;
599
600                 default:
601                         move_x = 0;
602                         move_y = 0;
603                         break;
604         }
605
606         evas_object_move(ugd->ctxpopup, move_x, move_y);
607
608         __FUNC_EXIT__;
609 }
610
611 void _create_mluti_connect_view(void *data, Evas_Object *obj, void *event_info)
612 {
613         __FUNC_ENTER__;
614         struct ug_data *ugd = (struct ug_data *) data;
615         WFD_RET_IF(ugd == NULL, "The param is NULL\n");
616         WFD_IF_DEL_OBJ(ugd->ctxpopup);
617         int ret = 0;
618
619         wfd_client_free_raw_discovered_peers(ugd);
620         ugd->raw_discovered_peer_cnt = 0;
621         wfd_create_multiconnect_view(ugd);
622         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
623         ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
624         if (ret != WIFI_DIRECT_ERROR_NONE) {
625                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
626                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
627                 wifi_direct_cancel_discovery();
628         }
629
630         __FUNC_EXIT__;
631 }
632
633 void _more_button_cb(void *data, Evas_Object *obj, void *event_info)
634 {
635         __FUNC_ENTER__;
636
637         Evas_Object *naviframe = (Evas_Object *)data;
638         Elm_Object_Item *multi_connect_item = NULL;
639         Elm_Object_Item *rename_item = NULL;
640         struct ug_data *ugd = wfd_get_ug_data();
641
642         if (!naviframe || !ugd) {
643                 DBG(LOG_ERROR, "NULL parameters.\n");
644                 return;
645         }
646
647         ugd->more_btn_multiconnect_item = NULL;
648
649         if (ugd->ctxpopup) {
650                 evas_object_del(ugd->ctxpopup);
651         }
652
653         ugd->ctxpopup = elm_ctxpopup_add(naviframe);
654         elm_object_style_set(ugd->ctxpopup, "more/default");
655         eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_BACK, eext_ctxpopup_back_cb, NULL);
656         eext_object_event_callback_add(ugd->ctxpopup, EEXT_CALLBACK_MORE, eext_ctxpopup_back_cb, NULL);
657         evas_object_smart_callback_add(ugd->ctxpopup, "dismissed", ctxpopup_dismissed_cb, ugd);
658         elm_ctxpopup_auto_hide_disabled_set(ugd->ctxpopup, EINA_TRUE);
659
660         elm_ctxpopup_direction_priority_set(ugd->ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
661                                         ELM_CTXPOPUP_DIRECTION_LEFT,
662                                         ELM_CTXPOPUP_DIRECTION_RIGHT,
663                                         ELM_CTXPOPUP_DIRECTION_DOWN);
664
665         _ctxpopup_move();
666
667         multi_connect_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_WIFI_BUTTON_MULTI_CONNECT", NULL, _create_mluti_connect_view, ugd);
668         elm_object_item_domain_text_translatable_set(multi_connect_item, PACKAGE, EINA_TRUE);
669         ugd->more_btn_multiconnect_item = multi_connect_item;
670
671         wfd_refresh_wifi_direct_state(ugd);
672         if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
673                 WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status ||
674                 WIFI_DIRECT_STATE_DEACTIVATED == ugd->wfd_status ||
675                 ugd->raw_connected_peer_cnt > 0) {
676                 elm_object_item_disabled_set(multi_connect_item, TRUE);
677         }
678
679         rename_item = elm_ctxpopup_item_append(ugd->ctxpopup, "IDS_ST_BODY_RENAME_DEVICE_ABB", NULL, _gl_rename_device_sel, ugd);
680         elm_object_item_domain_text_translatable_set(rename_item, PACKAGE, EINA_TRUE);
681         evas_object_show(ugd->ctxpopup);
682
683         __FUNC_EXIT__;
684 }
685
686 /**
687  *      This function make items into group
688 */
689 void _wfd_realize_item(Elm_Object_Item *pre_item, int count)
690 {
691         __FUNC_ENTER__;
692         int i = 0;
693         if (count < 1 || pre_item == NULL) {
694                 return;
695         }
696
697         Elm_Object_Item *item = elm_genlist_item_next_get(pre_item);
698         if (item == NULL) {
699                 return;
700         }
701
702         if (count == 1) {
703                 elm_object_item_signal_emit(item, "elm,state,normal", "");
704                 return;
705         }
706
707         for (i = 0; i < count; i++) {
708                 if (i == 0) {
709                         elm_object_item_signal_emit(item, "elm,state,top", "");
710                 } else if (i == count - 1) {
711                         elm_object_item_signal_emit(item, "elm,state,bottom", "");
712                 } else {
713                         elm_object_item_signal_emit(item, "elm,state,center", "");
714                 }
715
716                 item = elm_genlist_item_next_get(item);
717         }
718         __FUNC_EXIT__;
719 }
720
721 /**
722  *      This function let the ug call it when unresized event is received
723 */
724 static void _gl_unrealized(void *data, Evas_Object *obj, void *event_info)
725 {
726         __FUNC_ENTER__;
727         struct ug_data *ugd = (struct ug_data *)data;
728
729         _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
730         _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
731         _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
732         _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
733         _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
734         __FUNC_EXIT__;
735 }
736
737 /**
738  *      This function let the ug call it when resized event is received
739  *      @return   void
740  *      @param[in] data the pointer to the main data structure
741  *      @param[in] obj the pointer to the evas object
742  *      @param[in] event_info the pointer to the event information
743  */
744 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
745 {
746         __FUNC_ENTER__;
747
748         if (!data || !event_info) {
749                 DBG(LOG_ERROR, "Invalid parameters");
750                 return;
751         }
752
753         struct ug_data *ugd = (struct ug_data *)data;
754 #ifdef ACCESSIBILITY_FEATURE
755         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
756         int index = elm_genlist_item_index_get(item);
757         char *sr_msg = NULL;
758 #endif
759
760         _wfd_realize_item(ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
761         _wfd_realize_item(ugd->conn_wfd_item, ugd->gl_connected_peer_cnt);
762         _wfd_realize_item(ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
763         _wfd_realize_item(ugd->busy_wfd_item, ugd->gl_busy_peer_cnt);
764         _wfd_realize_item(ugd->conn_failed_wfd_item, ugd->gl_connected_failed_peer_cnt);
765
766 #ifdef ACCESSIBILITY_FEATURE
767         /* screen reader */
768         if (GENLIST_HEADER_POS == index && item != NULL) {
769                 Evas_Object *check = elm_object_item_part_content_get(item, "elm.icon");
770                 if (check) {
771                         Eina_Bool state = elm_check_state_get(check);
772                         if (state) {
773                                 sr_msg = strdup(SR_CHECKBOX_ON_MSG);
774                         } else {
775                                 sr_msg = strdup(SR_CHECKBOX_OFF_MSG);
776                         }
777
778                         if (sr_msg) {
779                                 Evas_Object *ao = NULL;
780                                 ao = elm_object_item_access_object_get(item);
781                                 elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, sr_msg);
782                                 free(sr_msg);
783                         } else {
784                                 DBG(LOG_ERROR, "index = %d, screen reader message create fail!", index);
785                         }
786                 } else {
787                         DBG(LOG_ERROR, "index = %d, get check box fail!", index);
788                 }
789         }
790 #endif
791
792         __FUNC_EXIT__;
793 }
794
795 /**
796  *      This function let the ug call it when click 'disconnect' button
797  *      @return   void
798  *      @param[in] data the pointer to the main data structure
799  *      @param[in] obj the pointer to the evas object
800  *      @param[in] event_info the pointer to the event information
801  */
802 void _wfd_ug_disconnect_button_cb(void *data, Evas_Object * obj, void *event_info)
803 {
804         __FUNC_ENTER__;
805         struct ug_data *ugd = (struct ug_data *)data;
806         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
807
808         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_CURRENT_CONNECTION_WILL_BE_DISCONNECTED_CONTINUE_Q"), POP_TYPE_DISCONNECT);
809
810         __FUNC_EXIT__;
811 }
812
813 /**
814  *      This function let the ug call it when click "cancel connection" button
815  *      @return   void
816  *      @param[in] data the pointer to the main data structure
817  *      @param[in] obj the pointer to the evas object
818  *      @param[in] event_info the pointer to the event information
819  */
820 void _wfd_ug_cancel_connection_button_cb(void *data, Evas_Object * obj, void *event_info)
821 {
822         __FUNC_ENTER__;
823         struct ug_data *ugd = (struct ug_data *)data;
824         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
825
826         wfd_ug_act_popup(ugd, D_("IDS_WIFI_POP_THIS_WI_FI_DIRECT_CONNECTION_WILL_BE_CANCELLED"), POP_TYPE_CANCEL_CONNECT);
827
828         __FUNC_EXIT__;
829 }
830
831
832 /**
833  *      This function let the ug update the genlist item
834  *      @return   void
835  *      @param[in] gl_item the pointer to genlist item
836  */
837 void wfd_ug_view_refresh_glitem(Elm_Object_Item *gl_item)
838 {
839         __FUNC_ENTER__;
840         if (gl_item != NULL) {
841                 elm_genlist_item_update(gl_item);
842         }
843         __FUNC_EXIT__;
844 }
845
846 /**
847  *      This function let the ug refresh the attributes of button
848  *      @return   void
849  *      @param[in] tb_item the pointer to the toolbar button
850  *      @param[in] text the pointer to the text of button
851  *      @param[in] enable whether the button is disabled
852  */
853 void wfd_ug_view_refresh_button(Evas_Object *tb_item, const char *text,
854                 int enable)
855 {
856         __FUNC_ENTER__;
857
858         if (NULL == tb_item || NULL == text) {
859                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
860                 return;
861         }
862
863         DBG(LOG_INFO, "Set the attributes of button: text[%s], enabled[%d]\n", text, enable);
864         elm_object_domain_translatable_part_text_set(tb_item, "default",
865                          PACKAGE, text);
866         elm_object_disabled_set(tb_item, !enable);
867
868         __FUNC_EXIT__;
869 }
870
871 /**
872  *      This function let the ug know whether current device is connected by me
873  *      @return   If connected, return TRUE, else return FALSE
874  *      @param[in] ugd the pointer to the main data structure
875  *      @param[in] dev the pointer to the device
876  */
877 static bool __wfd_is_device_connected_with_me(struct ug_data *ugd, device_type_s *dev)
878 {
879         __FUNC_ENTER__;
880         int i = 0;
881
882         for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
883                 if (strncmp(ugd->raw_connected_peers[i].mac_addr,
884                         dev->mac_addr, strlen(ugd->raw_connected_peers[i].mac_addr)) == 0) {
885                         return TRUE;
886                 }
887         }
888
889         __FUNC_EXIT__;
890         return FALSE;
891 }
892
893 /**
894  *      This function let the ug know whether current device is connected by other peer
895  *      @return   If connected, return TRUE, else return FALSE
896  *      @param[in] ugd the pointer to the main data structure
897  *      @param[in] dev the pointer to the device
898  */
899 static bool __wfd_is_device_busy(struct ug_data *ugd, device_type_s *dev)
900 {
901         __FUNC_ENTER__;
902
903         if (ugd->I_am_group_owner == TRUE) {
904                 if (dev->is_connected || dev->is_group_owner) {
905                         return TRUE;
906                 } else {
907                         return FALSE;
908                 }
909         } else {
910                 if (dev->is_connected == TRUE && dev->is_group_owner == TRUE) {
911                         return FALSE;
912                 }
913
914                 if (dev->is_connected == TRUE && dev->is_group_owner == FALSE) {
915                         return TRUE;
916                 }
917
918                 if (dev->is_connected == FALSE) {
919                         return FALSE;
920                 }
921         }
922
923         __FUNC_EXIT__;
924         return FALSE;
925 }
926
927 /**
928  *      This function let the ug calculate how many devices are avaliable
929  *      @return   TRUE
930  *      @param[in] ugd the pointer to the main data structure
931  *      @param[in] dev the pointer to the number of avaliable devices
932  */
933 static bool __wfd_is_any_device_available(struct ug_data *ugd, int* no_of_available_dev)
934 {
935         __FUNC_ENTER__;
936         GList *iterator = NULL;
937
938         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
939                 /* Not include the device which is connected with me */
940                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
941                         continue;
942                 }
943                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
944                         ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT) {
945                         (*no_of_available_dev)++;
946                 }
947         }
948
949         __FUNC_EXIT__;
950         return TRUE;
951 }
952
953 /**
954  *      This function let the ug calculate how many devices are busy
955  *      @return   TRUE
956  *      @param[in] ugd the pointer to the main data structure
957  *      @param[in] dev the pointer to the number of busy devices
958  */
959 static bool __wfd_is_any_device_busy(struct ug_data *ugd, int* no_of_busy_dev)
960 {
961         __FUNC_ENTER__;
962         GList *iterator = NULL;
963
964         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
965                 /* Not include the device which is connected with me */
966                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
967                         continue;
968                 }
969                 if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data)) {
970                         (*no_of_busy_dev)++;
971                 }
972         }
973
974         __FUNC_EXIT__;
975         return TRUE;
976 }
977
978 /**
979  *      This function let the ug calculate how many devices are connected failed
980  *      @return   TRUE
981  *      @param[in] ugd the pointer to the main data structure
982  *      @param[in] dev the pointer to the number of connected failed devices
983  */
984 static bool __wfd_is_any_device_connect_failed(struct ug_data *ugd, int* no_of_connect_failed_dev)
985 {
986         __FUNC_ENTER__;
987         GList *iterator = NULL;
988
989         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
990                 /* Not include the device which is connected with me */
991                 if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
992                         continue;
993                 }
994                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
995                         ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
996                         (*no_of_connect_failed_dev)++;
997                 }
998         }
999
1000         __FUNC_EXIT__;
1001         return TRUE;
1002 }
1003
1004 /**
1005  *      This function let the ug create the main genlist
1006  *      @return   the main genlist
1007  *      @param[in] data the pointer to the main data structure
1008  */
1009 static Evas_Object *_create_basic_genlist(void *data)
1010 {
1011         __FUNC_ENTER__;
1012         struct ug_data *ugd = (struct ug_data *) data;
1013         Evas_Object *genlist;
1014
1015         genlist = elm_genlist_add(ugd->layout);
1016
1017         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
1018         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
1019                         EVAS_HINT_EXPAND);
1020         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1021
1022         /* Wifi ON/OFF toggle button */
1023 #ifdef WFD_ON_OFF_GENLIST
1024         ugd->item_wifi_onoff = elm_genlist_item_append(genlist, &wfd_onoff_itc, ugd,
1025                         NULL, ELM_GENLIST_ITEM_NONE,_onoff_changed_cb, ugd);
1026         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1027                                         EINA_FALSE);
1028 #endif
1029         evas_object_smart_callback_add(genlist, "realized", _gl_realized, ugd);
1030         evas_object_smart_callback_add(genlist, "unrealized", _gl_unrealized, ugd);
1031         ugd->device_name_item = elm_genlist_item_append(genlist, &device_name_itc, ugd, NULL,
1032                 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1033         if(ugd->device_name_item != NULL)
1034                 elm_genlist_item_select_mode_set(ugd->device_name_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1035
1036         __FUNC_EXIT__;
1037         return genlist;
1038 }
1039
1040 /**
1041  *      This function let the ug create no device item to append the genlist
1042  *      @return   the main item
1043  *      @param[in] data the pointer to the main data structure
1044  */
1045 Evas_Object *_create_no_device_genlist(void *data)
1046 {
1047         __FUNC_ENTER__;
1048         struct ug_data *ugd = (struct ug_data *) data;
1049         Elm_Object_Item *last_item = NULL;
1050         int i = 0;
1051
1052         WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1053
1054         if (ugd->conn_wfd_item != NULL) {
1055                 last_item = ugd->conn_wfd_item;
1056                 for (i = 0; i < ugd->gl_connected_peer_cnt; i++) {
1057                         last_item = elm_genlist_item_next_get(last_item);
1058                 }
1059         } else {
1060                 last_item = ugd->device_name_item;
1061         }
1062
1063         ugd->nodevice_title_item = elm_genlist_item_insert_after(ugd->genlist,
1064                 &title_no_device_itc, (void *)ugd, NULL, last_item,
1065                 ELM_GENLIST_ITEM_NONE, NULL, NULL);
1066         if(ugd->nodevice_title_item != NULL)
1067                 elm_genlist_item_select_mode_set(ugd->nodevice_title_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1068
1069         ugd->nodevice_item = elm_genlist_item_insert_after(ugd->genlist, &noitem_itc, (void *)ugd, NULL,
1070                 ugd->nodevice_title_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1071         if(ugd->nodevice_item != NULL)
1072                 elm_genlist_item_select_mode_set(ugd->nodevice_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1073
1074         __FUNC_EXIT__;
1075         return ugd->genlist;
1076 }
1077
1078 /**
1079  *      This function let the ug create busy device list
1080  *      @return   0
1081  *      @param[in] data the pointer to the main data structure
1082  */
1083 int _create_busy_dev_list(void *data)
1084 {
1085         __FUNC_ENTER__;
1086         struct ug_data *ugd = (struct ug_data *) data;
1087
1088         ugd->busy_wfd_item = elm_genlist_item_append(ugd->genlist, &title_busy_itc, (void *)ugd,
1089                 NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1090         if(ugd->busy_wfd_item != NULL)
1091                 elm_genlist_item_select_mode_set(ugd->busy_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1092         __FUNC_EXIT__;
1093         return 0;
1094 }
1095
1096 void wfd_free_nodivice_item(struct ug_data *ugd)
1097 {
1098         __FUNC_ENTER__;
1099         WFD_IF_DEL_ITEM(ugd->nodevice_title_item);
1100         WFD_IF_DEL_ITEM(ugd->nodevice_item);
1101         __FUNC_EXIT__;
1102 }
1103
1104 /**
1105  *      This function let the ug create avaliable device list
1106  *      @return   0
1107  *      @param[in] data the pointer to the main data structure
1108  */
1109 int _create_available_dev_genlist(void *data)
1110 {
1111         __FUNC_ENTER__;
1112         int i = 0;
1113         struct ug_data *ugd = (struct ug_data *) data;
1114         Elm_Object_Item *last_item = NULL;
1115
1116         wfd_free_nodivice_item(ugd);
1117
1118         if (ugd->conn_wfd_item != NULL) {
1119                 last_item = ugd->conn_wfd_item;
1120                 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1121                         last_item = elm_genlist_item_next_get(last_item);
1122                 }
1123         } else {
1124                 last_item = ugd->device_name_item;
1125         }
1126
1127         ugd->avlbl_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_available_itc, (void *)ugd, NULL,
1128                 last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1129         if(ugd->avlbl_wfd_item != NULL) {
1130                 elm_genlist_item_select_mode_set(ugd->avlbl_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1131                 elm_genlist_item_update(ugd->avlbl_wfd_item);
1132         }
1133         __FUNC_EXIT__;
1134         return 0;
1135 }
1136
1137 /**
1138  *      This function let the ug create multi connect device list
1139  *      @return   0
1140  *      @param[in] data the pointer to the main data structure
1141  */
1142 static int _create_multi_connect_dev_genlist(void *data)
1143 {
1144         __FUNC_ENTER__;
1145         struct ug_data *ugd = (struct ug_data *) data;
1146
1147         ugd->multi_connect_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_multi_connect_itc, (void *)ugd,
1148                                                                 NULL, ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1149         if(ugd->multi_connect_wfd_item != NULL)
1150                 elm_genlist_item_select_mode_set(ugd->multi_connect_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1151         __FUNC_EXIT__;
1152         return 0;
1153 }
1154
1155 /**
1156  *      This function let the ug create connected device list
1157  *      @return   0
1158  *      @param[in] data the pointer to the main data structure
1159  */
1160 int _create_connected_dev_genlist(void *data)
1161 {
1162         __FUNC_ENTER__;
1163         struct ug_data *ugd = (struct ug_data *) data;
1164
1165         ugd->conn_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_itc, (void *)ugd, NULL,
1166                 ugd->device_name_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1167         if(ugd->conn_wfd_item != NULL) {
1168                 elm_genlist_item_select_mode_set(ugd->conn_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1169                 elm_genlist_item_update(ugd->conn_wfd_item);
1170         }
1171
1172         __FUNC_EXIT__;
1173         return 0;
1174 }
1175
1176 /**
1177  *      This function let the ug create connected falied device list
1178  *      @return   0
1179  *      @param[in] data the pointer to the main data structure
1180  */
1181 int _create_connected_failed_dev_genlist(void *data)
1182 {
1183         __FUNC_ENTER__;
1184         struct ug_data *ugd = (struct ug_data *) data;
1185         Elm_Object_Item *last_item = NULL;
1186         int i = 0;
1187
1188         if (ugd->avlbl_wfd_item != NULL) {
1189                 last_item = ugd->avlbl_wfd_item;
1190                 for (i=0; i<ugd->gl_available_peer_cnt; i++) {
1191                         last_item = elm_genlist_item_next_get(last_item);
1192                 }
1193         } else if (ugd->conn_wfd_item != NULL) {
1194                 last_item = ugd->conn_wfd_item;
1195                 for (i=0; i<ugd->gl_connected_peer_cnt; i++) {
1196                         last_item = elm_genlist_item_next_get(last_item);
1197                 }
1198         } else {
1199                 last_item = ugd->device_name_item;
1200         }
1201
1202         ugd->conn_failed_wfd_item = elm_genlist_item_insert_after(ugd->genlist, &title_conn_failed_itc, (void *)ugd,
1203                                                                 NULL, last_item, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1204         if(ugd->conn_failed_wfd_item != NULL)
1205                 elm_genlist_item_select_mode_set(ugd->conn_failed_wfd_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1206         __FUNC_EXIT__;
1207         return 0;
1208 }
1209
1210 /**
1211  *      This function let the ug make the display callback for connect failed peers
1212  *      @return   if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
1213  *      @param[in] data the pointer to the user data
1214  */
1215 static Eina_Bool _connect_failed_peers_display_cb(void *user_data)
1216 {
1217         __FUNC_ENTER__;
1218         int interval = 0;
1219         int res = -1;
1220         struct ug_data *ugd = (struct ug_data *) user_data;
1221
1222         if (NULL == ugd) {
1223                 DBG(LOG_ERROR, "NULL parameters.\n");
1224                 return ECORE_CALLBACK_CANCEL;
1225         }
1226
1227         if (ugd->avlbl_wfd_item == NULL) {
1228                 _create_available_dev_genlist(ugd);
1229         }
1230
1231         if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1232                 DBG(LOG_INFO, "Background mode\n");
1233                 ugd->display_timer = NULL;
1234                 return ECORE_CALLBACK_CANCEL;
1235         }
1236
1237         /* check the timeout, if not timeout, keep the cb */
1238         interval = time(NULL) - ugd->last_display_time;
1239         if (interval < MAX_DISPLAY_TIME_OUT) {
1240                 return ECORE_CALLBACK_RENEW;
1241         }
1242
1243         if (ugd->is_paused == false) {
1244                 DBG(LOG_INFO, "Not Paused");
1245                 /* start discovery again */
1246                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1247                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1248                 if (res != WIFI_DIRECT_ERROR_NONE) {
1249                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1250                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1251                         wifi_direct_cancel_discovery();
1252                 }
1253         }
1254
1255         ugd->display_timer = NULL;
1256         __FUNC_EXIT__;
1257         return ECORE_CALLBACK_CANCEL;
1258 }
1259
1260 void wfd_ug_view_free_peer(device_type_s *gl_peers_start)
1261 {
1262         __FUNC_ENTER__;
1263         device_type_s *peer_for_free = NULL;
1264         device_type_s *peer = gl_peers_start;
1265
1266         while (peer != NULL && peer->gl_item != NULL) {
1267                 DBG(LOG_INFO, "Deleted item, ssid:%s\n", peer->ssid);
1268                 elm_object_item_del(peer->gl_item);
1269                 peer->gl_item = NULL;
1270                 peer_for_free = peer;
1271                 peer = peer->next;
1272                 free(peer_for_free);
1273         }
1274         __FUNC_EXIT__;
1275 }
1276
1277 void wfd_check_gl_conn_peers(struct ug_data *ugd)
1278 {
1279         __FUNC_ENTER__;
1280         if (ugd->gl_connected_peer_cnt == 0) {
1281                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1282         }
1283         __FUNC_EXIT__;
1284 }
1285
1286 /**
1287  *      This function let the ug free the peers
1288  *      @return   void
1289  *      @param[in] data the pointer to the main data structure
1290  */
1291 void wfd_ug_view_free_peers(void *data)
1292 {
1293         __FUNC_ENTER__;
1294
1295         struct ug_data *ugd = (struct ug_data *) data;
1296
1297         ugd->gl_connected_peer_cnt = 0;
1298
1299         if (ugd->gl_conn_peers_start != NULL) {
1300                 wfd_ug_view_free_peer(ugd->gl_conn_peers_start);
1301                 ugd->gl_conn_peers_start = NULL;
1302         }
1303
1304         ugd->gl_available_peer_cnt = 0;
1305
1306         if (ugd->gl_avlb_peers_start != NULL) {
1307                 wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1308                 ugd->gl_avlb_peers_start = NULL;
1309         }
1310
1311         ugd->gl_busy_peer_cnt = 0;
1312
1313         if (ugd->gl_busy_peers_start != NULL) {
1314                 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1315                 ugd->gl_busy_peers_start = NULL;
1316         }
1317
1318         ugd->gl_multi_connect_peer_cnt = 0;
1319
1320         if (ugd->gl_mul_conn_peers_start != NULL) {
1321                 wfd_ug_view_free_peer(ugd->gl_mul_conn_peers_start);
1322                 ugd->gl_mul_conn_peers_start = NULL;
1323         }
1324
1325         if (ugd->gl_connected_peer_cnt == 0) {
1326                 WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
1327         }
1328
1329         if (ugd->display_timer != NULL) {
1330                 ecore_timer_del(ugd->display_timer);
1331                 ugd->display_timer = NULL;
1332         }
1333
1334         WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1335         WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1336         WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1337         WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1338
1339         __FUNC_EXIT__;
1340 }
1341
1342 void wfd_ug_update_toolbar(struct ug_data *ugd)
1343 {
1344         __FUNC_ENTER__;
1345         int no_of_conn_dev = ugd->raw_connected_peer_cnt;
1346         Evas_Object *btn;
1347
1348         wfd_refresh_wifi_direct_state(ugd);
1349         if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1350                 DBG(LOG_INFO, "WIFI_DIRECT_STATE_CONNECTING\n");
1351                 if( ugd->multi_connect_wfd_item != NULL) {
1352                         DBG(LOG_INFO, "multi_connect_toolbar_item\n");
1353                         btn = elm_button_add(ugd->button_layout);
1354                         /* Use "bottom" style button */
1355                         elm_object_style_set(btn, "bottom");
1356                         elm_object_domain_translatable_text_set(btn, PACKAGE,
1357                                         "IDS_WIFI_SK2_CANCEL_CONNECTION");
1358                         evas_object_smart_callback_add(btn, "clicked",
1359                                         _wfd_ug_cancel_connection_button_cb, (void *)ugd);
1360                         /* Set button into "toolbar" swallow part */
1361                         elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1362                         ugd->disconnect_btn = btn;
1363                         evas_object_show(ugd->disconnect_btn);
1364                         elm_object_part_content_set(ugd->button_layout, "button.prev",
1365                                 ugd->scan_toolbar);
1366                         wfd_ug_view_refresh_button(ugd->scan_toolbar,
1367                                         "IDS_WIFI_SK4_SCAN", FALSE);
1368                         evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1369                         DBG(LOG_INFO, "button: disconnect button added\n");
1370                 } else {
1371                         DBG(LOG_INFO, "scan_toolbar\n");
1372                         WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
1373                         wfd_ug_view_refresh_button(ugd->scan_toolbar,
1374                                         "IDS_WIFI_SK2_CANCEL_CONNECTION", TRUE);
1375                         evas_object_data_set(ugd->scan_btn, "multi", "cancel");
1376                         DBG(LOG_INFO, "button: stop connect button added\n");
1377                 }
1378         } else if (no_of_conn_dev > 0) {
1379                 if (!ugd->multi_connect_toolbar_item) {
1380                         btn = elm_button_add(ugd->button_layout);
1381                         /* Use "bottom" style button */
1382                         elm_object_style_set(btn, "bottom");
1383                         elm_object_domain_translatable_text_set(btn, PACKAGE,
1384                                         "IDS_WIFI_SK_DISCONNECT");
1385                         evas_object_smart_callback_add(btn, "clicked",
1386                                         _wfd_ug_disconnect_button_cb, (void *)ugd);
1387                         /* Set button into "toolbar" swallow part */
1388                         elm_object_part_content_set(ugd->button_layout, "button.next", btn);
1389                         ugd->disconnect_btn = btn;
1390                         evas_object_show(ugd->disconnect_btn);
1391                 }
1392                 elm_object_part_content_set(ugd->button_layout, "button.prev",
1393                                 ugd->scan_toolbar);
1394                 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1395                                 "IDS_WIFI_SK4_SCAN", TRUE);
1396                 evas_object_data_set(ugd->disconnect_btn, "multi", "disconnect");
1397                 DBG(LOG_INFO, "button: disconnect button added\n");
1398         } else {
1399                 if (no_of_conn_dev == 0 && ugd->disconnect_btn != NULL) {
1400                         DBG(LOG_INFO, "disconnect btn removed when conn failed\n");
1401                         Evas_Object *content;
1402                         content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1403                         WFD_IF_DEL_OBJ(content);
1404                         ugd->disconnect_btn = NULL;
1405                         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1406                 }
1407                 wfd_ug_view_refresh_button(ugd->scan_toolbar,
1408                         "IDS_WIFI_SK4_SCAN", TRUE);
1409                 evas_object_data_set(ugd->scan_toolbar, "multi", "connect");
1410                 DBG(LOG_INFO, "button: scan button added\n");
1411         }
1412         __FUNC_EXIT__;
1413 }
1414
1415 /**
1416  *      This function let the ug init the genlist
1417  */
1418 void wfd_ug_view_init_genlist(void *data, bool is_free_all_peers)
1419 {
1420         __FUNC_ENTER__;
1421         struct ug_data *ugd = (struct ug_data *) data;
1422         int no_of_busy_dev = 0;
1423         int no_of_available_dev = 0;
1424         int no_of_conn_failed_dev = 0;
1425
1426         if (is_free_all_peers) {
1427                 wfd_ug_view_free_peers(ugd);
1428         }
1429
1430         if (ugd->gl_failed_peers_start != NULL) {
1431                 DBG(LOG_INFO, "These are failed peers, must clear them");
1432                 ugd->gl_connected_failed_peer_cnt = 0;
1433                 wfd_ug_view_free_peer(ugd->gl_failed_peers_start);
1434                 ugd->gl_failed_peers_start = NULL;
1435                 WFD_IF_DEL_ITEM(ugd->conn_failed_wfd_item);
1436         }
1437
1438         if (ugd->avlbl_wfd_item != NULL) {
1439                 DBG(LOG_INFO, "There are available peers in genlist");
1440                 wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
1441                 return;
1442         }
1443
1444         __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1445         __wfd_is_any_device_available(ugd, &no_of_available_dev);
1446         __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1447
1448         __FUNC_EXIT__;
1449 }
1450
1451 /**
1452  *      This function let the ug find a peer in genlist
1453  */
1454 device_type_s *find_peer_in_glist(device_type_s *start_pos, const char *mac_addr)
1455 {
1456         __FUNC_ENTER__;
1457
1458         if (start_pos == NULL) {
1459                 DBG(LOG_INFO, "no peer in genlist");
1460                 return NULL;
1461         }
1462
1463         device_type_s *peer = start_pos;
1464
1465         while (peer != NULL) {
1466                 if (!strncmp(peer->mac_addr, mac_addr, MAC_LENGTH - 1)) {
1467                         peer->is_alive = true;
1468                         DBG(LOG_INFO, "device [%s] found in genlist", peer->ssid);
1469                         __FUNC_EXIT__;
1470                         return peer;
1471                 }
1472                 peer = peer->next;
1473         }
1474
1475         __FUNC_EXIT__;
1476         return NULL;
1477 }
1478
1479 void delete_not_alive_peers(struct ug_data *ugd, device_type_s **start_pos, int *cnt)
1480 {
1481         __FUNC_ENTER__;
1482         if (*start_pos == NULL) {
1483                 DBG(LOG_INFO, "no peer in genlist");
1484                 return;
1485         }
1486
1487         device_type_s *peer = *start_pos;
1488         device_type_s *peer_tmp = NULL;
1489         while (peer != NULL) {
1490                 peer_tmp = peer->next;
1491                 if(peer->is_alive == false) {
1492                          free_gl_peer(start_pos, peer->mac_addr, cnt);
1493                 }
1494                 peer = peer_tmp;
1495         }
1496
1497 //      wfd_check_gl_available_peers(ugd);
1498         if (ugd->gl_busy_peer_cnt == 0) {
1499                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1500         }
1501         __FUNC_EXIT__;
1502         return;
1503 }
1504
1505 void set_not_alive_peers(device_type_s *start_pos)
1506 {
1507         __FUNC_ENTER__;
1508         if (start_pos == NULL) {
1509                 DBG(LOG_INFO, "no peer in genlist");
1510                 return;
1511         }
1512
1513         device_type_s *peer = start_pos;
1514         while (peer != NULL) {
1515                 peer->is_alive = false;
1516                 peer = peer->next;
1517         }
1518
1519         __FUNC_EXIT__;
1520         return;
1521 }
1522
1523 /**
1524  *      This function let the ug get the insert position for next item
1525  */
1526 Elm_Object_Item *get_insert_postion(device_type_s *peer, Elm_Object_Item *pre_item, int peer_cnt)
1527 {
1528         __FUNC_ENTER__;
1529         int i = 0;
1530         device_type_s *peer_ite = NULL;
1531         Elm_Object_Item *head = elm_genlist_item_next_get(pre_item);
1532         Elm_Object_Item *item = NULL;
1533
1534         if(peer_cnt == 0) {
1535                 DBG(LOG_INFO, "first peer [%s] would be added", peer->ssid);
1536                 return pre_item;
1537         }
1538
1539         peer_ite = (device_type_s *)elm_object_item_data_get(head);
1540         if(peer_ite->gl_item != NULL) {
1541                 for(i=0; i < peer_cnt; i++) {
1542                         if (strcasecmp(peer_ite->ssid, peer->ssid) > 0) {
1543                                 /* if peer_ite is greater than peer, return previous item */
1544                                 __FUNC_EXIT__;
1545                                 return  elm_genlist_item_prev_get(head);
1546                         } else {
1547                                 item = elm_genlist_item_next_get(head);
1548                                 if (item == NULL) {
1549                                         /* return the last item */
1550                                         return head;
1551                                 } else {
1552                                         head = item;
1553                                         peer_ite = (device_type_s *)elm_object_item_data_get(head);
1554                                 }
1555                         }
1556                 }
1557         }
1558         __FUNC_EXIT__;
1559         return elm_genlist_item_prev_get(head);
1560 }
1561
1562 /**
1563  *      This function let the ug insert peer item to genlist
1564  */
1565 int insert_gl_item(Evas_Object *genlist, Elm_Object_Item *item, Elm_Gen_Item_Class *itc, device_type_s **start_pos,
1566                                 device_type_s *peer_for_insert, void *callback)
1567 {
1568         __FUNC_ENTER__;
1569         WFD_RETV_IF(item == NULL, -1, "Item is NULL\n");
1570         device_type_s *peer = NULL;
1571         device_type_s *peer_ite = NULL;
1572
1573         peer = (device_type_s *)malloc(sizeof(device_type_s));
1574         WFD_RETV_IF(peer == NULL, -1, "malloc failed\n");
1575
1576         memcpy(peer, peer_for_insert, sizeof(device_type_s));
1577         peer->next = NULL;
1578
1579         if(*start_pos == NULL) {
1580                 *start_pos = peer;
1581         } else {
1582                 peer_ite = *start_pos;
1583                 while(peer_ite->next != NULL) {
1584                         /* move pointer to the last peer */
1585                         peer_ite = peer_ite->next;
1586                 }
1587                 peer_ite->next = peer;
1588         }
1589
1590         peer->is_alive = true;
1591         peer->gl_item = elm_genlist_item_insert_after(genlist, itc, (void *)peer, NULL, item,
1592                 ELM_GENLIST_ITEM_NONE, callback, (void *)peer);
1593         if (callback == NULL && peer->gl_item != NULL) {
1594                 elm_genlist_item_select_mode_set(peer->gl_item, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1595         }
1596         __FUNC_EXIT__;
1597         return 0;
1598 }
1599
1600 /**
1601  *      This function let the ug update connected peers
1602  *      @return   void
1603  *      @param[in] data the pointer to the main data structure
1604  */
1605 void wfd_ug_update_connected_peers(void *data)
1606 {
1607         __FUNC_ENTER__;
1608
1609         struct ug_data *ugd = (struct ug_data *) data;
1610         int i = 0 ;
1611         int res;
1612         bool is_group_owner = FALSE;
1613         Elm_Object_Item *item = NULL;
1614
1615         res = wifi_direct_is_group_owner(&is_group_owner);
1616         if (res == WIFI_DIRECT_ERROR_NONE) {
1617                 DBG(LOG_INFO, "is_group_owner=[%d]", is_group_owner);
1618         }
1619
1620         if (!ugd->conn_wfd_item) {
1621                 _create_connected_dev_genlist(ugd);
1622         }
1623
1624         for (i = 0; i < ugd->raw_connected_peer_cnt; i++) {
1625                 if (find_peer_in_glist(ugd->gl_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) == NULL) {
1626                         if (find_peer_in_glist(ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1627                                 free_gl_peer(&ugd->gl_avlb_peers_start, ugd->raw_connected_peers[i].mac_addr,
1628                                         &ugd->gl_available_peer_cnt);
1629                                 wfd_check_gl_available_peers(ugd);
1630                         }
1631
1632                         if (find_peer_in_glist(ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr) != NULL) {
1633                                 free_gl_peer(&ugd->gl_mul_conn_peers_start, ugd->raw_connected_peers[i].mac_addr,
1634                                         &ugd->gl_multi_connect_peer_cnt);
1635                                 if (ugd->gl_multi_connect_peer_cnt == 0) {
1636                                         WFD_IF_DEL_ITEM(ugd->multi_connect_wfd_item);
1637                                         WFD_IF_DEL_ITEM(ugd->multi_connect_sep_item);
1638                                 }
1639                         }
1640
1641                         item = get_insert_postion(&(ugd->raw_connected_peers[i]), ugd->conn_wfd_item,
1642                                 ugd->gl_connected_peer_cnt);
1643                         res = insert_gl_item(ugd->genlist, item, &peer_conn_itc, &ugd->gl_conn_peers_start,
1644                                         &ugd->raw_connected_peers[i], NULL);
1645                         if (res != 0) {
1646                                 break;
1647                         }
1648                         ugd->gl_connected_peer_cnt++;
1649                 }
1650         }
1651
1652         /* if is not GO, free all available peers */
1653         if (is_group_owner == FALSE) {
1654                 ugd->gl_available_peer_cnt = 0;
1655                 WFD_IF_DEL_ITEM(ugd->avlbl_wfd_item);
1656
1657                 if (ugd->gl_avlb_peers_start != NULL) {
1658                         wfd_ug_view_free_peer(ugd->gl_avlb_peers_start);
1659                         ugd->gl_avlb_peers_start = NULL;
1660                 }
1661         }
1662
1663         /* free busy peers */
1664         if (ugd->gl_busy_peers_start != NULL) {
1665                 ugd->gl_busy_peer_cnt = 0;
1666                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1667
1668                 wfd_ug_view_free_peer(ugd->gl_busy_peers_start);
1669                 ugd->gl_busy_peers_start = NULL;
1670
1671         }
1672
1673         __FUNC_EXIT__;
1674 }
1675
1676 /**
1677  *      This function let the ug update the multi-connect peers
1678  *      @return   void
1679  *      @param[in] data the pointer to the main data structure
1680  */
1681 void wfd_ug_view_update_multiconn_peers(void *data)
1682 {
1683         __FUNC_ENTER__;
1684
1685         struct ug_data *ugd = (struct ug_data *) data;
1686         int i;
1687         int res;
1688         Elm_Object_Item *item = NULL;
1689
1690         if (ugd->raw_multi_selected_peer_cnt > 0) {
1691                 if (ugd->raw_connected_peer_cnt < ugd->raw_multi_selected_peer_cnt &&
1692                         ugd->multi_connect_wfd_item == NULL) {
1693                         _create_multi_connect_dev_genlist(ugd);
1694                 }
1695
1696                 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
1697                         if (ugd->raw_multi_selected_peers[i].conn_status != PEER_CONN_STATUS_CONNECTED) {
1698                                 item = get_insert_postion(&(ugd->raw_multi_selected_peers[i]),
1699                                         ugd->multi_connect_wfd_item, ugd->gl_multi_connect_peer_cnt);
1700                                 res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_mul_conn_peers_start,
1701                                                 &ugd->raw_multi_selected_peers[i], NULL);
1702                                 if (res != 0) {
1703                                         break;
1704                                 }
1705                                 ugd->gl_multi_connect_peer_cnt++;
1706                         }
1707                 }
1708         }
1709
1710         __FUNC_EXIT__;
1711 }
1712
1713 /**
1714  *      This function let the ug update the available and busy peers
1715  */
1716 void wfd_ug_update_available_peers(void *data)
1717 {
1718         __FUNC_ENTER__;
1719
1720         struct ug_data *ugd = (struct ug_data *) data;
1721         int no_of_busy_dev = 0;
1722         int no_of_available_dev = 0;
1723         int no_of_conn_dev = 0;
1724         bool is_group_owner = FALSE;
1725         int res = 0;
1726         Elm_Object_Item *item = NULL;
1727         device_type_s *peer = NULL;
1728         GList *iterator = NULL;
1729
1730         __wfd_is_any_device_busy(ugd, &no_of_busy_dev);
1731         __wfd_is_any_device_available(ugd, &no_of_available_dev);
1732         no_of_conn_dev = ugd->raw_connected_peer_cnt;
1733
1734         res = wifi_direct_is_group_owner(&is_group_owner);
1735         if (res != WIFI_DIRECT_ERROR_NONE) {
1736                 DBG(LOG_INFO, "Fail to get group_owner_state. ret=[%d]", res);
1737                 ugd->I_am_group_owner = FALSE;
1738         } else {
1739                 ugd->I_am_group_owner = is_group_owner;
1740         }
1741
1742         DBG(LOG_INFO, "avail_dev=[%d], busy_dev=[%d], GO=[%d]\n", no_of_available_dev, no_of_busy_dev, is_group_owner);
1743         if (no_of_available_dev != 0 || no_of_busy_dev != 0) {
1744                 DBG(LOG_INFO, "There are available or busy peers\n");
1745                 wfd_free_nodivice_item(ugd);
1746         }
1747
1748         if (no_of_conn_dev == 0 || is_group_owner == TRUE) {
1749                 if (ugd->avlbl_wfd_item == NULL) {
1750                         _create_available_dev_genlist(ugd);
1751                 }
1752
1753                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1754                         /* Not include the device which is connected with me */
1755                         if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1756                                 continue;
1757                         }
1758                         if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1759                                 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_FAILED_TO_CONNECT &&
1760                                 ((device_type_s *)iterator->data)->conn_status != PEER_CONN_STATUS_CONNECTED) {
1761                                 /* free disconnected gl peer */
1762                                 if (find_peer_in_glist(ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1763                                         free_gl_peer(&ugd->gl_conn_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1764                                                 &ugd->gl_connected_peer_cnt);
1765                                 }
1766
1767                                 /* free busy gl peer, which is available now */
1768                                 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1769                                         free_gl_peer(&ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr, &ugd->gl_busy_peer_cnt);
1770                                         if (ugd->gl_busy_peer_cnt == 0) {
1771                                                 WFD_IF_DEL_ITEM(ugd->busy_wfd_item);
1772                                         }
1773                                 }
1774
1775                                 if (find_peer_in_glist(ugd->gl_failed_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr) != NULL) {
1776                                         continue;
1777                                 }
1778
1779                                 peer = find_peer_in_glist(ugd->gl_avlb_peers_start, (const char *)((device_type_s *)iterator->data)->mac_addr);
1780                                 if (peer == NULL) {
1781                                         item = get_insert_postion((device_type_s *)iterator->data,
1782                                                 ugd->avlbl_wfd_item, ugd->gl_available_peer_cnt);
1783                                         res = insert_gl_item(ugd->genlist, item, &peer_itc, &ugd->gl_avlb_peers_start,
1784                                                         (device_type_s *)iterator->data, _gl_peer_sel);
1785                                         if (res != 0) {
1786                                                 break;
1787                                         }
1788                                         ugd->gl_available_peer_cnt++;
1789                                 } else if (no_of_conn_dev > 0 && ((device_type_s *)iterator->data)->is_group_owner == TRUE) {
1790                                         /* if peer is GO, free it */
1791                                         free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1792                                                 &ugd->gl_available_peer_cnt);
1793                                 }
1794                         }
1795                 }
1796         }
1797
1798         wfd_check_gl_available_peers(ugd);
1799         wfd_check_gl_conn_peers(ugd);
1800
1801         if (no_of_conn_dev == 0 && no_of_busy_dev > 0) {
1802                 if (ugd->busy_wfd_item == NULL) {
1803                         _create_busy_dev_list(ugd);
1804                 }
1805
1806                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1807                         /* Not include the device which is connected with me */
1808                         if (__wfd_is_device_connected_with_me(ugd, (device_type_s *)iterator->data)) {
1809                                 continue;
1810                         }
1811                         if (__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) == TRUE) {
1812                                 if (find_peer_in_glist(ugd->gl_busy_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1813                                         if (find_peer_in_glist(ugd->gl_avlb_peers_start,
1814                                                 ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1815                                                 free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1816                                                         &ugd->gl_available_peer_cnt);
1817                                                 wfd_check_gl_available_peers(ugd);
1818                                         }
1819                                         item = get_insert_postion((device_type_s *)iterator->data, ugd->busy_wfd_item,
1820                                                 ugd->gl_busy_peer_cnt);
1821                                         res = insert_gl_item(ugd->genlist, item, &peer_busy_itc, &ugd->gl_busy_peers_start,
1822                                                         (device_type_s *)iterator->data, _gl_busy_peer_sel);
1823                                         if (res != 0) {
1824                                                 break;
1825                                         }
1826                                         ugd->gl_busy_peer_cnt++;
1827                                 }
1828                         }
1829                 }
1830         }
1831
1832         wfd_check_gl_busy_peers(ugd);
1833
1834         __FUNC_EXIT__;
1835 }
1836
1837 /**
1838  *      This function let the ug update the failed peers
1839  *      @return   void
1840  *      @param[in] data the pointer to the main data structure
1841  */
1842 void wfd_ug_update_failed_peers(void *data)
1843 {
1844         __FUNC_ENTER__;
1845         struct ug_data *ugd = (struct ug_data *) data;
1846         int no_of_conn_failed_dev = 0;
1847         GList *iterator = NULL;
1848
1849         __wfd_is_any_device_connect_failed(ugd, &no_of_conn_failed_dev);
1850         DBG(LOG_INFO, "conn_failed_dev=[%d]", no_of_conn_failed_dev);
1851
1852         if (no_of_conn_failed_dev == 0) {
1853                 return;
1854         }
1855
1856         /* add timer for disappearing failed peers after N secs */
1857         if (NULL == ugd->display_timer) {
1858                 ugd->last_display_time = time(NULL);
1859                 ugd->display_timer = ecore_timer_add(0.05, (Ecore_Task_Cb)_connect_failed_peers_display_cb, ugd);
1860         }
1861
1862         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
1863                 if (!__wfd_is_device_busy(ugd, (device_type_s *)iterator->data) &&
1864                         ((device_type_s *)iterator->data)->conn_status == PEER_CONN_STATUS_FAILED_TO_CONNECT) {
1865                         if (find_peer_in_glist(ugd->gl_failed_peers_start, ((device_type_s *)iterator->data)->mac_addr) == NULL) {
1866                                 if (find_peer_in_glist(ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr) != NULL) {
1867                                         free_gl_peer(&ugd->gl_avlb_peers_start, ((device_type_s *)iterator->data)->mac_addr,
1868                                                 &ugd->gl_available_peer_cnt);
1869                                         wfd_check_gl_available_peers(ugd);
1870                                 }
1871                         }
1872                 }
1873         }
1874
1875         __FUNC_EXIT__;
1876 }
1877
1878 #ifdef WFD_ON_OFF_GENLIST
1879 /**
1880  *      This function is called when user swipes on/off button
1881  *      @return   void
1882  *      @param[in] data the pointer to the main data structure
1883  *      @param[in] obj the pointer to the evas object
1884  *      @param[in] event_info the pointer to the event information
1885  */
1886 void _onoff_changed_cb(void *data, Evas_Object *obj, void *event_info)
1887 {
1888         __FUNC_ENTER__;
1889         struct ug_data *ugd = (struct ug_data *)data;
1890         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1891         WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1892         wfd_refresh_wifi_direct_state(ugd);
1893         if(ugd->device_name_item != NULL)
1894                 elm_genlist_item_update(ugd->device_name_item);
1895
1896         elm_object_disabled_set(ugd->on_off_check, TRUE);
1897         if(ugd->disconnect_btn) {
1898                 Evas_Object *content;
1899                 content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1900                 WFD_IF_DEL_OBJ(content);
1901                 ugd->disconnect_btn = NULL;
1902         }
1903         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
1904
1905         /* turn on/off wfd */
1906         if (!ugd->wfd_onoff) {
1907                 if (ugd->wfd_status <= WIFI_DIRECT_STATE_DEACTIVATING) {
1908                         DBG(LOG_INFO, "wifi-direct switch on\n");
1909                         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1910                                                                 EINA_FALSE);
1911                         wfd_client_switch_on(ugd);
1912                 }
1913         } else {
1914                 if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATING) {
1915                         DBG(LOG_INFO, "wifi-direct switch off\n");
1916                         elm_genlist_item_selected_set(ugd->item_wifi_onoff,
1917                                                                 EINA_FALSE);
1918                         wfd_client_switch_off(ugd);
1919                 }
1920         }
1921
1922         __FUNC_EXIT__;
1923 }
1924
1925 void wfd_ug_refresh_on_off_check(struct ug_data *ugd)
1926 {
1927         __FUNC_ENTER__;
1928         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1929         WFD_RET_IF(ugd->on_off_check == NULL, "on_off_check(NULL)\n");
1930
1931         wfd_refresh_wifi_direct_state(ugd);
1932         if (ugd->wfd_status == WIFI_DIRECT_STATE_DEACTIVATING ||
1933                 ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATING ) {
1934                 elm_object_disabled_set(ugd->on_off_check, TRUE);
1935         } else {
1936                 elm_object_disabled_set(ugd->on_off_check, FALSE);
1937         }
1938         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1939                 elm_check_state_set(ugd->on_off_check, TRUE);
1940         } else {
1941                 elm_check_state_set(ugd->on_off_check, FALSE);
1942         }
1943
1944         __FUNC_EXIT__;
1945 }
1946
1947 void wfd_ug_create_on_off_check(struct ug_data *ugd)
1948 {
1949         __FUNC_ENTER__;
1950         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1951         WFD_RET_IF(ugd->naviframe == NULL, "naviframe NULL\n");
1952
1953         Evas_Object *check = elm_check_add(ugd->naviframe);
1954         elm_object_style_set(check, "naviframe/title_on&off");
1955         elm_check_state_set(check, ugd->wfd_onoff);
1956         evas_object_propagate_events_set(check, EINA_FALSE);
1957         evas_object_smart_callback_add(check, "changed", _onoff_changed_cb, ugd);
1958         elm_object_focus_allow_set(check, EINA_TRUE);
1959         elm_object_item_part_content_set(ugd->navi_item, "title_right_btn", check);
1960         evas_object_show(check);
1961         ugd->on_off_check = check;
1962
1963         __FUNC_EXIT__;
1964 }
1965 #endif
1966
1967 /**
1968  *      This function let the ug create the main view
1969  *      @return   void
1970  *      @param[in] data the pointer to the main data structure
1971  */
1972 void create_wfd_ug_view(void *data)
1973 {
1974         __FUNC_ENTER__;
1975         struct ug_data *ugd = (struct ug_data *) data;
1976         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
1977 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
1978         Evas_Object *more_btn;
1979 #endif
1980         Evas_Object *layout;
1981
1982         ugd->naviframe = elm_naviframe_add(ugd->base);
1983         elm_naviframe_prev_btn_auto_pushed_set(ugd->naviframe, EINA_FALSE);
1984         eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
1985         eext_object_event_callback_add(ugd->naviframe, EEXT_CALLBACK_MORE, eext_naviframe_more_cb, NULL);
1986         elm_object_part_content_set(ugd->base, "elm.swallow.content", ugd->naviframe);
1987
1988         ugd->back_btn = elm_button_add(ugd->naviframe);
1989         elm_object_style_set(ugd->back_btn, "naviframe/back_btn/default");
1990         evas_object_smart_callback_add(ugd->back_btn, "clicked", _smart_back_btn_cb, (void *)ugd);
1991         elm_object_focus_allow_set(ugd->back_btn, EINA_FALSE);
1992
1993         /* Create layout */
1994         layout = elm_layout_add(ugd->naviframe);
1995         elm_layout_theme_set(layout, "layout", "application", "default");
1996         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1997         ugd->layout = layout;
1998
1999         ugd->genlist = _create_basic_genlist(ugd);
2000         if (ugd->genlist == NULL) {
2001                 DBG(LOG_ERROR, "Failed to create basic genlist");
2002                 return;
2003         }
2004         elm_object_part_content_set(layout, "elm.swallow.content", ugd->genlist);
2005
2006         evas_object_show(ugd->base);
2007         elm_object_focus_set(ugd->base, EINA_TRUE);
2008
2009         ugd->navi_item = elm_naviframe_item_push(ugd->naviframe, ugd->title,
2010                         ugd->back_btn, NULL, layout, NULL);
2011         elm_naviframe_item_pop_cb_set(ugd->navi_item, _back_btn_cb, ugd);
2012
2013 #ifdef TIZEN_WIFIDIRECT_MORE_BTN
2014         more_btn = elm_button_add(ugd->naviframe);
2015         elm_object_style_set(more_btn, "naviframe/more/default");
2016         evas_object_smart_callback_add(more_btn, "clicked",
2017                         _more_button_cb, ugd->win);
2018         elm_object_item_part_content_set(ugd->navi_item, "toolbar_more_btn",
2019                         more_btn);
2020 #endif
2021
2022         wifi_direct_initialize();
2023         wifi_direct_get_state(&ugd->wfd_status);
2024         if (ugd->wfd_status > WIFI_DIRECT_STATE_DEACTIVATING) {
2025                 scan_button_create(ugd);
2026         }
2027
2028         if (ugd->view_type && g_strcmp0(D_(ugd->view_type), D_("IDS_WIFI_BUTTON_MULTI_CONNECT")) == 0) {
2029                 int ret = 0;
2030                 ugd->raw_discovered_peer_cnt = 0;
2031                 wfd_create_multiconnect_view(ugd);
2032                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
2033                 ret = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
2034                 if (ret != WIFI_DIRECT_ERROR_NONE) {
2035                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
2036                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", ret);
2037                         wifi_direct_cancel_discovery();
2038                 }
2039                 return;
2040         }
2041
2042         __FUNC_EXIT__;
2043 }
2044
2045 /**
2046  *      This function let the ug destroy the main view
2047  *      @return   void
2048  *      @param[in] data the pointer to the main data structure
2049  */
2050 void destroy_wfd_ug_view(void *data)
2051 {
2052         __FUNC_ENTER__;
2053         struct ug_data *ugd = (struct ug_data *) data;
2054         WFD_IF_DEL_ITEM(ugd->device_name_item);
2055         WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
2056         WFD_IF_DEL_ITEM(ugd->conn_wfd_item);
2057
2058         WFD_IF_DEL_OBJ(ugd->scan_toolbar);
2059         WFD_IF_DEL_OBJ(ugd->back_btn);
2060         WFD_IF_DEL_OBJ(ugd->toolbar);
2061         WFD_IF_DEL_OBJ(ugd->genlist);
2062         WFD_IF_DEL_OBJ(ugd->button_layout);
2063         WFD_IF_DEL_OBJ(ugd->layout);
2064         WFD_IF_DEL_OBJ(ugd->naviframe);
2065         __FUNC_EXIT__;
2066 }