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