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