apply FSL(Flora Software License)
[apps/native/ug-wifi-direct.git] / ug-wifidirect / src / wfd_client.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * This file implements Wi-Fi direct client functions.
19  *
20  * @file    wfd_client.c
21  * @author  Gibyoung Kim (lastkgb.kim@samsung.com)
22  * @version 0.1
23  */
24
25 #include <stdio.h>
26 #include <stdbool.h>
27 #include <libintl.h>
28
29 #include <Elementary.h>
30 #include <pmapi.h>
31 #include <vconf.h>
32 #include <network-cm-intf.h>
33 #include <network-wifi-intf.h>
34 #include <wifi-direct.h>
35
36 #include "wfd_ug.h"
37 #include "wfd_ug_view.h"
38 #include "wfd_client.h"
39
40
41
42
43 static void _wifi_state_cb(keynode_t *key, void *data)
44 {
45     __FUNC_ENTER__;
46     struct ug_data *ugd = (struct ug_data*) data;
47     int res;
48     int wifi_state;
49
50     res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
51     if (res != 0)
52     {
53         DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
54         return;
55     }
56
57     if (wifi_state == VCONFKEY_WIFI_OFF)
58     {
59         DBG(LOG_VERBOSE, "WiFi is turned off\n");
60         wfd_client_swtch_force(ugd, TRUE);
61     }
62     else
63     {
64         DBG(LOG_VERBOSE, "WiFi is turned on\n");
65     }
66
67     res = net_deregister_client();
68     if (res != NET_ERR_NONE)
69     {
70         DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
71     }
72
73     __FUNC_EXIT__;
74 }
75
76 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
77 {
78     __FUNC_ENTER__;
79     DBG(LOG_VERBOSE, "Event from network. [%d]\n", event_info->Event);
80     __FUNC_EXIT__;
81 }
82
83 int wfd_wifi_off(void *data)
84 {
85     __FUNC_ENTER__;
86     struct ug_data *ugd = (struct ug_data*) data;
87     int res;
88
89     res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
90     if (res == -1)
91     {
92         DBG(LOG_ERROR, "Failed to register vconf callback\n");
93         return -1;
94     }
95     DBG(LOG_VERBOSE, "Vconf key callback is registered\n");
96     res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
97     if (res != NET_ERR_NONE)
98     {
99         DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
100         return -1;
101     }
102     DBG(LOG_VERBOSE, "Network client is registered\n");
103     res = net_wifi_power_off();
104     if (res != NET_ERR_NONE)
105     {
106         DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
107         return -1;
108     }
109     DBG(LOG_VERBOSE, "WiFi power off\n");
110     __FUNC_EXIT__;
111     return 0;
112 }
113
114 static device_type_s *wfd_client_find_peer_by_ssid(void *data, const char *ssid)
115 {
116     __FUNC_ENTER__;
117     struct ug_data *ugd = (struct ug_data *) data;
118     int i;
119
120     if (ugd == NULL)
121     {
122         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
123         return NULL;
124     }
125
126     for (i = 0; i < ugd->peer_cnt; i++)
127     {
128         DBG(LOG_VERBOSE, "check %dth peer\n", i);
129         if (!strcmp(ugd->peers[i].ssid, ssid))
130         {
131             DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
132             __FUNC_EXIT__;
133             return &ugd->peers[i];
134         }
135     }
136     __FUNC_EXIT__;
137
138     return NULL;
139 }
140
141 static device_type_s *wfd_client_find_peer_by_mac(void *data,
142                                                   const char *mac_addr)
143 {
144     __FUNC_ENTER__;
145     struct ug_data *ugd = (struct ug_data *) data;
146     int i;
147
148     if (ugd == NULL)
149     {
150         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
151         return NULL;
152     }
153
154     for (i = 0; i < ugd->peer_cnt; i++)
155     {
156         DBG(LOG_VERBOSE, "check %dth peer\n", i);
157         if (!strncmp
158             (mac_addr, (const char *) ugd->peers[i].mac_addr, MAC_LENGTH))
159         {
160             DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
161             __FUNC_EXIT__;
162             return &ugd->peers[i];
163         }
164     }
165     __FUNC_EXIT__;
166
167     return NULL;
168 }
169
170 void _activation_cb(int error_code, wifi_direct_device_state_e device_state,
171                     void *user_data)
172 {
173     __FUNC_ENTER__;
174     int res;
175     wifi_direct_state_e wfd_status;
176     struct ug_data *ugd = (struct ug_data *) user_data;
177
178     wifi_direct_get_state(&wfd_status);
179     DBG(LOG_VERBOSE, "WFD status [%d]", wfd_status);
180     ugd->wfd_status = wfd_status;
181
182     switch (device_state)
183     {
184     case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
185         DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
186         if(error_code != WIFI_DIRECT_ERROR_NONE)
187         {
188             DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
189             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL);
190
191             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
192             ugd->wfd_onoff = 0;
193             wfd_ug_view_refresh_glitem(ugd->head);
194             return;
195         }
196
197         ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
198         ugd->wfd_onoff = 1;
199         wfd_ug_view_refresh_glitem(ugd->head);
200         res = vconf_set_int("db/wifi_direct/onoff", ugd->wfd_onoff);
201         if (res != 0)
202         {
203             DBG(LOG_ERROR, "Failed to set vconf value for WFD onoff status\n");
204         }
205         wfg_ug_act_popup_remove(ugd);
206
207         res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
208         if (res == -1)
209         {
210             DBG(LOG_ERROR,
211                 "Failed to ignore vconf key callback for wifi state\n");
212         }
213
214         res = wifi_direct_start_discovery(FALSE, 0);
215         if (res != WIFI_DIRECT_ERROR_NONE)
216         {
217             DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
218         }
219         break;
220         DBG(LOG_VERBOSE, "Discovery is started\n");
221     case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
222         DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
223         if(error_code != WIFI_DIRECT_ERROR_NONE)
224         {
225             DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
226             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL);
227             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
228             ugd->wfd_onoff = 1;
229             wfd_ug_view_refresh_glitem(ugd->head);
230             return;
231         }
232
233         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
234         ugd->wfd_onoff = 0;
235         wfd_ug_view_refresh_glitem(ugd->head);
236         res = vconf_set_int("db/wifi_direct/onoff", ugd->wfd_onoff);
237         if (res != 0)
238         {
239             DBG(LOG_ERROR, "Failed to set vconf value for WFD onoff status\n");
240         }
241         wfd_ug_view_free_peers(ugd);
242         wfd_ug_view_update_peers(ugd);
243         break;
244     default:
245         break;
246     }
247     wfd_ug_view_refresh_button(ugd->scan_btn, ugd->wfd_onoff);
248
249     __FUNC_EXIT__;
250     return;
251 }
252
253 static int peer_cnt;
254 static int connected_cnt;
255 static int discovered_cnt;
256
257 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s * peer,
258                             void *user_data)
259 {
260     __FUNC_ENTER__;
261     device_type_s *peers = (device_type_s *) user_data;
262
263     DBG(LOG_VERBOSE, "%dth discovered peer. [%s]\n", peer_cnt, peer->ssid);
264     if (peer->is_connected == TRUE)
265         return FALSE;
266     memcpy(peers[peer_cnt].ssid, peer->ssid, SSID_LENGTH);
267     peers[peer_cnt].ssid[31] = '\0';
268     DBG(LOG_VERBOSE, "\tSSID: [%s]\n", peers[peer_cnt].ssid);
269     peers[peer_cnt].category = peer->primary_device_type;
270     DBG(LOG_VERBOSE, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, peers[peer_cnt].category);
271     strncpy(peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
272     strncpy(peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
273     peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED;
274     DBG(LOG_VERBOSE, "\tStatus: [%d]\n", peers[peer_cnt].conn_status);
275     peer_cnt++;
276
277     free(peer->ssid);
278     free(peer->mac_address);
279     free(peer->interface_address);
280     free(peer);
281     __FUNC_EXIT__;
282     return TRUE;
283 }
284
285 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s * peer,
286                             void *user_data)
287 {
288     __FUNC_ENTER__;
289     device_type_s *peers = (device_type_s *) user_data;
290
291     DBG(LOG_VERBOSE, "%dth connected peer. [%s]\n", peer_cnt, peer->ssid);
292     memcpy(peers[peer_cnt].ssid, peer->ssid, SSID_LENGTH);
293     peers[peer_cnt].ssid[31] = '\0';
294     DBG(LOG_VERBOSE, "\tSSID: [%s]\n", peers[peer_cnt].ssid);
295     peers[peer_cnt].category = peer->primary_device_type;
296     DBG(LOG_VERBOSE, "\tCategory: [%d]\n", peers[peer_cnt].category);
297     strncpy(peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
298     strncpy(peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
299     peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
300     DBG(LOG_VERBOSE, "\tStatus: [%d]\n", peers[peer_cnt].conn_status);
301     peer_cnt++;
302
303     free(peer->ssid);
304     free(peer->mac_address);
305     free(peer->interface_address);
306     free(peer);
307     __FUNC_EXIT__;
308     return TRUE;
309 }
310
311 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state,
312                   void *user_data)
313 {
314     __FUNC_ENTER__;
315     struct ug_data *ugd = (struct ug_data *) user_data;
316     int res;
317     device_type_s *peers = NULL;
318
319     if (ugd == NULL)
320     {
321         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
322         return;
323     }
324
325     peers = calloc(MAX_PEER_NUM, sizeof(device_type_s));
326
327     if (discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED)
328     {
329         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
330     }
331     else if (discovery_state == WIFI_DIRECT_DISCOVERY_STARTED)
332     {
333         ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
334     }
335     wfd_ug_view_refresh_glitem(ugd->head);
336
337     if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATED
338         || ugd->wfd_status > WFD_LINK_STATUS_GROUP_OWNER)
339     {
340         return;
341     }
342     else
343     {
344         peer_cnt = 0;
345     }
346
347     if (ugd->wfd_status >= WFD_LINK_STATUS_CONNECTED)
348     {
349         DBG(LOG_VERBOSE, "getting connected peer..\n");
350         res =
351             wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb,
352                                                 (void *) peers);
353         if (res != WIFI_DIRECT_ERROR_NONE)
354         {
355             connected_cnt = 0;
356             DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
357         }
358     }
359
360     if (discovery_state == WIFI_DIRECT_DISCOVERY_FOUND)
361     {
362         DBG(LOG_VERBOSE, "Peer is found\n");
363         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
364         wfd_ug_view_refresh_glitem(ugd->head);
365
366         if (ugd->wfd_status >= WFD_LINK_STATUS_ACTIVATED)
367         {
368             DBG(LOG_VERBOSE, "getting discovered peer..\n");
369             res =
370                 wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb,
371                                                      (void *) peers);
372             if (res != WIFI_DIRECT_ERROR_NONE)
373             {
374                 discovered_cnt = 0;
375                 DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
376             }
377         }
378     }
379
380     wfd_ug_view_free_peers(ugd);
381
382     ugd->peers = peers;
383     ugd->peer_cnt = peer_cnt;
384
385     wfd_ug_view_update_peers(ugd);
386     DBG(LOG_VERBOSE, "%d peers are updated\n", peer_cnt);
387
388     __FUNC_EXIT__;
389     return;
390 }
391
392 void _connection_cb(int error_code,
393                     wifi_direct_connection_state_e connection_state,
394                     const char *mac_address, void *user_data)
395 {
396     __FUNC_ENTER__;
397     DBG(LOG_VERBOSE, "Connection event [%d], error_code [%d]\n",
398         connection_state, error_code);
399     struct ug_data *ugd = (struct ug_data *) user_data;
400     device_type_s *peer = NULL;
401     bool owner = FALSE;
402     int res = 0;
403
404     if (mac_address == NULL)
405     {
406         DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
407         return;
408     }
409     DBG(LOG_VERBOSE, "Connection event from %s", mac_address);
410
411     peer = wfd_client_find_peer_by_mac(ugd, mac_address);
412     if (peer == NULL)
413     {
414         DBG(LOG_ERROR, "Failed to find peer [mac: %s]\n", mac_address);
415         return;
416     }
417
418     switch (connection_state)
419     {
420     case WIFI_DIRECT_CONNECTION_RSP:
421         DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_RSP\n");
422
423         if (error_code == WIFI_DIRECT_ERROR_NONE)
424         {
425             ugd->wfd_status = WFD_LINK_STATUS_CONNECTED;
426             peer->conn_status = PEER_CONN_STATUS_CONNECTED;
427             res = wifi_direct_is_group_owner(&owner);
428             if (res == WIFI_DIRECT_ERROR_NONE)
429             {
430                 if (!owner)
431                     wfd_ug_view_refresh_button(ugd->scan_btn, FALSE);
432             }
433             else
434             {
435                 DBG(LOG_ERROR,
436                     "Failed to get whether client is group owner. [%d]\n", res);
437             }
438         }
439         else
440         {
441             peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
442             wifi_direct_start_discovery(FALSE, 0);
443         }
444         break;
445     case WIFI_DIRECT_DISCONNECTION_RSP:
446     case WIFI_DIRECT_DISCONNECTION_IND:
447     case WIFI_DIRECT_DISASSOCIATION_IND:
448         DBG(LOG_VERBOSE, "WIFI_DIRECT_DISCONNECTION_X\n");
449         if (error_code != WIFI_DIRECT_ERROR_NONE)
450         {
451             return;
452         }
453
454         peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
455
456         ugd->wfd_status = WFD_LINK_STATUS_ACTIVATED;
457         ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
458
459         wfd_ug_view_refresh_button(ugd->scan_btn, TRUE);
460         wifi_direct_start_discovery(FALSE, 0);
461         ugd->wfd_status = WFD_LINK_STATUS_DISCOVERING;
462         ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
463         wfd_ug_view_refresh_glitem(ugd->head);
464         break;
465     case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
466         DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
467         peer->conn_status = PEER_CONN_STATUS_CONNECTING;
468         break;
469     case WIFI_DIRECT_CONNECTION_REQ:
470     case WIFI_DIRECT_CONNECTION_WPS_REQ:
471         DBG(LOG_VERBOSE, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
472         break;
473     default:
474         break;
475     }
476
477     if (peer != NULL)
478         wfd_ug_view_refresh_glitem(peer->gl_item);
479
480     __FUNC_EXIT__;
481     return;
482 }
483
484 int wfd_get_vconf_status(void *data)
485 {
486     __FUNC_ENTER__;
487     struct ug_data *ugd = (struct ug_data *) data;
488     int res;
489     char *dev_name;
490
491     res = vconf_get_int("db/wifi_direct/onoff", &ugd->wfd_onoff);
492     if (res != 0)
493     {
494         DBG(LOG_ERROR, "vconf_get_int is failed\n");
495     }
496     DBG(LOG_VERBOSE, "VCONF_WFD_ONOFF : %d\n", ugd->wfd_onoff);
497
498     dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
499     if (dev_name == NULL)
500     {
501         ugd->dev_name = strdup(DEFAULT_DEV_NAME);
502         DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
503     }
504     else
505     {
506         ugd->dev_name = strdup(dev_name);
507         free(dev_name);
508     }
509
510     __FUNC_EXIT__;
511
512     return 0;
513 }
514
515 int init_wfd_client(void *data)
516 {
517     __FUNC_ENTER__;
518     struct ug_data *ugd = (struct ug_data *) data;
519     int res = 0;
520     wifi_direct_state_e wfd_status;
521
522     res = wifi_direct_initialize();
523     if (res != WIFI_DIRECT_ERROR_NONE)
524     {
525         DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
526         return -1;
527     }
528
529     res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void *) ugd);
530     res =
531         wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void *) ugd);
532     res =
533         wifi_direct_set_connection_state_changed_cb(_connection_cb,
534                                                     (void *) ugd);
535
536     res = wifi_direct_get_state(&wfd_status);
537     if (res != WIFI_DIRECT_ERROR_NONE)
538     {
539         DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
540         return -1;
541     }
542     ugd->wfd_status = wfd_status;
543     DBG(LOG_VERBOSE, "WFD link status. [%d]\n", wfd_status);
544
545     if (wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
546     {
547         vconf_set_int("db/wifi_direct/onoff", 1);
548         ugd->wfd_onoff = 1;
549     }
550     else
551     {
552         vconf_set_int("db/wifi_direct/onoff", 0);
553         ugd->wfd_onoff = 0;
554     }
555     wfd_ug_view_refresh_glitem(ugd->head);
556     wfd_ug_view_refresh_button(ugd->scan_btn, ugd->wfd_onoff);
557
558     if(wfd_status >= WIFI_DIRECT_STATE_CONNECTED)
559     {
560         device_type_s *peers = NULL;
561
562         peers = calloc(MAX_PEER_NUM, sizeof(device_type_s));
563         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void*) peers);
564         if(res != WIFI_DIRECT_ERROR_NONE)
565         {
566             connected_cnt = 0;
567             DBG(LOG_ERROR, "get discovery result failed: %d\n", res);
568         }
569         wfd_ug_view_free_peers(ugd);
570
571         ugd->peers = peers;
572         ugd->peer_cnt = peer_cnt;
573
574         wfd_ug_view_update_peers(ugd);
575         DBG(LOG_VERBOSE, "%d peers are updated\n", peer_cnt);
576     }
577
578     if (wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
579     {
580         int wifi_state;
581         vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
582
583         if (wifi_state < VCONFKEY_WIFI_CONNECTED)
584         {
585             res = wifi_direct_start_discovery(FALSE, 0);
586             if (res != WIFI_DIRECT_ERROR_NONE)
587             {
588                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
589             }
590             DBG(LOG_VERBOSE, "Discovery is started\n");
591         }
592         else
593         {
594             wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"),
595                              POPUP_TYPE_WIFI_OFF);
596         }
597     }
598
599     __FUNC_EXIT__;
600
601     return 0;
602 }
603
604 int deinit_wfd_client(void *data)
605 {
606     __FUNC_ENTER__;
607     int res = 0;
608     wifi_direct_state_e status = 0;
609
610     wifi_direct_get_state(&status);
611
612     if (status == WIFI_DIRECT_STATE_DISCOVERING)
613     {
614         DBG(LOG_VERBOSE, "Stop discovery before deregister client\n");
615         wifi_direct_cancel_discovery();
616     }
617
618     res = wifi_direct_deinitialize();
619     if (res != WIFI_DIRECT_ERROR_NONE)
620     {
621         DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
622     }
623
624     res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
625     if (res == -1)
626     {
627         DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
628     }
629
630     res = net_deregister_client();
631     if (res != NET_ERR_NONE)
632     {
633         DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
634     }
635
636
637     __FUNC_EXIT__;
638
639     return 0;
640 }
641
642 int wfd_client_get_link_status()
643 {
644     __FUNC_ENTER__;
645     wifi_direct_state_e status;
646     int res;
647
648     res = wifi_direct_get_state(&status);
649     if (res != WIFI_DIRECT_ERROR_NONE)
650     {
651         DBG(LOG_ERROR, "Failed to get link status from wfd-server. [%d]", res);
652         return -1;
653     }
654
655     __FUNC_EXIT__;
656     return status;
657 }
658
659 int wfd_client_switch_on(void *data)
660 {
661     __FUNC_ENTER__;
662     struct ug_data *ugd = (struct ug_data *) data;
663     int res;
664
665     DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
666
667     if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
668     {
669         ugd->wfd_status = WFD_LINK_STATUS_ACTIVATING;
670
671         int wifi_state;
672         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
673         if (res != 0)
674         {
675             DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
676             return -1;
677         }
678
679         if (wifi_state > VCONFKEY_WIFI_OFF)
680         {
681             DBG(LOG_VERBOSE, "WiFi is connected, so have to turn off WiFi");
682             wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"),
683                              POPUP_TYPE_WIFI_OFF);
684         }
685         else
686         {
687             res = wifi_direct_activate();
688             if (res != WIFI_DIRECT_ERROR_NONE)
689             {
690                 DBG(LOG_ERROR,
691                     "Failed to activate Wi-Fi Direct. error code = [%d]\n",
692                     res);
693                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
694
695                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
696                 wfd_ug_view_refresh_glitem(ugd->head);
697                 return -1;
698             }
699         }
700     }
701     else
702     {
703         DBG(LOG_VERBOSE, "Wi-Fi Direct is already activated\n");
704     }
705
706     __FUNC_EXIT__;
707     return 0;
708 }
709
710 int wfd_client_switch_off(void *data)
711 {
712     __FUNC_ENTER__;
713     struct ug_data *ugd = (struct ug_data *) data;
714     int res;
715
716     DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
717
718     if (ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
719     {
720         DBG(LOG_VERBOSE, "Wi-Fi Direct is already deactivated\n");
721     }
722     else
723     {
724         ugd->wfd_status = WFD_LINK_STATUS_DEACTIVATING;
725
726         res = wifi_direct_deactivate();
727         if (res != WIFI_DIRECT_ERROR_NONE)
728         {
729             DBG(LOG_ERROR,
730                 "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
731             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
732
733             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
734             wfd_ug_view_refresh_glitem(ugd->head);
735             return -1;
736         }
737     }
738
739     __FUNC_EXIT__;
740     return 0;
741 }
742
743 int wfd_client_swtch_force(void *data, int onoff)
744 {
745     __FUNC_ENTER__;
746     struct ug_data *ugd = (struct ug_data*) data;
747     int res;
748
749     if (onoff)
750     {
751         res = wifi_direct_activate();
752         if (res != WIFI_DIRECT_ERROR_NONE)
753         {
754             DBG(LOG_ERROR,
755                 "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
756             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
757
758             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
759             wfd_ug_view_refresh_glitem(ugd->head);
760             return -1;
761         }
762     }
763     else
764     {
765         res = wifi_direct_deactivate();
766         if (res != WIFI_DIRECT_ERROR_NONE)
767         {
768             DBG(LOG_ERROR,
769                 "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
770             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
771
772             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
773             wfd_ug_view_refresh_glitem(ugd->head);
774             return -1;
775         }
776     }
777     __FUNC_EXIT__;
778     return 0;
779 }
780
781 int wfd_client_start_discovery(void *data)
782 {
783     __FUNC_ENTER__;
784     int res;
785     wifi_direct_state_e status;
786
787     wifi_direct_get_state(&status);
788     if (status >= WIFI_DIRECT_STATE_ACTIVATED)
789     {
790         res = wifi_direct_start_discovery(FALSE, 0);
791         if (res != WIFI_DIRECT_ERROR_NONE)
792         {
793             DBG(LOG_ERROR, "Failed to start wfd discovery. [%d]", res);
794         }
795     }
796     __FUNC_EXIT__;
797
798     return 0;
799 }
800
801 int wfd_client_connect(const char *mac_addr)
802 {
803     __FUNC_ENTER__;
804     int res;
805
806     res = wifi_direct_connect(mac_addr);
807     if (res != WIFI_DIRECT_ERROR_NONE)
808     {
809         DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
810         return -1;
811     }
812     __FUNC_EXIT__;
813     return 0;
814 }
815
816 int wfd_client_disconnect(const char *mac_addr)
817 {
818     __FUNC_ENTER__;
819     int res;
820
821     if (mac_addr == NULL)
822     {
823         res = wifi_direct_disconnect_all();
824         if (res != WIFI_DIRECT_ERROR_NONE)
825         {
826             DBG(LOG_ERROR,
827                 "Failed to send disconnection request to all. [%d]\n", res);
828             return -1;
829         }
830     }
831     else
832     {
833         res = wifi_direct_disconnect(mac_addr);
834         if (res != WIFI_DIRECT_ERROR_NONE)
835         {
836             DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
837             return -1;
838         }
839     }
840     __FUNC_EXIT__;
841     return 0;
842 }