e46ba008e16f6d0a32b053b2a3fb82b3919b5ded
[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, SSID_LENGTH);
602         ugd->raw_connected_peers[peer_cnt].ssid[SSID_LENGTH-1] = '\0';
603         ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
604         strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
605         ugd->raw_connected_peers[peer_cnt].mac_addr[MAC_LENGTH-1] = '\0';
606         strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
607         ugd->raw_connected_peers[peer_cnt].if_addr[MAC_LENGTH-1] = '\0';
608         ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
609
610         WDUG_LOGI("\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
611         WDUG_LOGI("\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
612         WDUG_LOGI("\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
613         WDUG_LOGI("\tMAC addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].mac_addr);
614         WDUG_LOGI("\tIface addr: [" MACSTR "]\n", ugd->raw_connected_peers[peer_cnt].if_addr);
615
616         ugd->raw_connected_peer_cnt++;
617
618         free(peer->device_name);
619         free(peer->mac_address);
620         free(peer->interface_address);
621         free(peer);
622
623         __WDUG_LOG_FUNC_EXIT__;
624         return TRUE;
625 }
626
627 /**
628  *      This function let the ug get the found peers
629  *      @return   If success, return 0, else return -1
630  *      @param[in] ugd the pointer to the main data structure
631  */
632 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
633 {
634         __WDUG_LOG_FUNC_ENTER__;
635         int res = 0;
636
637         if (ugd == NULL) {
638                 return -1;
639         }
640
641         ugd->raw_discovered_peer_cnt = 0;
642         res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void *)ugd);
643         if (res != WIFI_DIRECT_ERROR_NONE) {
644                 ugd->raw_discovered_peer_cnt = 0;
645                 WDUG_LOGE("Get discovery result failed: %d\n", res);
646         }
647
648         __WDUG_LOG_FUNC_EXIT__;
649         return 0;
650 }
651
652 /**
653  *      This function let the ug get the connected peers
654  *      @return   If success, return 0, else return -1
655  *      @param[in] ugd the pointer to the main data structure
656  */
657 int wfd_ug_get_connected_peers(struct ug_data *ugd)
658 {
659         __WDUG_LOG_FUNC_ENTER__;
660         int res = 0;
661
662         if (ugd == NULL) {
663                 return -1;
664         }
665
666         ugd->raw_connected_peer_cnt = 0;
667         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ugd);
668         if (res != WIFI_DIRECT_ERROR_NONE) {
669                 ugd->raw_connected_peer_cnt = 0;
670                 WDUG_LOGE("Get connected peer failed: %d\n", res);
671         }
672
673         __WDUG_LOG_FUNC_EXIT__;
674         return 0;
675 }
676
677 /**
678  *      This function let the ug make a callback for deactivating wfd automatically
679  *      @return   if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
680  *      @param[in] user_data the pointer to the main data structure
681  */
682 static Eina_Bool _wfd_automatic_deactivated_for_no_connection_cb(void *user_data)
683 {
684         int res = -1;
685         int interval = 0;
686         struct ug_data *ugd = (struct ug_data *)user_data;
687
688         if (NULL == ugd) {
689                 WDUG_LOGE("NULL parameters.\n");
690                 return ECORE_CALLBACK_CANCEL;
691         }
692
693         /* check the action, if action is exist, keep the cb */
694         res = wifi_direct_get_state(&ugd->wfd_status);
695         if (res != WIFI_DIRECT_ERROR_NONE) {
696                 WDUG_LOGE("Failed to get link status. [%d]\n", res);
697                 return ECORE_CALLBACK_CANCEL;
698         }
699
700         if (ugd->last_wfd_status != ugd->wfd_status) {
701                 WDUG_LOGE("Action is exist, last status: %d\n",
702                         ugd->last_wfd_status);
703                 ugd->last_wfd_status = ugd->wfd_status;
704                 ugd->last_wfd_time = time(NULL);
705                 return ECORE_CALLBACK_RENEW;
706         }
707
708         /* check the timeout, if not timeout, keep the cb */
709         interval = time(NULL) - ugd->last_wfd_time;
710         if (interval < MAX_NO_ACTION_TIME_OUT) {
711                 return ECORE_CALLBACK_RENEW;
712         }
713
714         /* turn off the Wi-Fi Direct */
715         wifi_direct_get_state(&ugd->wfd_status);
716         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
717                 WDUG_LOGE("Wi-Fi Direct is already deactivated\n");
718         } else {
719                 wfd_ug_warn_popup(ugd, IDS_WFD_POP_AUTOMATIC_TURN_OFF, POP_TYPE_AUTOMATIC_TURN_OFF);
720         }
721
722         return ECORE_CALLBACK_CANCEL;
723 }
724
725 /**
726  *      This function let the ug make a callback for registering discover event
727  *      @return   void
728  *      @param[in] error_code the returned error code
729  *      @param[in] discovery_state the state of discover
730  *      @param[in] user_data the pointer to the main data structure
731  */
732 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
733 {
734         __WDUG_LOG_FUNC_ENTER__;
735         struct ug_data *ugd = (struct ug_data *)user_data;
736
737         if (ugd == NULL) {
738                 WDUG_LOGE("Incorrect parameter(NULL)\n");
739                 return;
740         }
741
742         WDUG_LOGI("Discovery event [%d], error_code [%d]\n", discovery_state, error_code);
743
744         if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED) {
745                 __WDUG_LOG_FUNC_EXIT__;
746                 return;
747         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED) {
748                 ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
749
750                 /* clear all the previous discovered peers */
751                 if (ugd->raw_discovered_peer_cnt > 0) {
752                         memset(ugd->raw_discovered_peers, 0x00, ugd->raw_discovered_peer_cnt*sizeof(device_type_s));
753                 }
754
755                 ugd->raw_discovered_peer_cnt = 0;
756         } else if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND) {
757                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
758                 wfd_ug_get_discovered_peers(ugd);
759         } else {
760                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
761
762                 if (TRUE == ugd->is_re_discover) {
763                         ugd->is_re_discover = FALSE;
764                         wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
765                 } else {
766                         /* start LISTEN ONLY mode */
767                         wifi_direct_start_discovery(TRUE, 0);
768                 }
769         }
770
771         wfd_ug_view_refresh_glitem(ugd->head);
772         wfd_ug_view_update_peers(ugd);
773         wfd_update_multiconnect_device(ugd);
774
775         if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state) {
776                 if (ugd->scan_btn) {
777                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
778                 }
779
780                 if (ugd->multi_connect_btn) {
781                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
782                 }
783         } else {
784                 if (ugd->scan_btn) {
785                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
786                 }
787
788                 if (ugd->multi_connect_btn) {
789                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
790                 }
791         }
792
793         __WDUG_LOG_FUNC_EXIT__;
794         return;
795 }
796
797 /**
798  *      This function let the ug make a callback for registering connection event
799  *      @return   void
800  *      @param[in] error_code the returned error code
801  *      @param[in] connection_state the state of connection
802  *      @param[in] mac_address the mac address of peer
803  *      @param[in] user_data the pointer to the main data structure
804  */
805 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
806 {
807         __WDUG_LOG_FUNC_ENTER__;
808         struct ug_data *ugd = (struct ug_data *)user_data;
809         device_type_s *peer = NULL;
810         bool owner = FALSE;
811         int res = 0;
812
813         WDUG_LOGI("Connection event [%d], error_code [%d], multi_connect_mode [%d]\n",
814                 connection_state, error_code, ugd->multi_connect_mode);
815
816         if (mac_address == NULL) {
817                 WDUG_LOGE("Incorrect parameter(peer mac is NULL)\n");
818                 return;
819         }
820
821         /* when not in connection, mac_address is empty */
822         if (connection_state <= WIFI_DIRECT_DISASSOCIATION_IND) {
823                 peer = wfd_client_find_peer_by_mac(ugd, mac_address);
824
825                 if (NULL == peer || '\0' == peer->ssid[0]) {
826                         WDUG_LOGE("invalid peer from connection !!\n");
827                         goto refresh_button;
828                 }
829         }
830
831         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS) {
832                 switch (connection_state) {
833                 case WIFI_DIRECT_CONNECTION_RSP:
834                         WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_RSP\n");
835
836                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
837                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
838                                 wfd_ug_get_connected_peers(ugd);
839                         } else {
840                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
841                         }
842
843                         wfd_ug_view_update_peers(ugd);
844
845                         /* connect the next peer */
846                         ugd->g_source_multi_connect_next = g_timeout_add(1000, wfd_multi_connect_next_cb, ugd);
847                         break;
848                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
849                         WDUG_LOGI("MULTI: WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
850                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
851                         wfd_ug_view_update_peers(ugd);
852                         break;
853                 case WIFI_DIRECT_GROUP_CREATED:
854                         WDUG_LOGI("MULTI: WIFI_DIRECT_GROUP_CREATED\n");
855                         wfd_multi_connect_next_cb(ugd);
856                         break;
857                 default:
858                         break;
859                 }
860         } else {
861                 switch (connection_state) {
862                 case WIFI_DIRECT_CONNECTION_RSP:
863                         WDUG_LOGI("WIFI_DIRECT_CONNECTION_RSP\n");
864
865                         if (error_code == WIFI_DIRECT_ERROR_NONE) {
866                                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
867                                 wfd_ug_get_connected_peers(ugd);
868                         } else {
869                                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
870                         }
871
872                         wfd_ug_view_update_peers(ugd);
873                         break;
874                 case WIFI_DIRECT_DISASSOCIATION_IND:
875                         WDUG_LOGI("WIFI_DIRECT_DISASSOCIATION_IND\n");
876                         /* change the multi connection mode, it can be connected now */
877                         if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_COMPLETED) {
878                                 ugd->multi_connect_mode = WFD_MULTI_CONNECT_MODE_IN_PROGRESS;
879                         }
880
881                         /* if other peer disconnected, get connected peers and update */
882                         peer->conn_status = PEER_CONN_STATUS_WAIT_FOR_CONNECT;
883                         wfd_ug_get_connected_peers(ugd);
884                         wfd_ug_view_update_peers(ugd);
885                         break;
886                 case WIFI_DIRECT_DISCONNECTION_RSP:
887                 case WIFI_DIRECT_DISCONNECTION_IND:
888                         WDUG_LOGI("WIFI_DIRECT_DISCONNECTION_X\n");
889
890                         /* when disconnection, clear all the connected peers */
891                         if (ugd->raw_connected_peer_cnt > 0) {
892                                 memset(ugd->raw_connected_peers, 0x00, ugd->raw_connected_peer_cnt*sizeof(device_type_s));
893                         }
894
895                         ugd->raw_connected_peer_cnt = 0;
896
897                         /* start discovery again */
898                         res = wifi_direct_start_discovery(FALSE, MAX_SCAN_TIME_OUT);
899                         if (res != WIFI_DIRECT_ERROR_NONE) {
900                                 WDUG_LOGE("Failed to start discovery. [%d]\n", res);
901                                 ugd->is_re_discover = TRUE;
902                                 wifi_direct_cancel_discovery();
903                         } else {
904                                 WDUG_LOGI("Discovery is started\n");
905                                 ugd->is_re_discover = FALSE;
906                         }
907
908                         break;
909                 case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
910                         WDUG_LOGI("WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
911                         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
912                         wfd_ug_view_update_peers(ugd);
913                         break;
914                 case WIFI_DIRECT_CONNECTION_REQ:
915                 case WIFI_DIRECT_CONNECTION_WPS_REQ:
916                         WDUG_LOGI("WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
917                         break;
918                 default:
919                         break;
920                 }
921         }
922
923         if (peer != NULL) {
924                 wfd_ug_view_refresh_glitem(peer->gl_item);
925         }
926
927         _change_multi_button_title(ugd);
928
929 refresh_button:
930         /* refresh the scan button */
931         wfd_refresh_wifi_direct_state(ugd);
932         if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
933                 WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
934                 res = wifi_direct_is_group_owner(&owner);
935                 if (res == WIFI_DIRECT_ERROR_NONE) {
936                         if (!owner) {
937                                 if (ugd->scan_btn) {
938                                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
939                                 }
940
941                                 if (ugd->multi_connect_btn) {
942                                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
943                                 }
944                         }
945                 } else {
946                     WDUG_LOGE("Failed to get whether client is group owner. [%d]\n", res);
947                 }
948         } else {
949                 if (ugd->scan_btn) {
950                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
951                 }
952
953                 if (ugd->multi_connect_btn) {
954                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
955                 }
956         }
957
958         /* if no connection, start the monitor timer */
959         wifi_direct_get_state(&ugd->wfd_status);
960         WDUG_LOGI("status: %d", ugd->wfd_status);
961
962         if (ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED) {
963                 if (ugd->monitor_timer) {
964                         ecore_timer_del(ugd->monitor_timer);
965                         ugd->monitor_timer = NULL;
966                 }
967         } else {
968                 if (NULL == ugd->monitor_timer) {
969                         WDUG_LOGI("start the monitor timer\n");
970                         ugd->last_wfd_time = time(NULL);
971                         ugd->monitor_timer = ecore_timer_add(5.0,
972                                 (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
973                 }
974         }
975
976         __WDUG_LOG_FUNC_EXIT__;
977         return;
978 }
979
980 /**
981  *      This function let the ug get wi-fi direct status from vconf
982  *      @return   If success, return 0, else return -1
983  *      @param[in] data the pointer to the main data structure
984  */
985 int wfd_get_vconf_status(void *data)
986 {
987         __WDUG_LOG_FUNC_ENTER__;
988         struct ug_data *ugd = (struct ug_data *)data;
989         char *dev_name;
990         int wifi_direct_state = 0;
991
992         /* get wifi direct status from vconf */
993         if (vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state) < 0) {
994                 WDUG_LOGE("Error reading vconf (%s)\n", VCONFKEY_WIFI_DIRECT_STATE);
995                 return -1;
996         }
997
998         ugd->wfd_status = wifi_direct_state;
999
1000         /* get device name from vconf */
1001         dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1002         if (dev_name == NULL) {
1003                 ugd->dev_name = strdup(DEFAULT_DEV_NAME);
1004                 WDUG_LOGE("The AP name is NULL(setting default value)\n");
1005         } else {
1006                 ugd->dev_name = strdup(dev_name);
1007                 free(dev_name);
1008         }
1009
1010         __WDUG_LOG_FUNC_EXIT__;
1011         return 0;
1012 }
1013
1014 /**
1015  *      This function let the ug refresh current status of wi-fi direct
1016  *      @return   If success, return 0, else return -1
1017  *      @param[in] data the pointer to the main data structure
1018  */
1019 int wfd_refresh_wifi_direct_state(void *data)
1020 {
1021         __WDUG_LOG_FUNC_ENTER__;
1022         struct ug_data *ugd = (struct ug_data *)data;
1023         int res;
1024         wifi_direct_state_e wfd_status;
1025
1026         res = wifi_direct_get_state(&wfd_status);
1027         if (res != WIFI_DIRECT_ERROR_NONE) {
1028                 WDUG_LOGE("Failed to get link status. [%d]\n", res);
1029                 return -1;
1030         }
1031
1032         WDUG_LOGI("WFD status [%d]", wfd_status);
1033         ugd->wfd_status = wfd_status;
1034
1035         __WDUG_LOG_FUNC_EXIT__;
1036         return 0;
1037 }
1038
1039 /**
1040  *      This function let the ug do initialization
1041  *      @return   If success, return 0, else return -1
1042  *      @param[in] data the pointer to the main data structure
1043  */
1044 int init_wfd_client(void *data)
1045 {
1046         __WDUG_LOG_FUNC_ENTER__;
1047         struct ug_data *ugd = (struct ug_data *)data;
1048         int res = 0;
1049
1050         res = wifi_direct_initialize();
1051         if (res != WIFI_DIRECT_ERROR_NONE) {
1052                 WDUG_LOGE("Failed to initialize wifi direct. [%d]\n", res);
1053                 return -1;
1054         }
1055
1056         res = wifi_direct_initialize();
1057         if (res != WIFI_DIRECT_ERROR_NONE) {
1058                 WDUG_LOGE("Failed to initialize Wi-Fi Direct. error code = [%d]\n", res);
1059                 return -1;
1060         }
1061
1062         res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *)ugd);
1063         if (res != WIFI_DIRECT_ERROR_NONE) {
1064                 WDUG_LOGE("Failed to register _cb_activation. error code = [%d]\n", res);
1065                 return -1;
1066         }
1067
1068         res = wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *)ugd);
1069         if (res != WIFI_DIRECT_ERROR_NONE) {
1070                 WDUG_LOGE("Failed to register _cb_discover. error code = [%d]\n", res);
1071                 return -1;
1072         }
1073
1074         res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void *)ugd);
1075         if (res != WIFI_DIRECT_ERROR_NONE) {
1076                 WDUG_LOGE("Failed to register _cb_connection. error code = [%d]\n", res);
1077                 return -1;
1078         }
1079
1080         /* update WFD status */
1081         wfd_refresh_wifi_direct_state(ugd);
1082         if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING) {
1083                 ugd->wfd_onoff = 1;
1084         } else {
1085                 ugd->wfd_onoff = 0;
1086         }
1087
1088         WDUG_LOGI("WFD link status. [%d]\n", ugd->wfd_status);
1089
1090         /* start the monitor timer */
1091         ugd->last_wfd_time = time(NULL);
1092         ugd->last_wfd_status = WIFI_DIRECT_STATE_DEACTIVATED;
1093         ugd->monitor_timer = ecore_timer_add(5.0, (Ecore_Task_Cb)_wfd_automatic_deactivated_for_no_connection_cb, ugd);
1094
1095         ugd->is_re_discover = FALSE;
1096
1097         __WDUG_LOG_FUNC_EXIT__;
1098         return 0;
1099 }
1100
1101 /**
1102  *      This function let the ug do de-initialization
1103  *      @return   If success, return 0, else return -1
1104  *      @param[in] data the pointer to the main data structure
1105  */
1106 int deinit_wfd_client(void *data)
1107 {
1108         __WDUG_LOG_FUNC_ENTER__;
1109         struct ug_data *ugd = (struct ug_data *)data;
1110         int res = 0;
1111         tethering_error_e ret = TETHERING_ERROR_NONE;
1112         tethering_h th = NULL;
1113
1114         wfd_refresh_wifi_direct_state(ugd);
1115
1116         if (ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING) {
1117                 WDUG_LOGI("Stop discovery before deregister client\n");
1118                 wifi_direct_cancel_discovery();
1119         }
1120
1121         res = wifi_direct_deinitialize();
1122         if (res != WIFI_DIRECT_ERROR_NONE) {
1123                 WDUG_LOGE("Failed to deregister client. [%d]\n", res);
1124         }
1125
1126         /* release monitor timer */
1127         if (ugd->monitor_timer) {
1128                 ecore_timer_del(ugd->monitor_timer);
1129                 ugd->monitor_timer = NULL;
1130         }
1131
1132         /* release vconf, hotspot..  */
1133         res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
1134         if (res == -1) {
1135                 WDUG_LOGE("Failed to ignore vconf key callback for wifi state\n");
1136         }
1137
1138         res = net_deregister_client();
1139         if (res != NET_ERR_NONE) {
1140                 WDUG_LOGE("Failed to deregister network client. [%d]\n", res);
1141         }
1142
1143         res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _enable_hotspot_state_cb);
1144         if (res == -1) {
1145                 WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
1146         }
1147
1148         res = vconf_ignore_key_changed(VCONFKEY_MOBILE_HOTSPOT_MODE, _disable_hotspot_state_cb);
1149         if (res == -1) {
1150                 WDUG_LOGE("Failed to ignore vconf key callback for hotspot state\n");
1151         }
1152
1153         th = ugd->hotspot_handle;
1154
1155         if (th != NULL) {
1156                 /* Deregister cbs */
1157                 ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_WIFI);
1158                 if (ret != TETHERING_ERROR_NONE) {
1159                         WDUG_LOGE("tethering_unset_enabled_cb is failed(%d)\n", ret);
1160                 }
1161
1162                 ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_WIFI);
1163                 if (ret != TETHERING_ERROR_NONE) {
1164                         WDUG_LOGE("tethering_unset_disabled_cb is failed(%d)\n", ret);
1165                 }
1166
1167                 /* Destroy tethering handle */
1168                 ret = tethering_destroy(th);
1169                 if (ret != TETHERING_ERROR_NONE) {
1170                         WDUG_LOGE("tethering_destroy is failed(%d)\n", ret);
1171                 }
1172
1173                 ugd->hotspot_handle = NULL;
1174         }
1175
1176         __WDUG_LOG_FUNC_EXIT__;
1177         return 0;
1178 }
1179
1180 /**
1181  *      This function let the ug turn wi-fi direct on
1182  *      @return   If success, return 0, else return -1
1183  *      @param[in] data the pointer to the main data structure
1184  */
1185 int wfd_client_switch_on(void *data)
1186 {
1187         __WDUG_LOG_FUNC_ENTER__;
1188         struct ug_data *ugd = (struct ug_data *)data;
1189         int res;
1190
1191         wfd_refresh_wifi_direct_state(ugd);
1192         WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status);
1193
1194         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1195                 int wifi_state;
1196                 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1197                 if (res != 0) {
1198                         WDUG_LOGE("Failed to get wifi state from vconf. [%d]\n", res);
1199                         return -1;
1200                 }
1201
1202                 int hotspot_mode;
1203                 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_mode);
1204                 if (res != 0) {
1205                         WDUG_LOGE("Failed to get mobile hotspot state from vconf. [%d]\n", res);
1206                         return -1;
1207                 }
1208
1209                 if (wifi_state > VCONFKEY_WIFI_OFF) {
1210                         WDUG_LOGI("WiFi is connected, so have to turn off WiFi");
1211                         wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"), POPUP_TYPE_WIFI_OFF);
1212                 } else if (hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
1213                         WDUG_LOGI("WiFi is connected, so have to turn off WiFi");
1214                         wfd_ug_act_popup(ugd, _("IDS_WFD_POP_HOTSPOT_OFF"), POPUP_TYPE_HOTSPOT_OFF);
1215                 } else {
1216                         res = wifi_direct_activate();
1217                         if (res != WIFI_DIRECT_ERROR_NONE) {
1218                                 WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1219                                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1220
1221                                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1222                                 wfd_ug_view_refresh_glitem(ugd->head);
1223                                 return -1;
1224                         }
1225
1226                         /* refresh the header */
1227                         ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATING;
1228                         wfd_ug_view_refresh_glitem(ugd->head);
1229
1230                         /* while activating, disable the buttons */
1231                         if (ugd->scan_btn) {
1232                                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1233                         }
1234
1235                         if (ugd->multi_scan_btn) {
1236                                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1237                         }
1238
1239                         if (ugd->back_btn) {
1240                                 elm_object_disabled_set(ugd->back_btn, TRUE);
1241                         }
1242                 }
1243         } else {
1244                 WDUG_LOGI("Wi-Fi Direct is already activated\n");
1245         }
1246
1247         __WDUG_LOG_FUNC_EXIT__;
1248         return 0;
1249 }
1250
1251 /**
1252  *      This function let the ug turn wi-fi direct off
1253  *      @return   If success, return 0, else return -1
1254  *      @param[in] data the pointer to the main data structure
1255  */
1256 int wfd_client_switch_off(void *data)
1257 {
1258         __WDUG_LOG_FUNC_ENTER__;
1259         struct ug_data *ugd = (struct ug_data *)data;
1260         int res;
1261
1262         wfd_refresh_wifi_direct_state(ugd);
1263         WDUG_LOGI("WFD status [%d]\n", ugd->wfd_status);
1264
1265         if (ugd->wfd_status < WIFI_DIRECT_STATE_ACTIVATING) {
1266                 WDUG_LOGI("Wi-Fi Direct is already deactivated\n");
1267         } else {
1268                 /*if connected, disconnect all devices*/
1269                 if (WIFI_DIRECT_STATE_CONNECTED == ugd->wfd_status) {
1270                         res = wifi_direct_disconnect_all();
1271                         if (res != WIFI_DIRECT_ERROR_NONE) {
1272                                 WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res);
1273                                 return -1;
1274                         }
1275                 }
1276
1277                 res = wifi_direct_deactivate();
1278                 if (res != WIFI_DIRECT_ERROR_NONE) {
1279                         WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1280                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1281
1282                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1283                         wfd_ug_view_refresh_glitem(ugd->head);
1284                         return -1;
1285                 }
1286
1287                 /* refresh the header */
1288                 ugd->head_text_mode = HEAD_TEXT_TYPE_DEACTIVATING;
1289                 wfd_ug_view_refresh_glitem(ugd->head);
1290
1291                 /* while deactivating, disable the buttons */
1292                 if (ugd->scan_btn) {
1293                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1294                 }
1295
1296                 if (ugd->multi_scan_btn) {
1297                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
1298                 }
1299
1300                 if (ugd->back_btn) {
1301                         elm_object_disabled_set(ugd->back_btn, TRUE);
1302                 }
1303         }
1304
1305         __WDUG_LOG_FUNC_EXIT__;
1306         return 0;
1307 }
1308
1309 /**
1310  *      This function let the ug turn wi-fi direct on/off forcely
1311  *      @return   If success, return 0, else return -1
1312  *      @param[in] data the pointer to the main data structure
1313   *     @param[in] onoff whether to turn on/off wi-fi direct
1314  */
1315 int wfd_client_swtch_force(void *data, int onoff)
1316 {
1317         __WDUG_LOG_FUNC_ENTER__;
1318         struct ug_data *ugd = (struct ug_data *)data;
1319         int res;
1320
1321         if (onoff) {
1322                 res = wifi_direct_activate();
1323                 if (res != WIFI_DIRECT_ERROR_NONE) {
1324                         WDUG_LOGE("Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
1325                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1326
1327                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1328                         wfd_ug_view_refresh_glitem(ugd->head);
1329                         return -1;
1330                 }
1331         } else {
1332                 res = wifi_direct_deactivate();
1333                 if (res != WIFI_DIRECT_ERROR_NONE) {
1334                         WDUG_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
1335                         wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
1336
1337                         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
1338                         wfd_ug_view_refresh_glitem(ugd->head);
1339                         return -1;
1340                 }
1341         }
1342
1343         __WDUG_LOG_FUNC_EXIT__;
1344         return 0;
1345 }
1346
1347 /**
1348  *      This function let the ug create a group
1349  *      @return   If success, return 0, else return -1
1350  */
1351 int wfd_client_group_add()
1352 {
1353         __WDUG_LOG_FUNC_ENTER__;
1354         int res;
1355
1356         res = wifi_direct_create_group();
1357         if (res != WIFI_DIRECT_ERROR_NONE) {
1358                 WDUG_LOGE("Failed to add group");
1359                 __WDUG_LOG_FUNC_EXIT__;
1360                 return -1;
1361         }
1362
1363         __WDUG_LOG_FUNC_EXIT__;
1364         return 0;
1365 }
1366
1367 /**
1368  *      This function let the ug connect to the device by mac address
1369  *      @return   If success, return 0, else return -1
1370  *      @param[in] mac_addr the pointer to the mac address of device
1371  */
1372 int wfd_client_connect(const char *mac_addr)
1373 {
1374         __WDUG_LOG_FUNC_ENTER__;
1375         int res;
1376
1377         WDUG_LOGE("connect to peer=[%s]\n", mac_addr);
1378         res = wifi_direct_connect(mac_addr);
1379         if (res != WIFI_DIRECT_ERROR_NONE) {
1380                 WDUG_LOGE("Failed to send connection request. [%d]\n", res);
1381                 return -1;
1382         }
1383
1384         __WDUG_LOG_FUNC_EXIT__;
1385         return 0;
1386 }
1387
1388 /**
1389  *      This function let the ug disconnect to the device by mac address
1390  *      @return   If success, return 0, else return -1
1391  *      @param[in] mac_addr the pointer to the mac address of device
1392  */
1393 int wfd_client_disconnect(const char *mac_addr)
1394 {
1395         __WDUG_LOG_FUNC_ENTER__;
1396         int res;
1397
1398         if (mac_addr == NULL) {
1399                 res = wifi_direct_disconnect_all();
1400                 if (res != WIFI_DIRECT_ERROR_NONE) {
1401                         WDUG_LOGE("Failed to send disconnection request to all. [%d]\n", res);
1402                         return -1;
1403                 }
1404         } else {
1405                 res = wifi_direct_disconnect(mac_addr);
1406                 if (res != WIFI_DIRECT_ERROR_NONE) {
1407                         WDUG_LOGE("Failed to send disconnection request. [%d]\n", res);
1408                         return -1;
1409                 }
1410         }
1411
1412         __WDUG_LOG_FUNC_EXIT__;
1413         return 0;
1414 }
1415
1416 /**
1417  *      This function let the ug set the intent of a group owner
1418  *      @return   If success, return 0, else return -1
1419  *      @param[in] go_intent the intent parameter
1420  */
1421 int wfd_client_set_p2p_group_owner_intent(int go_intent)
1422 {
1423         __WDUG_LOG_FUNC_ENTER__;
1424         int res;
1425
1426         res = wifi_direct_set_group_owner_intent(go_intent);
1427         if (res != WIFI_DIRECT_ERROR_NONE) {
1428                 WDUG_LOGE("Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);
1429                 return -1;
1430         }
1431
1432         __WDUG_LOG_FUNC_EXIT__;
1433         return 0;
1434 }