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