License site changed
[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://floralicense.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 <pmapi.h>
26 #include <vconf.h>
27 //#include <vconf-keys.h>
28 #include <tethering.h>
29 #include <network-cm-intf.h>
30 #include <network-wifi-intf.h>
31
32 #include "wfd_ug.h"
33 #include "wfd_ug_view.h"
34 #include "wfd_client.h"
35
36 /**
37  *      This function let the ug make a change callback for wifi state
38  *      @return   void
39  *      @param[in] key the pointer to the key
40  *      @param[in] data the pointer to the main data structure
41  */
42 static void _wifi_state_cb(keynode_t *key, void *data)
43 {
44         __WDUG_LOG_FUNC_ENTER__;
45         struct ug_data *ugd = (struct ug_data *)data;
46         int res;
47         int wifi_state;
48
49         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
50         if (res != 0) {
51                 WDUG_LOGE("Failed to get wifi state from vconf. [%d]\n", res);
52                 return;
53         }
54
55         if (wifi_state == VCONFKEY_WIFI_OFF) {
56                 WDUG_LOGI("WiFi is turned off\n");
57                 wfd_client_swtch_force(ugd, TRUE);
58         } else {
59                 WDUG_LOGI("WiFi is turned on\n");
60         }
61
62         res = net_deregister_client();
63         if (res != NET_ERR_NONE) {
64                 WDUG_LOGE("Failed to deregister network client. [%d]\n", res);
65         }
66
67         __WDUG_LOG_FUNC_EXIT__;
68 }
69
70 /**
71  *      This function let the ug make a event callback for network registering
72  *      @return   void
73  *      @param[in] event_info the pointer to the information of network event
74  *      @param[in] user_data the pointer to the user data
75  */
76 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
77 {
78         __WDUG_LOG_FUNC_ENTER__;
79         WDUG_LOGI("Event from network. [%d]\n", event_info->Event);
80         __WDUG_LOG_FUNC_EXIT__;
81 }
82
83 /**
84  *      This function let the ug turn wifi off
85  *      @return   If success, return 0, else return -1
86  *      @param[in] data the pointer to the main data structure
87  */
88 int wfd_wifi_off(void *data)
89 {
90         __WDUG_LOG_FUNC_ENTER__;
91         struct ug_data *ugd = (struct ug_data *)data;
92         int res;
93
94         res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
95         if (res == -1) {
96                 WDUG_LOGE("Failed to register vconf callback\n");
97                 return -1;
98         }
99
100         WDUG_LOGI("Vconf key callback is registered\n");
101
102         res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
103         if (res != NET_ERR_NONE) {
104                 WDUG_LOGE("Failed to register network client. [%d]\n", res);
105                 return -1;
106         }
107
108         WDUG_LOGI("Network client is registered\n");
109
110         res = net_wifi_power_off();
111         if (res != NET_ERR_NONE) {
112                 WDUG_LOGE("Failed to turn off wifi. [%d]\n", res);
113                 return -1;
114         }
115
116         WDUG_LOGI("WiFi power off\n");
117
118         __WDUG_LOG_FUNC_EXIT__;
119         return 0;
120 }
121
122 /**
123  *      This function let the ug make a change callback for enabling hotspot state
124  *      @return   void
125  *      @param[in] key the pointer to the key
126  *      @param[in] data the pointer to the main data structure
127  */
128 static void _enable_hotspot_state_cb(keynode_t *key, void *data)
129 {
130         __WDUG_LOG_FUNC_ENTER__;
131         struct ug_data *ugd = (struct ug_data *)data;
132         int res;
133         int hotspot_mode;
134         tethering_error_e ret = TETHERING_ERROR_NONE;
135         tethering_h th = NULL;
136
137         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
138         if (res != 0) {
139                 WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res);
140                 return;
141         }
142
143         if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
144                 WDUG_LOGI(" Mobile hotspot is activated\n");
145         }
146
147         th = ugd->hotspot_handle;
148
149         if (th != NULL) {
150                 /* Deregister cbs */
151                 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
152                 if (ret != TETHERING_ERROR_NONE) {
153                         WDUG_LOGE("tethering_unset_enabled_cb is failed(%d)\n", ret);
154                 }
155
156                 /* Destroy tethering handle */
157                 ret = tethering_destroy(th);
158                 if (ret != TETHERING_ERROR_NONE) {
159                         WDUG_LOGE("tethering_destroy is failed(%d)\n", ret);
160                 }
161
162                 ugd->hotspot_handle = NULL;
163         }
164
165         __WDUG_LOG_FUNC_EXIT__;
166 }
167
168 /**
169  *      This function let the ug make a change callback for disabling hotspot state
170  *      @return   void
171  *      @param[in] key the pointer to the key
172  *      @param[in] data the pointer to the main data structure
173  */
174 static void _disable_hotspot_state_cb(keynode_t *key, void *data)
175 {
176         __WDUG_LOG_FUNC_ENTER__;
177         struct ug_data *ugd = (struct ug_data *)data;
178         int res;
179         int hotspot_mode;
180         tethering_error_e ret = TETHERING_ERROR_NONE;
181         tethering_h th = NULL;
182
183         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
184         if (res != 0) {
185                 WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res);
186                 return;
187         }
188
189         if (!(hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)) {
190                 WDUG_LOGI(" Mobile hotspot is deactivated\n");
191                 wfd_client_swtch_force(ugd, TRUE);
192         }
193
194         th = ugd->hotspot_handle;
195
196         if (th != NULL) {
197                 /* Deregister cbs */
198                 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
199                 if (ret != TETHERING_ERROR_NONE) {
200                         WDUG_LOGE("tethering_unset_disabled_cb is failed(%d)\n", ret);
201                 }
202
203                 /* Destroy tethering handle */
204                 ret = tethering_destroy(th);
205                 if (ret != TETHERING_ERROR_NONE) {
206                         WDUG_LOGE("tethering_destroy is failed(%d)\n", ret);
207                 }
208
209                 ugd->hotspot_handle = NULL;
210         }
211
212         __WDUG_LOG_FUNC_EXIT__;
213 }
214
215 /**
216  *      This function let the ug make a callback for setting tethering mode enabled
217  *      @return   void
218  *      @param[in] error the returned error code
219  *      @param[in] type the type of tethering
220  *      @param[in] is_requested whether tethering mode is enabled
221  *      @param[in] data the pointer to the user data
222  */
223 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
224 {
225         __WDUG_LOG_FUNC_ENTER__;
226
227         if (error != TETHERING_ERROR_NONE) {
228                 if (is_requested != TRUE) {
229                         return;
230                 }
231
232                 WDUG_LOGE("error !!! TETHERING is not enabled.\n");
233                 return;
234         }
235
236         WDUG_LOGI("TETHERING is enabled.\n");
237
238         __WDUG_LOG_FUNC_EXIT__;
239         return;
240 }
241
242 /**
243  *      This function let the ug make a callback for setting tethering mode disabled
244  *      @return   void
245  *      @param[in] error the returned error code
246  *      @param[in] type the type of tethering
247  *      @param[in] code whether tethering mode is enabled
248  *      @param[in] data the pointer to the user data
249  */
250 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
251 {
252         __WDUG_LOG_FUNC_ENTER__;
253
254         if (error != TETHERING_ERROR_NONE) {
255                 if (code != TETHERING_DISABLED_BY_REQUEST) {
256                         return;
257                 }
258
259                 WDUG_LOGE("error !!! TETHERING is not disabled.\n");
260                 return;
261         }
262
263         WDUG_LOGI("TETHERING is disabled.\n");
264
265         __WDUG_LOG_FUNC_EXIT__;
266         return;
267 }
268
269 /**
270  *      This function let the ug turn AP on
271  *      @return   If success, return 0, else return -1
272  *      @param[in] data the pointer to the main data structure
273  */
274 int wfd_mobile_ap_on(void *data)
275 {
276         __WDUG_LOG_FUNC_ENTER__;
277         struct ug_data *ugd = (struct ug_data *)data;
278         int res;
279         tethering_error_e ret = TETHERING_ERROR_NONE;
280         tethering_h th = NULL;
281
282         res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb, ugd);
283         if (res == -1) {
284                 WDUG_LOGE("Failed to register vconf callback\n");
285                 return -1;
286         }
287
288         /* Create tethering handle */
289         ret = tethering_create(&th);
290         if (ret != TETHERING_ERROR_NONE) {
291                 WDUG_LOGE("Failed to tethering_create() [%d]\n", ret);
292                 return -1;
293         } else {
294                 WDUG_LOGI("Succeeded to tethering_create()\n");
295         }
296
297         /* Register cbs */
298         ret = tethering_set_enabled_cb(th, TETHERING_TYPE_WIFI, __enabled_cb, NULL);
299         if (ret != TETHERING_ERROR_NONE) {
300                 WDUG_LOGE("tethering_set_enabled_cb is failed\n", ret);
301                 return -1;
302         }
303
304         /* Enable tethering */
305         ret = tethering_enable(th, TETHERING_TYPE_WIFI);
306         if (ret != TETHERING_ERROR_NONE) {
307                 WDUG_LOGE("Failed to turn on mobile hotspot. [%d]\n", ret);
308                 return -1;
309         } else {
310                 WDUG_LOGI("Succeeded to turn on mobile hotspot\n");
311         }
312
313         ugd->hotspot_handle = th;
314         ugd->is_hotspot_off = FALSE;
315
316         __WDUG_LOG_FUNC_EXIT__;
317         return 0;
318 }
319
320 /**
321  *      This function let the ug turn AP off
322  *      @return   If success, return 0, else return -1
323  *      @param[in] data the pointer to the main data structure
324  */
325 int wfd_mobile_ap_off(void *data)
326 {
327         __WDUG_LOG_FUNC_ENTER__;
328         struct ug_data *ugd = (struct ug_data *)data;
329         int res;
330         tethering_error_e ret = TETHERING_ERROR_NONE;
331         tethering_h th = NULL;
332
333         res = vconf_notify_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb, ugd);
334         if (res == -1) {
335                 WDUG_LOGE("Failed to register vconf callback\n");
336                 return -1;
337         }
338
339         /* Create tethering handle */
340         ret = tethering_create(&th);
341         if (ret != TETHERING_ERROR_NONE) {
342                 WDUG_LOGE("Failed to tethering_create() [%d]\n", ret);
343                 return -1;
344         } else {
345                 WDUG_LOGI("Succeeded to tethering_create()\n");
346         }
347
348         /* Register cbs */
349         ret = tethering_set_disabled_cb(th, TETHERING_TYPE_WIFI, __disabled_cb, NULL);
350         if (ret != TETHERING_ERROR_NONE) {
351                 WDUG_LOGE("tethering_set_disabled_cb is failed\n", ret);
352                 return -1;
353         }
354
355         /* Disable tethering */
356         ret = tethering_disable(th, TETHERING_TYPE_WIFI);
357         if (ret != TETHERING_ERROR_NONE) {
358                 WDUG_LOGE("Failed to turn off mobile hotspot. [%d]\n", ret);
359                 return -1;
360         } else {
361                 WDUG_LOGI("Succeeded to turn off mobile hotspot\n");
362         }
363
364         ugd->hotspot_handle = th;
365         ugd->is_hotspot_off = TRUE;
366
367         __WDUG_LOG_FUNC_EXIT__;
368         return 0;
369 }
370
371 /**
372  *      This function let the ug find the peer by mac address
373  *      @return   the found peer
374  *      @param[in] data the pointer to the main data structure
375  *      @param[in] mac_addr the pointer to mac address
376  */
377 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
378 {
379         __WDUG_LOG_FUNC_ENTER__;
380         struct ug_data *ugd = (struct ug_data *)data;
381         int i;
382
383         if (ugd == NULL) {
384                 WDUG_LOGE("Incorrect parameter(NULL)\n");
385                 return NULL;
386         }
387
388         if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE) {
389                 for (i = 0; i < ugd->raw_multi_selected_peer_cnt; i++) {
390                         WDUG_LOGI("[Multi Connect] check %dth peer\n", i);
391                         if (!strncmp(mac_addr, (const char *)ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH)) {
392                                 WDUG_LOGI("selected found peer. [%d]\n", i);
393                                 __WDUG_LOG_FUNC_EXIT__;
394                                 return &ugd->raw_multi_selected_peers[i];
395                         }
396                 }
397         } else {
398                 for (i = 0; i < ugd->raw_discovered_peer_cnt; i++) {
399                         WDUG_LOGI("check %dth peer\n", i);
400                         if (!strncmp(mac_addr, (const char *)ugd->raw_discovered_peers[i].mac_addr, MAC_LENGTH)) {
401                                 WDUG_LOGI("found peer. [%d]\n", i);
402                                 __WDUG_LOG_FUNC_EXIT__;
403                                 return &ugd->raw_discovered_peers[i];
404                         }
405                 }
406         }
407
408         __WDUG_LOG_FUNC_EXIT__;
409         return NULL;
410 }
411
412 /**
413  *      This function let the ug make a callback for registering activation event
414  *      @return   void
415  *      @param[in] error_code the returned error code
416  *      @param[in] device_state the state of device
417  *      @param[in] user_data the pointer to the main data structure
418  */
419 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
420 {
421         __WDUG_LOG_FUNC_ENTER__;
422         int res = -1;
423         struct ug_data *ugd = (struct ug_data *)user_data;
424
425         wfd_refresh_wifi_direct_state(ugd);
426
427         switch (device_state) {
428         case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
429                 WDUG_LOGI("WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
430                 if (error_code != WIFI_DIRECT_ERROR_NONE) {
431                         WDUG_LOGE("Error in Activation/Deactivation [%d]\n", error_code);
432                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL);
433
434                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
435                         ugd->wfd_onoff = 0;
436                         wfd_ug_view_refresh_glitem(ugd->head);
437                         return;
438                 }
439
440                 ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
441                 ugd->wfd_onoff = 1;
442                 wfd_ug_view_refresh_glitem(ugd->head);
443
444                 wfg_ug_act_popup_remove(ugd);
445
446                 res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
447                 if (res == -1) {
448                         WDUG_LOGE("Failed to ignore vconf key callback for wifi state\n");
449                 }
450
451                 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb);
452                 if (res == -1) {
453                         WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
454                 }
455
456                 res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
457                 if (res != WIFI_DIRECT_ERROR_NONE) {
458                         WDUG_LOGE("Failed to start discovery. [%d]\n", res);
459                         ugd->is_re_discover = TRUE;
460                         wifi_direct_cancel_discovery();
461                 } else {
462                         WDUG_LOGI("Discovery is started\n");
463                         ugd->is_re_discover = FALSE;
464                 }
465
466                 break;
467         case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
468                 WDUG_LOGI("WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
469                 if (error_code != WIFI_DIRECT_ERROR_NONE) {
470                         WDUG_LOGE("Error in Activation/Deactivation [%d]\n", error_code);
471                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL);
472                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
473                         ugd->wfd_onoff = 1;
474                         wfd_ug_view_refresh_glitem(ugd->head);
475                         return;
476                 }
477
478                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
479                 ugd->wfd_onoff = 0;
480
481                 /*
482                 * when deactivated, clear all the
483                 *  discovered peers and connected peers
484                 */
485                 if (ugd->raw_discovered_peer_cnt > 0) {
486                         memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s));
487                 }
488
489                 if (ugd->raw_connected_peer_cnt > 0) {
490                         memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
491                 }
492
493                 ugd->raw_discovered_peer_cnt = 0;
494                 ugd->raw_connected_peer_cnt = 0;
495
496                 wfd_ug_view_update_peers(ugd);
497
498                 /* remove the callback for hotspot */
499                 res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb);
500                 if (res == -1) {
501                         WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
502                 }
503
504                 /* when deactivated, stop the timer */
505                 if (ugd->monitor_timer) {
506                         ecore_timer_del(ugd->monitor_timer);
507                         ugd->monitor_timer = NULL;
508                 }
509                 break;
510         default:
511                 break;
512         }
513
514         wfd_ug_view_refresh_glitem(ugd->head);
515
516         if (ugd->scan_btn) {
517                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
518         }
519
520         if (ugd->multi_connect_btn) {
521                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
522         }
523
524         if (ugd->back_btn) {
525                 elm_object_disabled_set(ugd->back_btn, FALSE);
526         }
527
528         __WDUG_LOG_FUNC_EXIT__;
529         return;
530 }
531
532 /**
533  *      This function let the ug make a callback for discovering peer
534  *      @return   TRUE
535  *      @param[in] peer the pointer to the discovered peer
536  *      @param[in] user_data the pointer to the main data structure
537  */
538 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
539 {
540         __WDUG_LOG_FUNC_ENTER__;
541         if (NULL == peer || NULL == user_data) {
542                 WDUG_LOGE("Incorrect parameter(NULL)\n");
543                 __WDUG_LOG_FUNC_EXIT__;
544                 return FALSE;
545         }
546
547         struct ug_data *ugd = (struct ug_data *)user_data;
548         int peer_cnt = ugd->raw_discovered_peer_cnt;
549
550         WDUG_LOGI("%dth discovered peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address);
551
552         strncpy(ugd->raw_discovered_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_discovered_peers[peer_cnt].ssid));
553         ugd->raw_discovered_peers[peer_cnt].category = peer->primary_device_type;
554         strncpy(ugd->raw_discovered_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
555         strncpy(ugd->raw_discovered_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
556         ugd->raw_discovered_peers[peer_cnt].is_group_owner = peer->is_group_owner;
557         ugd->raw_discovered_peers[peer_cnt].is_persistent_group_owner = peer->is_persistent_group_owner;
558         ugd->raw_discovered_peers[peer_cnt].is_connected = peer->is_connected;
559
560         if (TRUE == peer->is_connected) {
561                 ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
562         } else {
563                 ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED;
564         }
565
566         WDUG_LOGI("\tSSID: [%s]\n", ugd->raw_discovered_peers[peer_cnt].ssid);
567         WDUG_LOGI("\tPeer category [%d] -> [%d]\n", peer->primary_device_type, ugd->raw_discovered_peers[peer_cnt].category);
568         WDUG_LOGI("\tStatus: [%d]\n", ugd->raw_discovered_peers[peer_cnt].conn_status);
569
570         ugd->raw_discovered_peer_cnt++;
571
572         free(peer->device_name);
573         free(peer->mac_address);
574         free(peer->interface_address);
575         free(peer);
576
577         __WDUG_LOG_FUNC_EXIT__;
578         return TRUE;
579 }
580
581 /**
582  *      This function let the ug make a callback for connected peer
583  *      @return   TRUE
584  *      @param[in] peer the pointer to the connected peer
585  *      @param[in] user_data the pointer to the main data structure
586  */
587 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
588 {
589         __WDUG_LOG_FUNC_ENTER__;
590         if (NULL == peer || NULL == user_data) {
591                 WDUG_LOGE("Incorrect parameter(NULL)\n");
592                 __WDUG_LOG_FUNC_EXIT__;
593                 return FALSE;
594         }
595
596         struct ug_data *ugd = (struct ug_data *)user_data;
597         int peer_cnt = ugd->raw_connected_peer_cnt;
598
599         WDUG_LOGI("%dth connected peer. [%s] [%s]\n", peer_cnt, peer->device_name, peer->mac_address);
600
601         strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ugd->raw_connected_peers[peer_cnt].ssid));
602         ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
603         strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
604         strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
605         ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
606
607         WDUG_LOGI("\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
608         WDUG_LOGI("\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
609         WDUG_LOGI("\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
610         WDUG_LOGI("\tMAC addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].mac_addr);
611         WDUG_LOGI("\tIface addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].if_addr);
612
613         ugd->raw_connected_peer_cnt++;
614
615         free(peer->device_name);
616         free(peer->mac_address);
617         free(peer->interface_address);
618         free(peer);
619
620         __WDUG_LOG_FUNC_EXIT__;
621         return TRUE;
622 }
623
624 /**
625  *      This function let the ug get the found peers
626  *      @return   If success, return 0, else return -1
627  *      @param[in] ugd the pointer to the main data structure
628  */
629 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
630 {
631         __WDUG_LOG_FUNC_ENTER__;
632         int res = 0;
633
634         if (ugd == NULL) {
635                 return -1;
636         }
637
638         ugd->raw_discovered_peer_cnt = 0;
639         res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
640         if (res != WIFI_DIRECT_ERROR_NONE) {
641                 ugd->raw_discovered_peer_cnt = 0;
642                 WDUG_LOGE("Get discovery result failed: %d\n", res);
643         }
644
645         __WDUG_LOG_FUNC_EXIT__;
646         return 0;
647 }
648
649 /**
650  *      This function let the ug get the connected peers
651  *      @return   If success, return 0, else return -1
652  *      @param[in] ugd the pointer to the main data structure
653  */
654 int wfd_ug_get_connected_peers(struct ug_data *ugd)
655 {
656         __WDUG_LOG_FUNC_ENTER__;
657         int res = 0;
658
659         if (ugd == NULL) {
660                 return -1;
661         }
662
663         ugd->raw_connected_peer_cnt = 0;
664         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
665         if (res != WIFI_DIRECT_ERROR_NONE) {
666                 ugd->raw_connected_peer_cnt = 0;
667                 WDUG_LOGE("Get connected peer failed: %d\n", res);
668         }
669
670         __WDUG_LOG_FUNC_EXIT__;
671         return 0;
672 }
673
674 /**
675  *      This function let the ug make a callback for deactivating wfd automatically
676  *      @return   if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
677  *      @param[in] user_data the pointer to the main data structure
678  */
679 static Eina_Bool _wfd_automatic_deactivated_for_no_connection_cb(void *user_data)
680 {
681         int res = -1;
682         int interval = 0;
683         struct ug_data *ugd = (struct ug_data *)user_data;
684
685         if (NULL == ugd) {
686                 WDUG_LOGE("NULL parameters.\n");
687                 return ECORE_CALLBACK_CANCEL;
688         }
689
690         /* check the action, if action is exist, keep the cb */
691         res = wifi_direct_get_state(&ugd->wfd_status);
692         if (res != WIFI_DIRECT_ERROR_NONE) {
693                 WDUG_LOGE("Failed to get link status. [%d]\n", res);
694                 return ECORE_CALLBACK_CANCEL;
695         }
696
697         if (ugd->last_wfd_status != ugd->wfd_status) {
698                 WDUG_LOGE("Action is exist, last status: %d\n",
699                         ugd->last_wfd_status);
700                 ugd->last_wfd_status = ugd->wfd_status;
701                 ugd->last_wfd_time = time(NULL);
702                 return ECORE_CALLBACK_RENEW;
703         }
704
705         /* check the timeout, if not timeout, keep the cb */
706         interval = time(NULL) - ugd->last_wfd_time;
707         if (interval < MAX_NO_ACTION_TIME_OUT) {
708                 return ECORE_CALLBACK_RENEW;
709         }
710
711         /* turn off the Wi-Fi Direct */
712         wifi_direct_get_state(&ugd->wfd_status);
713         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
714                 WDUG_LOGE("Wi-Fi Direct is already deactivated\n");
715         } else {
716                 wfd_ug_warn_popup(ugd, IDS_WFD_POP_AUTOMATIC_TURN_OFF, POP_TYPE_AUTOMATIC_TURN_OFF);
717         }
718
719         return ECORE_CALLBACK_CANCEL;
720 }
721
722 /**
723  *      This function let the ug make a callback for registering discover event
724  *      @return   void
725  *      @param[in] error_code the returned error code
726  *      @param[in] discovery_state the state of discover
727  *      @param[in] user_data the pointer to the main data structure
728  */
729 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
730 {
731         __WDUG_LOG_FUNC_ENTER__;
732         struct ug_data *ugd = (struct ug_data *)user_data;
733
734         if (ugd == NULL) {
735                 WDUG_LOGE("Incorrect parameter(NULL)\n");
736                 return;
737         }
738
739         WDUG_LOGI("Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
740
741         if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED) {
742                 __WDUG_LOG_FUNC_EXIT__;
743                 return;
744         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
745                 ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
746
747                 /* clear all the previous discovered peers */
748                 if (ugd->raw_discovered_peer_cnt > 0) {
749                         memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s));
750                 }
751
752                 ugd->raw_discovered_peer_cnt = 0;
753         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
754                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
755                 wfd_ug_get_discovered_peers(ugd);
756         } else {
757                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
758
759                 if (TRUE == ugd->is_re_discover) {
760                         ugd->is_re_discover = FALSE;
761                         wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
762                 } else {
763                         /* start LISTEN ONLY mode */
764                         wifi_direct_start_discovery(TRUE, 0);
765                 }
766         }
767
768         wfd_ug_view_refresh_glitem(ugd->head);
769         wfd_ug_view_update_peers(ugd);
770         wfd_update_multiconnect_device(ugd);
771
772         if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state) {
773                 if (ugd->scan_btn) {
774                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
775                 }
776
777                 if (ugd->multi_connect_btn) {
778                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
779                 }
780         } else {
781                 if (ugd->scan_btn) {
782                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
783                 }
784
785                 if (ugd->multi_connect_btn) {
786                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
787                 }
788         }
789
790         __WDUG_LOG_FUNC_EXIT__;
791         return;
792 }
793
794 /**
795  *      This function let the ug make a callback for registering connection event
796  *      @return   void
797  *      @param[in] error_code the returned error code
798  *      @param[in] connection_state the state of connection
799  *      @param[in] mac_address the mac address of peer
800  *      @param[in] user_data the pointer to the main data structure
801  */
802 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
803 {
804         __WDUG_LOG_FUNC_ENTER__;
805         struct ug_data *ugd = (struct ug_data *)user_data;
806         device_type_s *peer = NULL;
807         bool owner = FALSE;
808         int res = 0;
809
810         WDUG_LOGI("Connection event [%d], error_code [%d], multi_connect_mode [%d]\n",
811                 connection_state, error_code, ugd->multi_connect_mode);
812
813         if (mac_address == NULL) {
814                 WDUG_LOGE("Incorrect parameter(peer mac is NULL)\n");
815                 return;
816         }
817
818         /* when not in connection, mac_address is empty */
819         if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
820                 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
821
822                 if (NULL == peer || '\0' == peer->ssid[0]) {
823                         WDUG_LOGE("invalid peer from connection !!\n");
824                         goto refresh_button;
825                 }
826         }
827
828         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
829                 switch (connection_state) {
830                 case WIFI_DIRECT_CONNECTION_RSP:
831                         WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
832
833                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
834                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
835                                 wfd_ug_get_connected_peers(ugd);
836                         } else {
837                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
838                         }
839
840                         wfd_ug_view_update_peers(ugd);
841
842                         /* connect the next peer */
843                         ugd->g_source_multi_connect_next = g_timeout_add(1000, wfd_multi_connect_next_cb, ugd);
844                         break;
845                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
846                         WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
847                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
848                         wfd_ug_view_update_peers(ugd);
849                         break;
850                 case WIFI_DIRECT_GROUP_CREATED:
851                         WDUG_LOGI("MULTI: WIFI_DIRECT_GROUP_CREATED\n");
852                         wfd_multi_connect_next_cb(ugd);
853                         break;
854                 default:
855                         break;
856                 }
857         } else {
858                 switch (connection_state) {
859                 case WIFI_DIRECT_CONNECTION_RSP:
860                         WDUG_LOGI("WIFI_DIRECT_CONNECTION_RSP\n");
861
862                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
863                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
864                                 wfd_ug_get_connected_peers(ugd);
865                         } else {
866                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
867                         }
868
869                         wfd_ug_view_update_peers(ugd);
870                         break;
871                 case WIFI_DIRECT_DISASSOCIATION_IND:
872                         WDUG_LOGI("WIFI_DIRECT_DISASSOCIATION_IND\n");
873                         /* change the multi connection mode, it can be connected now */
874                         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
875                                 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS;
876                         }
877
878                         /* if other peer disconnected, get connected peers and update */
879                         peer->conn_status = PEER_CONN_STATUS_WAIT_FOR_CONNECT;
880                         wfd_ug_get_connected_peers(ugd);
881                         wfd_ug_view_update_peers(ugd);
882                         break;
883                 case WIFI_DIRECT_DISCONNECTION_RSP:
884                 case WIFI_DIRECT_DISCONNECTION_IND:
885                         WDUG_LOGI("WIFI_DIRECT_DISCONNECTION_X\n");
886
887                         /* when disconnection, clear all the connected peers */
888                         if (ugd->raw_connected_peer_cnt > 0) {
889                                 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
890                         }
891
892                         ugd->raw_connected_peer_cnt = 0;
893
894                         /* start discovery again */
895                         res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
896                         if (res != WIFI_DIRECT_ERROR_NONE) {
897                                 WDUG_LOGE("Failed to start discovery. [%d]\n", res);
898                                 ugd->is_re_discover = TRUE;
899                                 wifi_direct_cancel_discovery();
900                         } else {
901                                 WDUG_LOGI("Discovery is started\n");
902                                 ugd->is_re_discover = FALSE;
903                         }
904
905                         break;
906                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
907                         WDUG_LOGI("WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
908                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
909                         wfd_ug_view_update_peers(ugd);
910                         break;
911                 case WIFI_DIRECT_CONNECTION_REQ:
912                 case WIFI_DIRECT_CONNECTION_WPS_REQ:
913                         WDUG_LOGI("WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
914                         break;
915                 default:
916                         break;
917                 }
918         }
919
920         if (peer != NULL) {
921                 wfd_ug_view_refresh_glitem(peer->gl_item);
922         }
923
924         _change_multi_button_title(ugd);
925
926 refresh_button:
927         /* refresh the scan button */
928         wfd_refresh_wifi_direct_state(ugd);
929         if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
930                 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
931                 res = wifi_direct_is_group_owner(&owner);
932                 if (res == WIFI_DIRECT_ERROR_NONE) {
933                         if (!owner) {
934                                 if (ugd->scan_btn) {
935                                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
936                                 }
937
938                                 if (ugd->multi_connect_btn) {
939                                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
940                                 }
941                         }
942                 } else {
943                     WDUG_LOGE("Failed to get whether client is group owner. [%d]\n", res);
944                 }
945         } else {
946                 if (ugd->scan_btn) {
947                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
948                 }
949
950                 if (ugd->multi_connect_btn) {
951                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
952                 }
953         }
954
955         /* if no connection, start the monitor timer */
956         wifi_direct_get_state(&ugd->wfd_status);
957         WDUG_LOGI("status: %d", ugd->wfd_status);
958
959         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
960                 if (ugd->monitor_timer) {
961                         ecore_timer_del(ugd->monitor_timer);
962                         ugd->monitor_timer = NULL;
963                 }
964         } else {
965                 if (NULL == ugd->monitor_timer) {
966                         WDUG_LOGI("start the monitor timer\n");
967                         ugd->last_wfd_time = time(NULL);
968                         ugd->monitor_timer = ecore_timer_add(5.0,
969                                 (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
970                 }
971         }
972
973         __WDUG_LOG_FUNC_EXIT__;
974         return;
975 }
976
977 /**
978  *      This function let the ug get wi-fi direct status from vconf
979  *      @return   If success, return 0, else return -1
980  *      @param[in] data the pointer to the main data structure
981  */
982 int wfd_get_vconf_status(void *data)
983 {
984         __WDUG_LOG_FUNC_ENTER__;
985         struct ug_data *ugd = (struct ug_data *)data;
986         char *dev_name;
987         int wifi_direct_state = 0;
988
989         /* get wifi direct status from vconf */
990         if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
991                 WDUG_LOGE("Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
992                 return -1;
993         }
994
995         ugd->wfd_status = wifi_direct_state;
996
997         /* get device name from vconf */
998         dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
999         if (dev_name == NULL) {
1000                 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1001                 WDUG_LOGE("The AP name is NULL(setting default value)\n");
1002         } else {
1003                 ugd->dev_name = strdup(dev_name);
1004                 free(dev_name);
1005         }
1006
1007         __WDUG_LOG_FUNC_EXIT__;
1008         return 0;
1009 }
1010
1011 /**
1012  *      This function let the ug refresh current status of wi-fi direct
1013  *      @return   If success, return 0, else return -1
1014  *      @param[in] data the pointer to the main data structure
1015  */
1016 int wfd_refresh_wifi_direct_state(void *data)
1017 {
1018         __WDUG_LOG_FUNC_ENTER__;
1019         struct ug_data *ugd = (struct ug_data *)data;
1020         int res;
1021         wifi_direct_state_e wfd_status;
1022
1023         res = wifi_direct_get_state(&wfd_status);
1024         if (res != WIFI_DIRECT_ERROR_NONE) {
1025                 WDUG_LOGE("Failed to get link status. [%d]\n", res);
1026                 return -1;
1027         }
1028
1029         WDUG_LOGI("WFD status [%d]", wfd_status);
1030         ugd->wfd_status = wfd_status;
1031
1032         __WDUG_LOG_FUNC_EXIT__;
1033         return 0;
1034 }
1035
1036 /**
1037  *      This function let the ug do initialization
1038  *      @return   If success, return 0, else return -1
1039  *      @param[in] data the pointer to the main data structure
1040  */
1041 int init_wfd_client(void *data)
1042 {
1043         __WDUG_LOG_FUNC_ENTER__;
1044         struct ug_data *ugd = (struct ug_data *)data;
1045         int res = 0;
1046
1047         res = wifi_direct_initialize();
1048         if (res != WIFI_DIRECT_ERROR_NONE) {
1049                 WDUG_LOGE("Failed to initialize wifi direct. [%d]\n", res);
1050                 return -1;
1051         }
1052
1053         res = wifi_direct_initialize();
1054         if (res != WIFI_DIRECT_ERROR_NONE) {
1055                 WDUG_LOGE("Failed to initialize Wi-Fi Direct. error code = [%d]\n", res);
1056                 return -1;
1057         }
1058
1059         res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1060         if (res != WIFI_DIRECT_ERROR_NONE) {
1061                 WDUG_LOGE("Failed to register _cb_activation. error code = [%d]\n", res);
1062                 return -1;
1063         }
1064
1065         res = wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *)ugd);
1066         if (res != WIFI_DIRECT_ERROR_NONE) {
1067                 WDUG_LOGE("Failed to register _cb_discover. error code = [%d]\n", res);
1068                 return -1;
1069         }
1070
1071         res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1072         if (res != WIFI_DIRECT_ERROR_NONE) {
1073                 WDUG_LOGE("Failed to register _cb_connection. error code = [%d]\n", res);
1074                 return -1;
1075         }
1076
1077         /* update WFD status */
1078         wfd_refresh_wifi_direct_state(ugd);
1079         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1080                 ugd->wfd_onoff = 1;
1081         } else {
1082                 ugd->wfd_onoff = 0;
1083         }
1084
1085         WDUG_LOGI("WFD link status. [%d]\n", ugd->wfd_status);
1086
1087         /* start the monitor timer */
1088         ugd->last_wfd_time = time(NULL);
1089         ugd->last_wfd_status = WIFI_DIRECT_STATE_DEACTIVATED;
1090         ugd->monitor_timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
1091
1092         ugd->is_re_discover = FALSE;
1093
1094         __WDUG_LOG_FUNC_EXIT__;
1095         return 0;
1096 }
1097
1098 /**
1099  *      This function let the ug do de-initialization
1100  *      @return   If success, return 0, else return -1
1101  *      @param[in] data the pointer to the main data structure
1102  */
1103 int deinit_wfd_client(void *data)
1104 {
1105         __WDUG_LOG_FUNC_ENTER__;
1106         struct ug_data *ugd = (struct ug_data *)data;
1107         int res = 0;
1108         tethering_error_e ret = TETHERING_ERROR_NONE;
1109         tethering_h th = NULL;
1110
1111         wfd_refresh_wifi_direct_state(ugd);
1112
1113         if (ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1114                 WDUG_LOGI("Stop discovery before deregister client\n");
1115                 wifi_direct_cancel_discovery();
1116         }
1117
1118         res = wifi_direct_deinitialize();
1119         if (res != WIFI_DIRECT_ERROR_NONE) {
1120                 WDUG_LOGE("Failed to deregister client. [%d]\n", res);
1121         }
1122
1123         /* release monitor timer */
1124         if (ugd->monitor_timer) {
1125                 ecore_timer_del(ugd->monitor_timer);
1126                 ugd->monitor_timer = NULL;
1127         }
1128
1129         /* release vconf, hotspot..  */
1130         res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1131         if (res == -1) {
1132                 WDUG_LOGE("Failed to ignore vconf key callback for wifi state\n");
1133         }
1134
1135         res = net_deregister_client();
1136         if (res != NET_ERR_NONE) {
1137                 WDUG_LOGE("Failed to deregister network client. [%d]\n", res);
1138         }
1139
1140         res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb);
1141         if (res == -1) {
1142                 WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
1143         }
1144
1145         res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb);
1146         if (res == -1) {
1147                 WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
1148         }
1149
1150         th = ugd->hotspot_handle;
1151
1152         if (th != NULL) {
1153                 /* Deregister cbs */
1154                 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
1155                 if (ret != TETHERING_ERROR_NONE) {
1156                         WDUG_LOGE("tethering_unset_enabled_cb is failed(%d)\n", ret);
1157                 }
1158
1159                 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
1160                 if (ret != TETHERING_ERROR_NONE) {
1161                         WDUG_LOGE("tethering_unset_disabled_cb is failed(%d)\n", ret);
1162                 }
1163
1164                 /* Destroy tethering handle */
1165                 ret = tethering_destroy(th);
1166                 if (ret != TETHERING_ERROR_NONE) {
1167                         WDUG_LOGE("tethering_destroy is failed(%d)\n", ret);
1168                 }
1169
1170                 ugd->hotspot_handle = NULL;
1171         }
1172
1173         __WDUG_LOG_FUNC_EXIT__;
1174         return 0;
1175 }
1176
1177 /**
1178  *      This function let the ug turn wi-fi direct on
1179  *      @return   If success, return 0, else return -1
1180  *      @param[in] data the pointer to the main data structure
1181  */
1182 int wfd_client_switch_on(void *data)
1183 {
1184         __WDUG_LOG_FUNC_ENTER__;
1185         struct ug_data *ugd = (struct ug_data *)data;
1186         int res;
1187
1188         wfd_refresh_wifi_direct_state(ugd);
1189         WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status);
1190
1191         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1192                 int wifi_state;
1193                 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1194                 if (res != 0) {
1195                         WDUG_LOGE("Failed to get wifi state from vconf. [%d]\n", res);
1196                         return -1;
1197                 }
1198
1199                 int hotspot_mode;
1200                 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
1201                 if (res != 0) {
1202                         WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res);
1203                         return -1;
1204                 }
1205
1206                 if (wifi_state > VCONFKEY_WIFI_OFF) {
1207                         WDUG_LOGI("WiFi is connected, so have to turn off WiFi");
1208                         wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"), POPUP_TYPE_WIFI_OFF);
1209                 } else if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
1210                         WDUG_LOGI("WiFi is connected, so have to turn off WiFi");
1211                         wfd_ug_act_popup(ugd, _("IDS_WFD_POP_HOTSPOT_OFF"), POPUP_TYPE_HOTSPOT_OFF);
1212                 } else {
1213                         res = wifi_direct_activate();
1214                         if (res != WIFI_DIRECT_ERROR_NONE) {
1215                                 WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1216                                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1217
1218                                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1219                                 wfd_ug_view_refresh_glitem(ugd->head);
1220                                 return -1;
1221                         }
1222
1223                         /* refresh the header */
1224                         ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING;
1225                         wfd_ug_view_refresh_glitem(ugd->head);
1226
1227                         /* while activating, disable the buttons */
1228                         if (ugd->scan_btn) {
1229                                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1230                         }
1231
1232                         if (ugd->multi_scan_btn) {
1233                                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1234                         }
1235
1236                         if (ugd->back_btn) {
1237                                 elm_object_disabled_set(ugd->back_btn, TRUE);
1238                         }
1239                 }
1240         } else {
1241                 WDUG_LOGI("Wi-Fi Direct is already activated\n");
1242         }
1243
1244         __WDUG_LOG_FUNC_EXIT__;
1245         return 0;
1246 }
1247
1248 /**
1249  *      This function let the ug turn wi-fi direct off
1250  *      @return   If success, return 0, else return -1
1251  *      @param[in] data the pointer to the main data structure
1252  */
1253 int wfd_client_switch_off(void *data)
1254 {
1255         __WDUG_LOG_FUNC_ENTER__;
1256         struct ug_data *ugd = (struct ug_data *)data;
1257         int res;
1258
1259         wfd_refresh_wifi_direct_state(ugd);
1260         WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status);
1261
1262         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1263                 WDUG_LOGI("Wi-Fi Direct is already deactivated\n");
1264         } else {
1265                 /*if connected, disconnect all devices*/
1266                 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1267                         res = wifi_direct_disconnect_all();
1268                         if (res != WIFI_DIRECT_ERROR_NONE) {
1269                                 WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res);
1270                                 return -1;
1271                         }
1272                 }
1273
1274                 res = wifi_direct_deactivate();
1275                 if (res != WIFI_DIRECT_ERROR_NONE) {
1276                         WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1277                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1278
1279                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1280                         wfd_ug_view_refresh_glitem(ugd->head);
1281                         return -1;
1282                 }
1283
1284                 /* refresh the header */
1285                 ugd->head_text_mode = HEAD_TEXT_TYPE_DEACTIVATING;
1286                 wfd_ug_view_refresh_glitem(ugd->head);
1287
1288                 /* while deactivating, disable the buttons */
1289                 if (ugd->scan_btn) {
1290                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1291                 }
1292
1293                 if (ugd->multi_scan_btn) {
1294                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1295                 }
1296
1297                 if (ugd->back_btn) {
1298                         elm_object_disabled_set(ugd->back_btn, TRUE);
1299                 }
1300         }
1301
1302         __WDUG_LOG_FUNC_EXIT__;
1303         return 0;
1304 }
1305
1306 /**
1307  *      This function let the ug turn wi-fi direct on/off forcely
1308  *      @return   If success, return 0, else return -1
1309  *      @param[in] data the pointer to the main data structure
1310   *     @param[in] onoff whether to turn on/off wi-fi direct
1311  */
1312 int wfd_client_swtch_force(void *data, int onoff)
1313 {
1314         __WDUG_LOG_FUNC_ENTER__;
1315         struct ug_data *ugd = (struct ug_data *)data;
1316         int res;
1317
1318         if (onoff) {
1319                 res = wifi_direct_activate();
1320                 if (res != WIFI_DIRECT_ERROR_NONE) {
1321                         WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1322                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1323
1324                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1325                         wfd_ug_view_refresh_glitem(ugd->head);
1326                         return -1;
1327                 }
1328         } else {
1329                 res = wifi_direct_deactivate();
1330                 if (res != WIFI_DIRECT_ERROR_NONE) {
1331                         WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1332                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1333
1334                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1335                         wfd_ug_view_refresh_glitem(ugd->head);
1336                         return -1;
1337                 }
1338         }
1339
1340         __WDUG_LOG_FUNC_EXIT__;
1341         return 0;
1342 }
1343
1344 /**
1345  *      This function let the ug create a group
1346  *      @return   If success, return 0, else return -1
1347  */
1348 int wfd_client_group_add()
1349 {
1350         __WDUG_LOG_FUNC_ENTER__;
1351         int res;
1352
1353         res = wifi_direct_create_group();
1354         if (res != WIFI_DIRECT_ERROR_NONE) {
1355                 WDUG_LOGE("Failed to add group");
1356                 __WDUG_LOG_FUNC_EXIT__;
1357                 return -1;
1358         }
1359
1360         __WDUG_LOG_FUNC_EXIT__;
1361         return 0;
1362 }
1363
1364 /**
1365  *      This function let the ug connect to the device by mac address
1366  *      @return   If success, return 0, else return -1
1367  *      @param[in] mac_addr the pointer to the mac address of device
1368  */
1369 int wfd_client_connect(const char *mac_addr)
1370 {
1371         __WDUG_LOG_FUNC_ENTER__;
1372         int res;
1373
1374         WDUG_LOGE("connect to peer=[%s]\n", mac_addr);
1375         res = wifi_direct_connect(mac_addr);
1376         if (res != WIFI_DIRECT_ERROR_NONE) {
1377                 WDUG_LOGE("Failed to send connection request. [%d]\n", res);
1378                 return -1;
1379         }
1380
1381         __WDUG_LOG_FUNC_EXIT__;
1382         return 0;
1383 }
1384
1385 /**
1386  *      This function let the ug disconnect to the device by mac address
1387  *      @return   If success, return 0, else return -1
1388  *      @param[in] mac_addr the pointer to the mac address of device
1389  */
1390 int wfd_client_disconnect(const char *mac_addr)
1391 {
1392         __WDUG_LOG_FUNC_ENTER__;
1393         int res;
1394
1395         if (mac_addr == NULL) {
1396                 res = wifi_direct_disconnect_all();
1397                 if (res != WIFI_DIRECT_ERROR_NONE) {
1398                         WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res);
1399                         return -1;
1400                 }
1401         } else {
1402                 res = wifi_direct_disconnect(mac_addr);
1403                 if (res != WIFI_DIRECT_ERROR_NONE) {
1404                         WDUG_LOGE("Failed to send disconnection request. [%d]\n", res);
1405                         return -1;
1406                 }
1407         }
1408
1409         __WDUG_LOG_FUNC_EXIT__;
1410         return 0;
1411 }
1412
1413 /**
1414  *      This function let the ug set the intent of a group owner
1415  *      @return   If success, return 0, else return -1
1416  *      @param[in] go_intent the intent parameter
1417  */
1418 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1419 {
1420         __WDUG_LOG_FUNC_ENTER__;
1421         int res;
1422
1423         res = wifi_direct_set_group_owner_intent(go_intent);
1424         if (res != WIFI_DIRECT_ERROR_NONE) {
1425                 WDUG_LOGE("Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);
1426                 return -1;
1427         }
1428
1429         __WDUG_LOG_FUNC_EXIT__;
1430         return 0;
1431 }