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