ce64950c56b157714c6a688b5485c22b6250642f
[apps/native/ug-wifi-direct.git] / ug-wifidirect / src / wfd_client.c
1 /*
2 *  WiFi-Direct UG
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
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 #include <stdio.h>
21 #include <stdbool.h>
22 #include <libintl.h>
23
24 #include <Elementary.h>
25 #include <vconf.h>
26 #include <vconf-keys.h>
27
28 #include <tethering.h>
29
30 #include <network-cm-intf.h>
31 #include <network-wifi-intf.h>
32
33 #include "wfd_ug.h"
34 #include "wfd_ug_view.h"
35 #include "wfd_client.h"
36
37 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data);
38
39 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
40 /**
41  *      This function let the ug make a change callback for wifi state
42  *      @return   void
43  *      @param[in] key the pointer to the key
44  *      @param[in] data the pointer to the main data structure
45  */
46 static void _wifi_state_cb(keynode_t *key, void *data)
47 {
48         __FUNC_ENTER__;
49         struct ug_data *ugd = (struct ug_data *)data;
50         int res;
51         int wifi_state;
52
53         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
54         if (res != 0) {
55                 DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
56                 return;
57         }
58
59         if (wifi_state == VCONFKEY_WIFI_OFF) {
60                 DBG(LOG_INFO, "WiFi is turned off\n");
61                 wfd_client_swtch_force(ugd, TRUE);
62         } else {
63                 DBG(LOG_INFO, "WiFi is turned on\n");
64         }
65
66         res = net_deregister_client();
67         if (res != NET_ERR_NONE)
68                 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
69
70         __FUNC_EXIT__;
71 }
72
73 /**
74  *      This function let the ug make a event callback for network registering
75  *      @return   void
76  *      @param[in] event_info the pointer to the information of network event
77  *      @param[in] user_data the pointer to the user data
78  */
79 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
80 {
81         __FUNC_ENTER__;
82         DBG(LOG_INFO, "Event from network. [%d]\n", event_info->Event);
83         __FUNC_EXIT__;
84 }
85
86 /**
87  *      This function let the ug turn wifi off
88  *      @return   If success, return 0, else return -1
89  *      @param[in] data the pointer to the main data structure
90  */
91 int wfd_wifi_off(void *data)
92 {
93         __FUNC_ENTER__;
94         struct ug_data *ugd = (struct ug_data *)data;
95         int res;
96
97         res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
98         if (res == -1) {
99                 DBG(LOG_ERROR, "Failed to register vconf callback\n");
100                 return -1;
101         }
102
103         DBG(LOG_INFO, "Vconf key callback is registered\n");
104
105         res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
106         if (res != NET_ERR_NONE) {
107                 DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
108                 return -1;
109         }
110
111         DBG(LOG_INFO, "Network client is registered\n");
112
113         res = net_wifi_power_off();
114         if (res != NET_ERR_NONE) {
115                 DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
116                 return -1;
117         }
118
119         DBG(LOG_INFO, "WiFi power off\n");
120
121         __FUNC_EXIT__;
122         return 0;
123 }
124 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
125
126
127 /**
128  *      This function let the ug make a callback for setting tethering mode enabled
129  *      @return   void
130  *      @param[in] error the returned error code
131  *      @param[in] type the type of tethering
132  *      @param[in] is_requested whether tethering mode is enabled
133  *      @param[in] data the pointer to the user data
134  */
135 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
136 {
137         __FUNC_ENTER__;
138         struct ug_data *ugd = (struct ug_data *)data;
139         tethering_error_e ret = TETHERING_ERROR_NONE;
140         tethering_h th = NULL;
141         bool is_wifi_enabled = false;
142
143         if (error != TETHERING_ERROR_NONE) {
144                 if (is_requested != TRUE)
145                         return;
146
147                 DBG(LOG_ERROR, "error !!! TETHERING is not enabled.\n");
148                 return;
149         }
150
151         th = ugd->hotspot_handle;
152         if (th != NULL) {
153                 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
154                 if (is_wifi_enabled)
155                         DBG(LOG_INFO, "Mobile hotspot is activated\n");
156
157                 /* Deregister cbs */
158                 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
159                 if (ret != TETHERING_ERROR_NONE)
160                         DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
161
162                 /* Destroy tethering handle */
163                 ret = tethering_destroy(th);
164                 if (ret != TETHERING_ERROR_NONE)
165                         DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
166
167                 ugd->hotspot_handle = NULL;
168         }
169
170         DBG(LOG_INFO, "TETHERING is enabled.\n");
171
172         __FUNC_EXIT__;
173         return;
174 }
175
176 /**
177  *      This function let the ug make a callback for setting tethering mode disabled
178  *      @return   void
179  *      @param[in] error the returned error code
180  *      @param[in] type the type of tethering
181  *      @param[in] code whether tethering mode is enabled
182  *      @param[in] data the pointer to the user data
183  */
184 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
185 {
186         __FUNC_ENTER__;
187
188         struct ug_data *ugd = (struct ug_data *)data;
189         tethering_error_e ret = TETHERING_ERROR_NONE;
190         tethering_h th = NULL;
191         bool is_wifi_enabled = false;
192
193         if (error != TETHERING_ERROR_NONE) {
194                 if (code != TETHERING_DISABLED_BY_REQUEST)
195                         return;
196
197                 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
198                 return;
199         }
200
201         th = ugd->hotspot_handle;
202         if (th != NULL) {
203                 is_wifi_enabled = tethering_is_enabled(th, TETHERING_TYPE_WIFI);
204                 if (is_wifi_enabled) {
205                         DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
206                         return;
207                 }
208
209                 DBG(LOG_INFO, "Mobile hotspot is deactivated\n");
210                 wfd_client_swtch_force(ugd, TRUE);
211
212                 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
213                 if (ret != TETHERING_ERROR_NONE)
214                         DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
215
216                 /* Destroy tethering handle */
217                 ret = tethering_destroy(th);
218                 if (ret != TETHERING_ERROR_NONE)
219                         DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
220
221                 ugd->hotspot_handle = NULL;
222         }
223
224         DBG(LOG_INFO, "TETHERING is disabled.\n");
225
226         __FUNC_EXIT__;
227         return;
228 }
229
230 /**
231  *      This function let the ug turn AP on
232  *      @return   If success, return 0, else return -1
233  *      @param[in] data the pointer to the main data structure
234  */
235 int wfd_mobile_ap_on(void *data)
236 {
237         __FUNC_ENTER__;
238         struct ug_data *ugd = (struct ug_data *)data;
239         tethering_error_e ret = TETHERING_ERROR_NONE;
240         WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
241
242         if (NULL == ugd->hotspot_handle) {
243                 ret = tethering_create(&(ugd->hotspot_handle));
244                 if (TETHERING_ERROR_NONE != ret) {
245                         DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", ret);
246                         ugd->hotspot_handle = NULL;
247                         return -1;
248                 }
249                 DBG(LOG_INFO, "Succeeded to tethering_create()\n");
250         }
251         /* Register cbs */
252         ret = tethering_set_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __enabled_cb, ugd);
253         if (ret != TETHERING_ERROR_NONE) {
254                 DBG(LOG_ERROR, "tethering_set_enabled_cb is failed\n", ret);
255                 return -1;
256         }
257
258         /* Enable tethering */
259         ret = tethering_enable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
260         if (ret != TETHERING_ERROR_NONE) {
261                 DBG(LOG_ERROR, "Failed to turn on mobile hotspot. [%d]\n", ret);
262                 return -1;
263         } else {
264                 DBG(LOG_INFO, "Succeeded to turn on mobile hotspot\n");
265         }
266
267         ugd->is_hotspot_off = FALSE;
268
269         __FUNC_EXIT__;
270         return 0;
271 }
272
273 /**
274  *      This function let the ug turn AP off
275  *      @return   If success, return 0, else return -1
276  *      @param[in] data the pointer to the main data structure
277  */
278 int wfd_mobile_ap_off(void *data)
279 {
280         __FUNC_ENTER__;
281         struct ug_data *ugd = (struct ug_data *)data;
282         WFD_RETV_IF(ugd == NULL || ugd->hotspot_handle == NULL, -1, "Incorrect parameter(NULL)\n");
283         tethering_error_e ret = TETHERING_ERROR_NONE;
284         bool is_wifi_enabled = false;
285
286         is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
287
288         if (is_wifi_enabled) {
289                 /* Register cbs */
290                 ret = tethering_set_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI, __disabled_cb, ugd);
291                 if (ret != TETHERING_ERROR_NONE) {
292                         DBG(LOG_ERROR, "tethering_set_disabled_cb is failed\n", ret);
293                         return -1;
294                 }
295                 /* Disable tethering */
296                 ret = tethering_disable(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
297         }
298
299         if (ret != TETHERING_ERROR_NONE) {
300                 DBG(LOG_ERROR, "Failed to turn off mobile hotspot. [%d]\n", ret);
301                 return -1;
302         } else {
303                 DBG(LOG_INFO, "Succeeded to turn off mobile hotspot\n");
304         }
305
306         ugd->is_hotspot_off = TRUE;
307
308         __FUNC_EXIT__;
309         return 0;
310 }
311
312 void wfd_client_free_raw_discovered_peers(struct ug_data *ugd)
313 {
314         __FUNC_ENTER__;
315         WFD_RET_IF(ugd->raw_discovered_peer_list == NULL, "Incorrect parameter(NULL)\n");
316
317         g_list_free(ugd->raw_discovered_peer_list);
318         ugd->raw_discovered_peer_list = NULL;
319
320         __FUNC_EXIT__;
321 }
322
323 /**
324  *      This function let the ug find the peer by mac address
325  *      @return   the found peer
326  *      @param[in] data the pointer to the main data structure
327  *      @param[in] mac_addr the pointer to mac address
328  */
329 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
330 {
331         __FUNC_ENTER__;
332         struct ug_data *ugd = (struct ug_data *)data;
333         wifi_direct_discovered_peer_info_s *peer_info = NULL;
334         GList *iterator = NULL;
335         int i;
336         WFD_RETV_IF(ugd == NULL, NULL, "Incorrect parameter(NULL)\n");
337
338         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
339                 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
340                         if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH))
341                                 return &ugd->raw_multi_selected_peers[i];
342                 }
343         } else {
344                 for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
345                         if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
346                                 return (device_type_s *)iterator->data;
347                 }
348         }
349
350         /*
351          * In case, device is not in raw discovered list, then get peer info.
352          * There could be situation in which device is not yet discovered and
353          * connected process started.
354          */
355         if (WIFI_DIRECT_ERROR_NONE != wifi_direct_get_peer_info((char *)mac_addr, &peer_info) ||
356                 NULL == peer_info) {
357                 DBG(LOG_ERROR, "Peer Not Found !!!");
358                 return NULL;
359         }
360
361         /* Update peer list */
362         DBG(LOG_INFO, "Update Peer info");
363         _wfd_discoverd_peer_cb(peer_info, (void *)ugd);
364
365         /* Get the device from peer list */
366         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
367                 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
368                         return (device_type_s *)iterator->data;
369         }
370
371         __FUNC_EXIT__;
372         return NULL;
373 }
374
375 /**
376  *      This function let the ug make a callback for registering activation event
377  *      @return   void
378  *      @param[in] error_code the returned error code
379  *      @param[in] device_state the state of device
380  *      @param[in] user_data the pointer to the main data structure
381  */
382 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
383 {
384         __FUNC_ENTER__;
385         int res = -1;
386         struct ug_data *ugd = (struct ug_data *)user_data;
387         wfd_refresh_wifi_direct_state(ugd);
388
389         switch (device_state) {
390         case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
391                 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
392                 if (ugd->scan_toolbar == NULL)
393                         scan_button_create(ugd);
394
395                 if (error_code != WIFI_DIRECT_ERROR_NONE) {
396                         DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
397                         if (WIFI_DIRECT_ERROR_AUTH_FAILED == error_code)
398                                 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_SECURITY_POLICY_RESTRICTS_USE_OF_WI_FI"), POPUP_TYPE_ACTIVATE_FAIL_POLICY_RESTRICTS);
399                         else
400                                 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_ACTIVATE_FAIL);
401
402 #ifdef WFD_ON_OFF_GENLIST
403                         ugd->wfd_onoff = 0;
404                         wfd_ug_refresh_on_off_check(ugd);
405 #endif
406                         return;
407                 }
408
409                 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
410 #ifdef WFD_ON_OFF_GENLIST
411                 ugd->wfd_onoff = 1;
412                 wfd_ug_refresh_on_off_check(ugd);
413 #endif
414                 wfg_ug_act_popup_remove(ugd);
415
416                 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
417                         DBG(LOG_INFO, "Background mode\n");
418                         return;
419                 }
420
421 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
422                 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
423                 if (res == -1)
424                         DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
425 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
426
427                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
428                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
429                 if (res != WIFI_DIRECT_ERROR_NONE) {
430                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
431                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
432                         wifi_direct_cancel_discovery();
433                 }
434
435                 break;
436         case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
437                 DBG(LOG_INFO, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
438                 if (error_code != WIFI_DIRECT_ERROR_NONE) {
439                         DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
440                         wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_DEACTIVATE_FAIL);
441 #ifdef WFD_ON_OFF_GENLIST
442                         ugd->wfd_onoff = 1;
443                         wfd_ug_refresh_on_off_check(ugd);
444 #endif
445                         return;
446                 }
447
448                 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
449
450                 if (ugd->ctxpopup)
451                         ctxpopup_dismissed_cb(ugd, NULL, NULL);
452
453                 /*
454                  * When multi-connect is on ongoing and deactivte happened destroy
455                  * disconnect button.
456                  */
457                 if (ugd->disconnect_btn) {
458                         Evas_Object *content;
459                         content = elm_object_part_content_unset(ugd->button_layout, "button.next");
460                         WFD_IF_DEL_OBJ(content);
461                         ugd->disconnect_btn = NULL;
462                         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
463                 }
464
465                 /* When connect is on ongoing and deactivte happened refresh scan */
466                 if (ugd->scan_toolbar) {
467                         wfd_ug_view_refresh_button(ugd->scan_toolbar,
468                                 "IDS_WIFI_SK4_SCAN", FALSE);
469                 }
470                 /* Delete pop-up when deactivate happens */
471                 WFD_IF_DEL_OBJ(ugd->act_popup);
472                 /* Remove timeout handlers */
473                 if (ugd->timer_stop_progress_bar > 0)
474                         g_source_remove(ugd->timer_stop_progress_bar);
475
476                 if (ugd->timer_delete_not_alive_peer > 0)
477                         g_source_remove(ugd->timer_delete_not_alive_peer);
478
479                 if (ugd->g_source_multi_connect_next > 0)
480                         g_source_remove(ugd->g_source_multi_connect_next);
481
482                 if (ugd->timer_multi_reset > 0)
483                         g_source_remove(ugd->timer_multi_reset);
484
485                 /* Delete warn popups for Airplane mode */
486                 if (NULL != ugd->warn_popup) {
487                         evas_object_del(ugd->warn_popup);
488                         ugd->warn_popup = NULL;
489                 }
490
491 #ifdef WFD_ON_OFF_GENLIST
492                 ugd->wfd_onoff = 0;
493                 wfd_ug_refresh_on_off_check(ugd);
494 #endif
495                 /*
496                 * when deactivated, clear all the
497                 *  discovered peers and connected peers
498                 */
499                 wfd_client_free_raw_discovered_peers(ugd);
500                 if (ugd->raw_connected_peer_cnt > 0)
501                         memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
502
503                 ugd->raw_discovered_peer_cnt = 0;
504                 ugd->raw_connected_peer_cnt = 0;
505
506                 wfd_free_nodivice_item(ugd);
507                 wfd_ug_view_init_genlist(ugd, true);
508
509                 if (ugd->multi_navi_item != NULL)
510                         elm_naviframe_item_pop(ugd->naviframe);
511
512                 if (TRUE == ugd->is_hotspot_off && TRUE == ugd->is_hotspot_locally_disabled) {
513                         if (0 == wfd_mobile_ap_on(ugd))
514                                 ugd->is_hotspot_locally_disabled = FALSE;
515                 }
516
517                 if (ugd->scan_toolbar) {
518                         evas_object_del(ugd->scan_toolbar);
519                         ugd->scan_toolbar = NULL;
520                 }
521                 break;
522         default:
523                 break;
524         }
525
526         /*if (ugd->scan_toolbar)
527                 wfd_ug_view_refresh_button(ugd->scan_toolbar, D_("IDS_WIFI_SK4_SCAN"), TRUE);
528         */
529
530         if (ugd->multiconn_scan_stop_btn)
531                 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
532
533         if (ugd->back_btn)
534                 elm_object_disabled_set(ugd->back_btn, FALSE);
535
536         __FUNC_EXIT__;
537         return;
538 }
539
540 /**
541  *      This function let the ug make a callback for discovering peer
542  *      @return   TRUE
543  *      @param[in] peer the pointer to the discovered peer
544  *      @param[in] user_data the pointer to the main data structure
545  */
546 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
547 {
548         __FUNC_ENTER__;
549         WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
550
551         struct ug_data *ugd = (struct ug_data *)user_data;
552         int peer_cnt = ugd->raw_discovered_peer_cnt;
553         device_type_s *peer_tmp = g_new(device_type_s, 1);
554         int i;
555
556         DBG_SECURE(LOG_INFO, "%dth discovered peer. [%s] ["MACSECSTR"]\n", peer_cnt,
557                 peer->device_name, MAC2SECSTR(peer->mac_address));
558
559         if (ugd->device_filter < 0 || peer->primary_device_type == ugd->device_filter) {
560                 strncpy(peer_tmp->ssid, peer->device_name, sizeof(peer_tmp->ssid) - 1);
561                 peer_tmp->ssid[SSID_LENGTH - 1] = '\0';
562                 peer_tmp->category = peer->primary_device_type;
563                 peer_tmp->sub_category = peer->secondary_device_type;
564                 strncpy(peer_tmp->mac_addr, peer->mac_address, MAC_LENGTH - 1);
565                 peer_tmp->mac_addr[MAC_LENGTH - 1] = '\0';
566                 strncpy(peer_tmp->if_addr, peer->interface_address, MAC_LENGTH - 1);
567                 peer_tmp->if_addr[MAC_LENGTH - 1] = '\0';
568                 peer_tmp->is_group_owner = peer->is_group_owner;
569                 peer_tmp->is_persistent_group_owner = peer->is_persistent_group_owner;
570                 peer_tmp->is_connected = peer->is_connected;
571                 peer_tmp->dev_sel_state = FALSE;
572
573                 if (TRUE == peer->is_connected)
574                         peer_tmp->conn_status = PEER_CONN_STATUS_CONNECTED;
575                 else
576                         peer_tmp->conn_status = PEER_CONN_STATUS_DISCONNECTED;
577
578                 ugd->raw_discovered_peer_list = g_list_append(ugd->raw_discovered_peer_list, peer_tmp);
579                 DBG(LOG_INFO, "\tSSID: [%s]\n", peer_tmp->ssid);
580                 DBG(LOG_INFO, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peer_tmp->category);
581                 DBG(LOG_INFO, "\tStatus: [%d]\n", peer_tmp->conn_status);
582                 DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
583                 ugd->raw_discovered_peer_cnt++;
584         } else {
585                 DBG(LOG_INFO, "Unavailable WiFi-Direct Device\n");
586         }
587
588         WFD_IF_FREE_MEM(peer->device_name);
589         WFD_IF_FREE_MEM(peer->mac_address);
590         WFD_IF_FREE_MEM(peer->interface_address);
591
592         if (NULL != peer->service_list) {
593                 for (i = 0; i < peer->service_count && peer->service_list[i] != NULL; i++)
594                         free(peer->service_list[i]);
595
596                 WFD_IF_FREE_MEM(peer->service_list);
597         }
598
599         WFD_IF_FREE_MEM(peer);
600
601         __FUNC_EXIT__;
602         return TRUE;
603 }
604
605 /**
606  *      This function let the ug make a callback for connected peer
607  *      @return   TRUE
608  *      @param[in] peer the pointer to the connected peer
609  *      @param[in] user_data the pointer to the main data structure
610  */
611 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
612 {
613         __FUNC_ENTER__;
614         WFD_RETV_IF(NULL == peer || NULL == user_data, FALSE, "Incorrect parameter(NULL)\n");
615
616         struct ug_data *ugd = (struct ug_data *)user_data;
617         int peer_cnt = ugd->raw_connected_peer_cnt;
618         int i;
619
620         DBG_SECURE(LOG_INFO, "%dth connected peer. [%s] ["MACSECSTR"]\n", peer_cnt,
621                 peer->device_name, MAC2SECSTR(peer->mac_address));
622
623         /*
624         * check wether ug needs to exit
625         * automatically after successed connection
626         */
627
628         char services[256] = {0,};
629         DBG(LOG_INFO, "\tservice_count: [%d]\n", peer->service_count);
630         if (peer->service_count > 0) {
631                 unsigned int len = 0;
632                 for (i = 0; i < peer->service_count && peer->service_list != NULL; i++) {
633                         snprintf(services + len, 256-len, "%s ", peer->service_list[i]);
634                         len = len + strlen(peer->service_list[i]) + 1;
635                 }
636                 DBG(LOG_INFO, "\tServices: [%s]\n", services);
637         }
638
639         g_strlcpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid));
640         ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
641         ugd->raw_connected_peers[peer_cnt].sub_category = peer->secondary_device_type;
642         g_strlcpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
643         g_strlcpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
644         ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
645
646         DBG(LOG_INFO, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
647         DBG(LOG_INFO, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
648         DBG(LOG_INFO, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
649
650         ugd->raw_connected_peer_cnt++;
651
652         int error = -1;
653         bool is_group_owner = FALSE;
654         error = wifi_direct_is_group_owner(&is_group_owner);
655         if (error != WIFI_DIRECT_ERROR_NONE) {
656                 DBG(LOG_ERROR, "Fail to get group_owner_state. ret=[%d]", error);
657                 return FALSE;
658         }
659
660         if (FALSE == is_group_owner) {
661                 /* to send ip_addr*/
662                 int ret = -1;
663                 app_control_h control = NULL;
664                 ret = app_control_create(&control);
665                 if (ret) {
666                         DBG(LOG_ERROR, "Failed to create control");
667                         return FALSE;
668                 }
669
670                 if (peer->ip_address != NULL && strlen(services) != 0) {
671                         app_control_add_extra_data(control, "ip_address", peer->ip_address);
672                         app_control_add_extra_data(control, "wfds", services);
673                         ug_send_result(ugd->ug, control);
674                 }
675                 app_control_destroy(control);
676         }
677
678         WFD_IF_FREE_MEM(peer->device_name);
679         WFD_IF_FREE_MEM(peer->mac_address);
680         WFD_IF_FREE_MEM(peer->interface_address);
681
682         if (NULL != peer->service_list) {
683                 for (i = 0; i < peer->service_count && peer->service_list[i] != NULL; i++)
684                         free(peer->service_list[i]);
685
686                 WFD_IF_FREE_MEM(peer->service_list);
687         }
688
689         WFD_IF_FREE_MEM(peer);
690
691         __FUNC_EXIT__;
692         return TRUE;
693 }
694
695 /**
696  *      This function let the ug get the found peers
697  *      @return   If success, return 0, else return -1
698  *      @param[in] ugd the pointer to the main data structure
699  */
700 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
701 {
702         __FUNC_ENTER__;
703         int res = 0;
704         WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
705
706         ugd->raw_discovered_peer_cnt = 0;
707         wfd_client_free_raw_discovered_peers(ugd);
708         res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
709         if (res != WIFI_DIRECT_ERROR_NONE) {
710                 ugd->raw_discovered_peer_cnt = 0;
711                 DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
712         }
713
714         __FUNC_EXIT__;
715         return 0;
716 }
717
718 #if 0
719 /**
720  *      This function let the ug get the connecting peer
721  *      @return   If success, return 0, else return -1
722  *      @param[in] ugd the pointer to the main data structure
723  */
724 int wfd_ug_get_connecting_peer(struct ug_data *ugd)
725 {
726         __FUNC_ENTER__;
727         int res = 0;
728         WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
729         char *mac_addr = NULL;
730         GList *iterator = NULL;
731
732         ugd->mac_addr_connecting = NULL;
733         res = wifi_direct_get_connecting_peer(&mac_addr);
734         if (res != WIFI_DIRECT_ERROR_NONE) {
735                 DBG(LOG_ERROR, "Get connecting device mac failed: %d\n", res);
736                 return -1;
737         }
738         DBG_SECURE(LOG_INFO, "Mac Addr Connecting: ["MACSECSTR"]\n",
739                 MAC2SECSTR(mac_addr));
740         ugd->mac_addr_connecting = mac_addr;
741
742         for (iterator = ugd->raw_discovered_peer_list; iterator; iterator = iterator->next) {
743                 if (!strncmp(mac_addr, ((device_type_s *)iterator->data)->mac_addr, MAC_LENGTH))
744                         ((device_type_s *)iterator->data)->conn_status = PEER_CONN_STATUS_CONNECTING;
745         }
746
747
748         __FUNC_EXIT__;
749         return 0;
750 }
751 #endif
752
753 /**
754  *      This function let the ug get the connected peers
755  *      @return   If success, return 0, else return -1
756  *      @param[in] ugd the pointer to the main data structure
757  */
758 int wfd_ug_get_connected_peers(struct ug_data *ugd)
759 {
760         __FUNC_ENTER__;
761         int res = 0;
762         WFD_RETV_IF(ugd == NULL, -1, "Incorrect parameter(NULL)\n");
763
764         ugd->raw_connected_peer_cnt = 0;
765         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
766         if (res != WIFI_DIRECT_ERROR_NONE) {
767                 ugd->raw_connected_peer_cnt = 0;
768                 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
769         }
770
771         __FUNC_EXIT__;
772         return 0;
773 }
774
775 /**
776  *      This function let the ug exits automatically after successed connection
777  *      @return   void
778  *      @param[in] user_data the pointer to the main data structure
779  */
780 void _wfd_ug_auto_exit(void *user_data)
781 {
782         __FUNC_ENTER__;
783         struct ug_data *ugd = (struct ug_data *)user_data;
784         WFD_RET_IF(ugd == NULL, "Incorrect parameter(NULL)\n");
785
786         deinit_wfd_client(ugd);
787         wfd_destroy_ug(ugd);
788
789         __FUNC_EXIT__;
790 }
791
792 gboolean wfd_delete_not_alive_peer_cb(void *user_data)
793 {
794         __FUNC_ENTER__;
795         struct ug_data *ugd = (struct ug_data *)user_data;
796         WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
797
798         delete_not_alive_peers(ugd, &ugd->gl_avlb_peers_start, &ugd->gl_available_peer_cnt);
799         delete_not_alive_peers(ugd, &ugd->gl_busy_peers_start, &ugd->gl_busy_peer_cnt);
800         delete_not_alive_peers(ugd, &ugd->multi_conn_dev_list_start, &ugd->gl_available_dev_cnt_at_multiconn_view);
801         wfd_ug_view_init_genlist(ugd, false);
802         wfd_update_multiconnect_device(ugd, false);
803         __FUNC_EXIT__;
804         return FALSE;
805 }
806
807
808 gboolean wfd_delete_progressbar_cb(void *user_data)
809 {
810         __FUNC_ENTER__;
811         struct ug_data *ugd = (struct ug_data *)user_data;
812         WFD_RETV_IF(ugd == NULL, FALSE, "Incorrect parameter(NULL)\n");
813
814         ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
815         if (ugd->raw_discovered_peer_cnt == 0 &&
816                 ugd->nodevice_title_item == NULL &&
817                 ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE &&
818                 ugd->gl_available_peer_cnt == 0) {
819                         _create_no_device_genlist(ugd);
820         };
821
822         wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
823         wfd_ug_view_refresh_glitem(ugd->avlbl_wfd_item);
824
825         if (0 == ugd->gl_available_dev_cnt_at_multiconn_view)
826                 _create_no_device_multiconnect_genlist(ugd);
827
828         wfd_refresh_wifi_direct_state(ugd);
829         if (WIFI_DIRECT_STATE_CONNECTING != ugd->wfd_status &&
830                 WIFI_DIRECT_STATE_DISCONNECTING != ugd->wfd_status) {
831                 if (ugd->scan_toolbar) {
832                         wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
833                         evas_object_data_set(ugd->toolbar, "scan", "scan");
834                 }
835
836                 if (ugd->multiconn_layout) {
837                         wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
838                         DBG(LOG_INFO, "Multiconn button text IDS_WIFI_SK4_SCAN \n");
839
840                 }
841         }
842
843         __FUNC_EXIT__;
844         return FALSE;
845 }
846
847 /**
848  *      This function let the ug make a callback for registering discover event
849  *      @return   void
850  *      @param[in] error_code the returned error code
851  *      @param[in] discovery_state the state of discover
852  *      @param[in] user_data the pointer to the main data structure
853  */
854 void discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
855 {
856         __FUNC_ENTER__;
857         int ret;
858         struct ug_data *ugd = (struct ug_data *)user_data;
859
860         if (ugd == NULL) {
861                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
862                 return;
863         }
864
865         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS)
866                 return;
867
868         DBG(LOG_INFO, "Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
869
870         if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
871                 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
872                         ugd->title_content_mode = TITLE_CONTENT_TYPE_SCANNING;
873                         wfd_cancel_progressbar_stop_timer(ugd);
874                         ugd->timer_stop_progress_bar = g_timeout_add(1000*30, wfd_delete_progressbar_cb, ugd);
875                         /* clear all the previous discovered peers */
876                         wfd_client_free_raw_discovered_peers(ugd);
877
878                         ugd->raw_discovered_peer_cnt = 0;
879                         wfd_ug_view_init_genlist(ugd, false);
880
881                         if (ugd->avlbl_wfd_item == NULL)
882                                 _create_available_dev_genlist(ugd);
883
884                         wfd_ug_view_refresh_glitem(ugd->mcview_title_item);
885                         /* clear not alive peers after 5 secs */
886                         wfd_cancel_not_alive_delete_timer(ugd);
887                         ugd->timer_delete_not_alive_peer = g_timeout_add(1000*5, wfd_delete_not_alive_peer_cb, ugd);
888                         set_not_alive_peers(ugd->gl_avlb_peers_start);
889                         set_not_alive_peers(ugd->gl_busy_peers_start);
890                         set_not_alive_peers(ugd->multi_conn_dev_list_start);
891                 }
892         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
893                 if (ugd->wfd_discovery_status != WIFI_DIRECT_DISCOVERY_NONE) {
894                         wfd_ug_get_discovered_peers(ugd);
895                         wfd_ug_update_available_peers(ugd);
896                         wfd_update_multiconnect_device(ugd, false);
897                 }
898         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FINISHED) {
899                 if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
900                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_FULL_SCAN_START;
901                         ret = wifi_direct_start_discovery_specific_channel(false, 0, WIFI_DIRECT_DISCOVERY_FULL_SCAN);
902                         if (ret != WIFI_DIRECT_ERROR_NONE) {
903                                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
904                                 DBG(LOG_ERROR, "Failed to start discovery with full scan. [%d]\n", ret);
905                                 wifi_direct_cancel_discovery();
906                         }
907                 }
908         }
909
910         if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state &&
911                 ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START) {
912                 WFD_IF_DEL_ITEM(ugd->multi_connect_toolbar_item);
913                 if (!ugd->conn_wfd_item)
914                         elm_layout_content_set(ugd->button_layout, "button.big", ugd->scan_toolbar);
915
916                 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK_STOP", TRUE);
917                 if (ugd->multiconn_scan_stop_btn)
918                         wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK_STOP", TRUE);
919         }
920
921         __FUNC_EXIT__;
922         return;
923 }
924
925 /**
926  *      This function let the ug make a callback for registering connection event
927  *      @return   void
928  *      @param[in] error_code the returned error code
929  *      @param[in] connection_state the state of connection
930  *      @param[in] mac_address the mac address of peer
931  *      @param[in] user_data the pointer to the main data structure
932  */
933 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
934 {
935         __FUNC_ENTER__;
936         struct ug_data *ugd = (struct ug_data *)user_data;
937         device_type_s *peer = NULL;
938         bool owner = FALSE;
939         int res = 0;
940
941         if (mac_address == NULL) {
942                 DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
943                 return;
944         }
945
946         DBG_SECURE(LOG_INFO, "Connection event [%d], error_code [%d], multi_connect_mode [%d] mac ["MACSECSTR"]\n",
947                 connection_state, error_code, ugd->multi_connect_mode, MAC2SECSTR(mac_address));
948
949         /* when not in connection, mac_address is empty */
950         if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
951                 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
952
953                 if (NULL == peer || '\0' == peer->ssid[0]) {
954                         DBG(LOG_ERROR, "invalid peer from connection !!\n");
955                         ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
956                         goto refresh_button;
957                 }
958         }
959
960         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
961                 switch (connection_state) {
962                 case WIFI_DIRECT_CONNECTION_RSP:
963                         DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
964                         ugd->mac_addr_connecting = NULL;
965                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
966                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
967                                 wfd_ug_get_connected_peers(ugd);
968                                 wfd_ug_update_connected_peers(ugd);
969                         } else {
970                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
971                                 peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
972                                 if (peer != NULL) {
973                                         peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
974                                         wfd_ug_view_refresh_glitem(peer->gl_item);
975                                 }
976                         }
977                         /* connect the next peer */
978                         ugd->g_source_multi_connect_next = g_timeout_add(500, wfd_multi_connect_next_cb, ugd);
979                         break;
980                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
981                         DBG(LOG_INFO, "MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
982                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
983                         peer = find_peer_in_glist(ugd->gl_mul_conn_peers_start, peer->mac_addr);
984
985                         if (peer != NULL) {
986                                 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
987                                 wfd_ug_view_refresh_glitem(peer->gl_item);
988                         }
989
990                         wfd_ug_update_toolbar(ugd);
991                         break;
992                 case WIFI_DIRECT_GROUP_CREATED:
993                         DBG(LOG_INFO, "MULTI: WIFI_DIRECT_GROUP_CREATED\n");
994                         wfd_cancel_progressbar_stop_timer(ugd);
995                         wfd_delete_progressbar_cb(ugd);
996
997                         wfd_ug_view_init_genlist(ugd, true);
998                         wfd_ug_view_update_multiconn_peers(ugd);
999                         wfd_multi_connect_next_cb(ugd);
1000                         break;
1001                 default:
1002                         break;
1003                 }
1004         } else {
1005                 switch (connection_state) {
1006                 case WIFI_DIRECT_CONNECTION_RSP:
1007                         DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_RSP\n");
1008                         wfd_delete_progressbar_cb(ugd);
1009
1010                         if (ugd->act_popup) {
1011                                 evas_object_del(ugd->act_popup);
1012                                 ugd->act_popup = NULL;
1013                         }
1014                         ugd->mac_addr_connecting = NULL;
1015
1016                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
1017                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
1018                                 wfd_ug_get_connected_peers(ugd);
1019
1020                                 /* when auto_exit and not multi-connect*/
1021                                 if ((ugd->is_auto_exit) && (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE))
1022                                         _wfd_ug_auto_exit(ugd);
1023
1024                                 wfd_ug_update_connected_peers(ugd);
1025                         } else {
1026                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
1027                                 wfd_ug_update_failed_peers(ugd);
1028                         }
1029
1030                         wfd_ug_update_toolbar(ugd);
1031                         break;
1032                 case WIFI_DIRECT_DISASSOCIATION_IND:
1033                         DBG(LOG_INFO, "WIFI_DIRECT_DISASSOCIATION_IND\n");
1034                         /* remove any possible popup */
1035                         WFD_IF_DEL_OBJ(ugd->act_popup);
1036                         wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", TRUE);
1037
1038                         /* change the multi connection mode, it can be connected now */
1039                         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED)
1040                                 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1041
1042                         /* if other peer disconnected, get connected peers and update */
1043                         peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
1044                         wfd_ug_get_connected_peers(ugd);
1045                         wfd_ug_update_available_peers(ugd);
1046                         break;
1047                 case WIFI_DIRECT_DISCONNECTION_RSP:
1048                 case WIFI_DIRECT_DISCONNECTION_IND:
1049                         DBG(LOG_INFO, "WIFI_DIRECT_DISCONNECTION_X\n");
1050                         WFD_IF_DEL_OBJ(ugd->act_popup);
1051
1052                         Evas_Object *content;
1053                         content = elm_object_part_content_unset(ugd->button_layout, "button.next");
1054                         WFD_IF_DEL_OBJ(content);
1055                         content = elm_object_part_content_unset(ugd->button_layout, "button.prev");
1056                         evas_object_hide(content);
1057
1058                         /* when disconnection, clear all the connected peers */
1059                         if (ugd->raw_connected_peer_cnt > 0)
1060                                 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
1061
1062                         ugd->raw_connected_peer_cnt = 0;
1063                         wfd_ug_view_init_genlist(ugd, true);
1064                         if (ugd->wfd_discovery_status == WIFI_DIRECT_DISCOVERY_BACKGROUND) {
1065                                 DBG(LOG_INFO, "Background mode\n");
1066                                 break;
1067                         }
1068
1069                         if (ugd->is_paused == false) {
1070                                 /* start discovery again */
1071                                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1072                                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1073                                 if (res != WIFI_DIRECT_ERROR_NONE) {
1074                                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1075                                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1076                                         wifi_direct_cancel_discovery();
1077                                 }
1078                         }
1079
1080                         break;
1081                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
1082                         DBG(LOG_INFO, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
1083                         wfd_ug_update_toolbar(ugd);
1084                         wfd_cancel_progressbar_stop_timer(ugd);
1085                         wfd_delete_progressbar_cb(ugd);
1086
1087                         if (ugd->multi_navi_item)
1088                                 elm_naviframe_item_pop(ugd->naviframe);
1089
1090                         ugd->mac_addr_connecting = peer->mac_addr;
1091                         ugd->is_conn_incoming = FALSE;
1092                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1093                         peer = find_peer_in_glist(ugd->gl_avlb_peers_start, peer->mac_addr);
1094                         if (peer != NULL) {
1095                                 peer->conn_status = PEER_CONN_STATUS_CONNECTING;
1096                                 wfd_ug_view_refresh_glitem(peer->gl_item);
1097                         } else {
1098                                 wfd_ug_get_discovered_peers(ugd);
1099                                 wfd_ug_update_available_peers(ugd);
1100                         }
1101
1102                         break;
1103                 case WIFI_DIRECT_CONNECTION_REQ:
1104                 case WIFI_DIRECT_CONNECTION_WPS_REQ:
1105                         ugd->mac_addr_connecting = peer->mac_addr;
1106                         ugd->is_conn_incoming = TRUE;
1107                         DBG(LOG_INFO, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
1108                         break;
1109                 case WIFI_DIRECT_GROUP_DESTROYED:
1110                         wfd_ug_update_toolbar(ugd);
1111                         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
1112                                 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_NONE;
1113                         } else {
1114                                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1115                                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1116                                 if (res != WIFI_DIRECT_ERROR_NONE) {
1117                                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1118                                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1119                                         wifi_direct_cancel_discovery();
1120                                 }
1121                         }
1122
1123                         break;
1124                 default:
1125                         break;
1126                 }
1127         }
1128
1129 refresh_button:
1130         /* refresh the scan button */
1131         wfd_refresh_wifi_direct_state(ugd);
1132         if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
1133                 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
1134                 res = wifi_direct_is_group_owner(&owner);
1135                 if (res == WIFI_DIRECT_ERROR_NONE) {
1136                         if (!owner) {
1137                                 if (ugd->scan_toolbar)
1138                                         evas_object_data_set(ugd->toolbar, "scan", "scan");
1139
1140                                 if (ugd->multiconn_scan_stop_btn)
1141                                         wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1142                         }
1143                 } else {
1144                     DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
1145                 }
1146         } else {
1147                 if (ugd->scan_toolbar)
1148                         evas_object_data_set(ugd->toolbar, "scan", "scan");
1149
1150                 if (ugd->multiconn_scan_stop_btn)
1151                         wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", TRUE);
1152         }
1153
1154         __FUNC_EXIT__;
1155         return;
1156 }
1157
1158 /**
1159  *      This function let the ug make a callback for registering ip assigned event
1160  *      @return   void
1161  *      @param[in] mac_address the mac address of peer
1162  *      @param[in] ip_address the ip address of peer
1163  *      @param[in] interface_address the interface address
1164  *      @param[in] user_data the pointer to the main data structure
1165  */
1166 void _ip_assigned_cb(const char *mac_address, const char *ip_address, const char *interface_address, void *user_data)
1167 {
1168         __FUNC_ENTER__;
1169
1170         if (!user_data) {
1171                 DBG(LOG_ERROR, "The user_data is NULL\n");
1172                 return;
1173         }
1174
1175         struct ug_data *ugd = (struct ug_data *)user_data;
1176
1177         if (!ip_address || 0 == strncmp(ip_address, "0.0.0.0", 7)) {
1178                 DBG(LOG_ERROR, "ip address is invalid.\n");
1179                 return;
1180         }
1181
1182         ugd->peer_ip_address = strdup(ip_address);
1183
1184
1185         /* to send ip_addr*/
1186         int ret = -1;
1187         app_control_h control = NULL;
1188         ret = app_control_create(&control);
1189         if (ret) {
1190                 DBG(LOG_ERROR, "Failed to create control");
1191                 return;
1192         }
1193         app_control_add_extra_data(control, "ip_address", ugd->peer_ip_address);
1194         app_control_add_extra_data(control, "wfds", ugd->service_name);
1195         ug_send_result(ugd->ug, control);
1196         app_control_destroy(control);
1197
1198         /* when auto_exit and not multi-connect*/
1199         if ((ugd->is_auto_exit) && (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_NONE))
1200                 _wfd_ug_auto_exit(ugd);
1201
1202         __FUNC_EXIT__;
1203 }
1204
1205 /**
1206  *      This function let the ug get wi-fi direct status from vconf
1207  *      @return   If success, return the wfd status, else return -1
1208  *      @param[in] void
1209  */
1210 int wfd_get_vconf_status()
1211 {
1212         __FUNC_ENTER__;
1213         int wifi_direct_state = 0;
1214
1215         /* get wifi direct status from vconf */
1216         if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
1217                 DBG(LOG_ERROR, "Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
1218                 return -1;
1219         }
1220         DBG(LOG_INFO, "WiFi Direct State [%d]", wifi_direct_state);
1221
1222         __FUNC_EXIT__;
1223         return wifi_direct_state;
1224 }
1225
1226 /**
1227  *      This function let the ug get device name from vconf
1228  *      @return   If success, return 0, else return -1
1229  *      @param[in] data the pointer to the main data structure
1230  */
1231 int wfd_get_vconf_device_name(void *data)
1232 {
1233         __FUNC_ENTER__;
1234         struct ug_data *ugd = (struct ug_data *)data;
1235         char *dev_name = NULL;
1236
1237         /* get device name from vconf */
1238         dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1239         if (dev_name == NULL) {
1240                 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1241                 DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
1242                 return -1;
1243         }
1244
1245         ugd->dev_name = strdup(dev_name);
1246         WFD_IF_FREE_MEM(dev_name);
1247
1248         __FUNC_EXIT__;
1249         return 0;
1250 }
1251
1252 /**
1253  *      This function let the ug refresh current status of wi-fi direct
1254  *      @return   If success, return 0, else return -1
1255  *      @param[in] data the pointer to the main data structure
1256  */
1257 int wfd_refresh_wifi_direct_state(void *data)
1258 {
1259         __FUNC_ENTER__;
1260         struct ug_data *ugd = (struct ug_data *)data;
1261         int res;
1262         wifi_direct_state_e wfd_status;
1263
1264         res = wifi_direct_get_state(&wfd_status);
1265         if (res != WIFI_DIRECT_ERROR_NONE) {
1266                 DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
1267                 return -1;
1268         }
1269
1270         DBG(LOG_INFO, "WFD status [%d]", wfd_status);
1271         ugd->wfd_status = wfd_status;
1272
1273         __FUNC_EXIT__;
1274         return 0;
1275 }
1276
1277 void wfd_init_ug_by_status(void *user_data)
1278 {
1279         __FUNC_ENTER__;
1280         struct ug_data *ugd = (struct ug_data *)user_data;
1281         int res = 0;
1282
1283         if (ugd == NULL) {
1284                 DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
1285                 return;
1286         }
1287
1288         if (ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED) {
1289                 //wfd_ug_get_discovered_peers(ugd);
1290                 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1291         }
1292
1293         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
1294                 wfd_ug_get_connected_peers(ugd);
1295                 wfd_ug_update_connected_peers(ugd);
1296                 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1297                 wfd_ug_get_discovered_peers(ugd);
1298                 wfd_ug_update_available_peers(ugd);
1299                 wfd_ug_update_toolbar(ugd);
1300         }
1301
1302         if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING) {
1303                 ugd->title_content_mode = TITLE_CONTENT_TYPE_NONE;
1304                 wfd_ug_get_discovered_peers(ugd);
1305                 wfd_ug_get_connecting_peer(ugd);
1306                 wfd_ug_update_available_peers(ugd);
1307                 wfd_ug_update_toolbar(ugd);
1308         }
1309
1310         if (ugd->wfd_status == WIFI_DIRECT_STATE_ACTIVATED ||
1311                 ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1312                 /* start discovery */
1313                 ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL_START;
1314                 res = wifi_direct_start_discovery_specific_channel(false, 1, WIFI_DIRECT_DISCOVERY_SOCIAL_CHANNEL);
1315                 if (res != WIFI_DIRECT_ERROR_NONE) {
1316                         ugd->wfd_discovery_status = WIFI_DIRECT_DISCOVERY_NONE;
1317                         DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
1318                         wifi_direct_cancel_discovery();
1319                 }
1320         }
1321
1322         __FUNC_EXIT__;
1323 }
1324
1325 /**
1326  *      This function let the ug do initialization
1327  *      @return   If success, return 0, else return -1
1328  *      @param[in] data the pointer to the main data structure
1329  */
1330 int init_wfd_client(void* data)
1331 {
1332         __FUNC_ENTER__;
1333         WFD_RETV_IF(data == NULL, -1, "Incorrect parameter(NULL)\n");
1334         struct ug_data *ugd = (struct ug_data *)data;
1335         int res = 0;
1336
1337         res = wifi_direct_initialize();
1338         if (res != WIFI_DIRECT_ERROR_NONE) {
1339                 if (res != WIFI_DIRECT_ERROR_ALREADY_INITIALIZED) {
1340                         DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
1341                         return -1;
1342                 } else {
1343                         DBG(LOG_ERROR, "Already registered\n");
1344                 }
1345         }
1346
1347         res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1348         if (res != WIFI_DIRECT_ERROR_NONE) {
1349                 DBG(LOG_ERROR, "Failed to register _cb_activation. error code = [%d]\n", res);
1350                 return -1;
1351         }
1352
1353         res = wifi_direct_set_discovery_state_changed_cb(discover_cb, (void *)ugd);
1354         if (res != WIFI_DIRECT_ERROR_NONE) {
1355                 DBG(LOG_ERROR, "Failed to register _cb_discover. error code = [%d]\n", res);
1356                 return -1;
1357         }
1358
1359         res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1360         if (res != WIFI_DIRECT_ERROR_NONE) {
1361                 DBG(LOG_ERROR, "Failed to register _cb_connection. error code = [%d]\n", res);
1362                 return -1;
1363         }
1364
1365         res = wifi_direct_set_client_ip_address_assigned_cb(_ip_assigned_cb, (void *)ugd);
1366         if (res != WIFI_DIRECT_ERROR_NONE) {
1367                 DBG(LOG_ERROR, "Failed to register _ip_assigned_cb. error code = [%d]\n", res);
1368                 return -1;
1369         }
1370
1371         /* update WFD status */
1372         wfd_refresh_wifi_direct_state(ugd);
1373 #ifdef WFD_ON_OFF_GENLIST
1374         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1375                 ugd->wfd_onoff = 1;
1376                 wfd_ug_refresh_on_off_check(ugd);
1377         } else {
1378                 ugd->wfd_onoff = 0;
1379         }
1380 #endif
1381
1382         DBG(LOG_INFO, "WFD link status. [%d]\n", ugd->wfd_status);
1383         ugd->is_init_ok = TRUE;
1384         wfd_init_ug_by_status(ugd);
1385
1386         __FUNC_EXIT__;
1387         return 0;
1388 }
1389
1390 void wfd_client_destroy_tethering(struct ug_data *ugd)
1391 {
1392         __FUNC_ENTER__;
1393
1394         tethering_error_e ret = TETHERING_ERROR_NONE;
1395
1396         if (ugd->hotspot_handle != NULL) {
1397                 /* Deregister cbs */
1398                 ret = tethering_unset_enabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1399                 if (ret != TETHERING_ERROR_NONE)
1400                         DBG(LOG_ERROR, "tethering_unset_enabled_cb is failed(%d)\n", ret);
1401
1402                 ret = tethering_unset_disabled_cb(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1403                 if (ret != TETHERING_ERROR_NONE)
1404                         DBG(LOG_ERROR, "tethering_unset_disabled_cb is failed(%d)\n", ret);
1405
1406                 /* Destroy tethering handle */
1407                 ret = tethering_destroy(ugd->hotspot_handle);
1408                 if (ret != TETHERING_ERROR_NONE)
1409                         DBG(LOG_ERROR, "tethering_destroy is failed(%d)\n", ret);
1410
1411                 ugd->hotspot_handle = NULL;
1412         }
1413
1414         __FUNC_EXIT__;
1415 }
1416
1417 /**
1418  *      This function let the ug do de-initialization
1419  *      @return   If success, return 0, else return -1
1420  *      @param[in] data the pointer to the main data structure
1421  */
1422 int deinit_wfd_client(void *data)
1423 {
1424         __FUNC_ENTER__;
1425         struct ug_data *ugd = (struct ug_data *)data;
1426         int res = 0;
1427
1428         wfd_refresh_wifi_direct_state(ugd);
1429
1430         if ((WIFI_DIRECT_STATE_DISCOVERING == ugd->wfd_status) &&
1431                 (WIFI_DIRECT_ERROR_NONE != wifi_direct_cancel_discovery())) {
1432                 DBG(LOG_ERROR, "Failed to send cancel discovery state [%d]\n", ugd->wfd_status);
1433         }
1434
1435         wfd_cancel_progressbar_stop_timer(ugd);
1436         wfd_cancel_not_alive_delete_timer(ugd);
1437
1438         if (ugd->timer_multi_reset > 0)
1439                 g_source_remove(ugd->timer_multi_reset);
1440
1441         ugd->timer_multi_reset = 0;
1442
1443         if (ugd->g_source_multi_connect_next > 0)
1444                 g_source_remove(ugd->g_source_multi_connect_next);
1445
1446         ugd->g_source_multi_connect_next = 0;
1447
1448         res = wifi_direct_unset_discovery_state_changed_cb();
1449         if (res != WIFI_DIRECT_ERROR_NONE)
1450                 DBG(LOG_ERROR, "Failed to unset discovery state changed cb. [%d]\n", res);
1451
1452         wifi_direct_unset_device_state_changed_cb();
1453         if (res != WIFI_DIRECT_ERROR_NONE)
1454                 DBG(LOG_ERROR, "Failed to unset device state changed cb. [%d]\n", res);
1455
1456         wifi_direct_unset_connection_state_changed_cb();
1457         if (res != WIFI_DIRECT_ERROR_NONE)
1458                 DBG(LOG_ERROR, "Failed to unset connection state changed cb. [%d]\n", res);
1459
1460         wifi_direct_unset_client_ip_address_assigned_cb();
1461         if (res != WIFI_DIRECT_ERROR_NONE)
1462                 DBG(LOG_ERROR, "Failed to unset client ip address assigned cb. [%d]\n", res);
1463
1464         if (ugd->wfd_status == WIFI_DIRECT_STATE_CONNECTING &&
1465                 NULL != ugd->mac_addr_connecting) {
1466                 if (ugd->is_conn_incoming) {
1467                         DBG(LOG_INFO, "Reject the incoming connection before client deregister \n");
1468                         res = wifi_direct_reject_connection(ugd->mac_addr_connecting);
1469                         if (res != WIFI_DIRECT_ERROR_NONE)
1470                                 DBG(LOG_ERROR, "Failed to send reject request [%d]\n", res);
1471                 } else {
1472                         DBG(LOG_INFO, "Cancel the outgoing connection before client deregister \n");
1473                         res = wifi_direct_cancel_connection(ugd->mac_addr_connecting);
1474                         if (res != WIFI_DIRECT_ERROR_NONE)
1475                                 DBG(LOG_ERROR, "Failed to send cancel request [%d]\n", res);
1476                 }
1477                 ugd->mac_addr_connecting = NULL;
1478         }
1479
1480
1481         res = wifi_direct_deinitialize();
1482         if (res != WIFI_DIRECT_ERROR_NONE)
1483                 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
1484
1485         /* release vconf, hotspot..  */
1486 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1487         res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1488         if (res == -1)
1489                 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
1490
1491         res = net_deregister_client();
1492         if (res != NET_ERR_NONE)
1493                 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
1494
1495 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1496
1497
1498         wfd_client_destroy_tethering(ugd);
1499
1500         __FUNC_EXIT__;
1501         return 0;
1502 }
1503
1504 /**
1505  *      This function let the ug turn wi-fi direct on
1506  *      @return   If success, return 0, else return -1
1507  *      @param[in] data the pointer to the main data structure
1508  */
1509 int wfd_client_switch_on(void *data)
1510 {
1511         __FUNC_ENTER__;
1512         struct ug_data *ugd = (struct ug_data *)data;
1513         int res;
1514
1515         bool is_wifi_enabled = false;
1516
1517         if (!ugd->is_init_ok) {
1518                 DBG(LOG_ERROR, "device is initializing, please wait\n");
1519                 return -1;
1520         }
1521
1522         wfd_refresh_wifi_direct_state(ugd);
1523         DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1524
1525         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1526
1527 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1528                 int wifi_state;
1529                 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1530                 if (res != 0) {
1531                         DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
1532                         return -1;
1533                 }
1534 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1535
1536                 ugd->hotspot_handle = NULL;
1537                 res = tethering_create(&(ugd->hotspot_handle));
1538                 if (res != TETHERING_ERROR_NONE) {
1539                         DBG(LOG_ERROR, "Failed to tethering_create() [%d]\n", res);
1540                         return -1;
1541                 } else {
1542                         DBG(LOG_INFO, "Succeeded to tethering_create()\n");
1543                 }
1544
1545                 is_wifi_enabled = tethering_is_enabled(ugd->hotspot_handle, TETHERING_TYPE_WIFI);
1546
1547 #ifndef MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE
1548                 if (wifi_state > VCONFKEY_WIFI_OFF) {
1549                         DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1550                         wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_CONNECTION_CONTINUE_Q"), POPUP_TYPE_WIFI_OFF);
1551                 } else
1552 #endif /* MODEL_BUILD_FEATURE_WLAN_CONCURRENT_MODE */
1553
1554                 if (is_wifi_enabled) {
1555                         DBG(LOG_INFO, "WiFi is connected, so have to turn off WiFi");
1556                         wfd_ug_act_popup(ugd, D_("IDS_WIFI_BODY_USING_WI_FI_DIRECT_WILL_DISCONNECT_CURRENT_WI_FI_TETHERING_CONTINUE_Q"), POPUP_TYPE_HOTSPOT_OFF);
1557                 } else {
1558                         res = wifi_direct_activate();
1559                         if (res != WIFI_DIRECT_ERROR_NONE) {
1560                                 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1561                                 wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1562 #ifdef WFD_ON_OFF_GENLIST
1563                                 wfd_ug_refresh_on_off_check(ugd);
1564 #endif
1565                                 return -1;
1566                         }
1567
1568 #ifdef WFD_ON_OFF_GENLIST
1569                         if (ugd->on_off_check) {
1570                                 elm_check_state_set(ugd->on_off_check, TRUE);
1571                                 elm_object_disabled_set(ugd->on_off_check, TRUE);
1572                         }
1573 #endif
1574                         /* while activating, disable the buttons */
1575                         if (ugd->scan_toolbar == NULL)
1576                                 scan_button_create(ugd);
1577
1578                         if (ugd->scan_toolbar)
1579                                 wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1580
1581                         if (ugd->multiconn_scan_stop_btn)
1582                                 wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1583
1584                         if (ugd->back_btn)
1585                                 elm_object_disabled_set(ugd->back_btn, TRUE);
1586                 }
1587         } else {
1588                 DBG(LOG_INFO, "Wi-Fi Direct is already activated\n");
1589         }
1590
1591         __FUNC_EXIT__;
1592         return 0;
1593 }
1594
1595 /**
1596  *      This function let the ug turn wi-fi direct off
1597  *      @return   If success, return 0, else return -1
1598  *      @param[in] data the pointer to the main data structure
1599  */
1600 int wfd_client_switch_off(void *data)
1601 {
1602         __FUNC_ENTER__;
1603         struct ug_data *ugd = (struct ug_data *)data;
1604         int res;
1605
1606         wfd_ug_view_free_peers(ugd);
1607         wfd_free_nodivice_item(ugd);
1608
1609         wfd_refresh_wifi_direct_state(ugd);
1610         DBG(LOG_INFO, "WFD status [%d]\n", ugd->wfd_status);
1611
1612         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1613                 DBG(LOG_INFO, "Wi-Fi Direct is already deactivated\n");
1614         } else {
1615
1616                 wfd_client_destroy_tethering(ugd);
1617
1618                 wfd_cancel_progressbar_stop_timer(ugd);
1619                 wfd_cancel_not_alive_delete_timer(ugd);
1620
1621                 if (ugd->timer_multi_reset > 0)
1622                         g_source_remove(ugd->timer_multi_reset);
1623
1624                 ugd->timer_multi_reset = 0;
1625
1626                 if (ugd->g_source_multi_connect_next > 0)
1627                         g_source_remove(ugd->g_source_multi_connect_next);
1628
1629                 ugd->g_source_multi_connect_next = 0;
1630
1631                 /*if connected, disconnect all devices*/
1632                 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1633                         res = wifi_direct_disconnect_all();
1634                         if (res != WIFI_DIRECT_ERROR_NONE) {
1635                                 DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1636                                 return -1;
1637                         }
1638                 }
1639
1640                 res = wifi_direct_deactivate();
1641                 if (res != WIFI_DIRECT_ERROR_NONE) {
1642                         DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1643                         wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE_DEACTIVATE_FAIL);
1644 #ifdef WFD_ON_OFF_GENLIST
1645                         wfd_ug_refresh_on_off_check(ugd);
1646 #endif
1647                         return -1;
1648                 }
1649
1650                 /* while deactivating, disable the buttons */
1651                 if (ugd->scan_toolbar) {
1652                         wfd_ug_view_refresh_button(ugd->scan_toolbar, "IDS_WIFI_SK4_SCAN", FALSE);
1653                         evas_object_del(ugd->scan_toolbar);
1654                         ugd->scan_toolbar = NULL;
1655                 }
1656
1657                 if (ugd->multiconn_scan_stop_btn)
1658                         wfd_ug_view_refresh_button(ugd->multiconn_scan_stop_btn, "IDS_WIFI_SK4_SCAN", FALSE);
1659
1660                 if (ugd->multi_connect_toolbar_item)
1661                         elm_object_item_disabled_set(ugd->multi_connect_toolbar_item, TRUE);
1662
1663                 if (ugd->back_btn)
1664                         elm_object_disabled_set(ugd->back_btn, TRUE);
1665         }
1666
1667         __FUNC_EXIT__;
1668         return 0;
1669 }
1670
1671 #ifdef WFD_ON_OFF_GENLIST
1672 /**
1673  *      This function let the ug turn wi-fi direct on/off forcely
1674  *      @return   If success, return 0, else return -1
1675  *      @param[in] data the pointer to the main data structure
1676   *     @param[in] onoff whether to turn on/off wi-fi direct
1677  */
1678 int wfd_client_swtch_force(void *data, int onoff)
1679 {
1680         __FUNC_ENTER__;
1681         struct ug_data *ugd = (struct ug_data *)data;
1682         int res;
1683
1684         if (onoff) {
1685                 res = wifi_direct_activate();
1686                 if (res != WIFI_DIRECT_ERROR_NONE) {
1687                         DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1688                         wfd_ug_warn_popup(ugd, D_("IDS_COM_POP_FAILED"), POPUP_TYPE_TERMINATE);
1689                         wfd_ug_refresh_on_off_check(ugd);
1690                         return -1;
1691                 }
1692         } else {
1693                 res = wifi_direct_deactivate();
1694                 if (res != WIFI_DIRECT_ERROR_NONE) {
1695                         DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1696                         wfd_ug_warn_popup(ugd, D_("IDS_WIFI_POP_DEACTIVATION_FAILED"), POPUP_TYPE_TERMINATE);
1697                         wfd_ug_refresh_on_off_check(ugd);
1698                         return -1;
1699                 }
1700         }
1701
1702         __FUNC_EXIT__;
1703         return 0;
1704 }
1705 #endif
1706
1707 /**
1708  *      This function let the ug create a group
1709  *      @return   If success, return 0, else return -1
1710  */
1711 int wfd_client_group_add()
1712 {
1713         __FUNC_ENTER__;
1714         int res;
1715
1716         res = wifi_direct_create_group();
1717         if (res != WIFI_DIRECT_ERROR_NONE) {
1718                 DBG(LOG_ERROR, "Failed to add group");
1719                 __FUNC_EXIT__;
1720                 return -1;
1721         }
1722
1723         __FUNC_EXIT__;
1724         return 0;
1725 }
1726
1727 /**
1728  *      This function let the ug connect to the device by mac address
1729  *      @return   If success, return 0, else return -1
1730  *      @param[in] mac_addr the pointer to the mac address of device
1731  */
1732 int wfd_client_connect(const char *mac_addr)
1733 {
1734         __FUNC_ENTER__;
1735         int res;
1736
1737         DBG_SECURE(LOG_INFO, "connect to peer=["MACSECSTR"]\n", MAC2SECSTR(mac_addr));
1738         res = wifi_direct_connect((char *)mac_addr);
1739         if (res != WIFI_DIRECT_ERROR_NONE) {
1740                 DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
1741                 return -1;
1742         }
1743
1744         __FUNC_EXIT__;
1745         return 0;
1746 }
1747
1748 /**
1749  *      This function let the ug disconnect to the device by mac address
1750  *      @return   If success, return 0, else return -1
1751  *      @param[in] mac_addr the pointer to the mac address of device
1752  */
1753 int wfd_client_disconnect(const char *mac_addr)
1754 {
1755         __FUNC_ENTER__;
1756         int res;
1757
1758         wifi_direct_cancel_discovery();
1759         /*
1760          * No need to handle return in cancel discovery as there maybe case
1761          * when framework can return failure.
1762          */
1763
1764         if (mac_addr == NULL) {
1765                 res = wifi_direct_disconnect_all();
1766                 if (res != WIFI_DIRECT_ERROR_NONE) {
1767                         DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
1768                         return -1;
1769                 }
1770         } else {
1771                 res = wifi_direct_disconnect((char *)mac_addr);
1772                 if (res != WIFI_DIRECT_ERROR_NONE) {
1773                         DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
1774                         return -1;
1775                 }
1776         }
1777
1778         __FUNC_EXIT__;
1779         return 0;
1780 }
1781
1782 /**
1783  *      This function let the ug set the intent of a group owner
1784  *      @return   If success, return 0, else return -1
1785  *      @param[in] go_intent the intent parameter
1786  */
1787 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1788 {
1789         __FUNC_ENTER__;
1790         int res;
1791
1792         res = wifi_direct_set_group_owner_intent(go_intent);
1793         if (res != WIFI_DIRECT_ERROR_NONE) {
1794                 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);
1795                 return -1;
1796         }
1797
1798         __FUNC_EXIT__;
1799         return 0;
1800 }