d0c3ae9728fe9cad65863365e4dd5c9cbaa84ce2
[apps/home/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 #include <wifi-direct.h>
32
33 #include "wfd_ug.h"
34 #include "wfd_ug_view.h"
35 #include "wfd_client.h"
36
37 static void _wifi_state_cb(keynode_t *key, void *data)
38 {
39     __FUNC_ENTER__;
40     struct ug_data *ugd = (struct ug_data*) data;
41     int res;
42     int wifi_state;
43
44     res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
45     if (res != 0)
46     {
47         DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
48         // TODO: set genlist head item as "WiFi Direct"
49         return;
50     }
51
52     if(wifi_state == VCONFKEY_WIFI_OFF)
53     {
54         DBG(LOG_VERBOSE, "WiFi is turned off\n");
55         wfd_client_swtch_force(ugd, TRUE);
56     }
57     else
58     {
59         DBG(LOG_VERBOSE, "WiFi is turned on\n");
60     }
61
62     res = net_deregister_client();
63     if(res != NET_ERR_NONE)
64     {
65         DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
66     }
67
68     __FUNC_EXIT__;
69 }
70
71 static void _network_event_cb(net_event_info_t *event_info, void *user_data)
72 {
73     __FUNC_ENTER__;
74     DBG(LOG_VERBOSE, "Event from network. [%d]\n", event_info->Event);
75     __FUNC_EXIT__;
76 }
77
78 int wfd_wifi_off(void *data)
79 {
80     __FUNC_ENTER__;
81     struct ug_data *ugd = (struct ug_data*) data;
82     int res;
83
84     res = vconf_notify_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb, ugd);
85     if (res == -1)
86     {
87         DBG(LOG_ERROR, "Failed to register vconf callback\n");
88         return -1;
89     }
90     DBG(LOG_VERBOSE, "Vconf key callback is registered\n");
91     res = net_register_client((net_event_cb_t) _network_event_cb, NULL);
92     if(res != NET_ERR_NONE)
93     {
94         DBG(LOG_ERROR, "Failed to register network client. [%d]\n", res);
95         return -1;
96     }
97     DBG(LOG_VERBOSE, "Network client is registered\n");
98     res = net_wifi_power_off();
99     if(res != NET_ERR_NONE)
100     {
101         DBG(LOG_ERROR, "Failed to turn off wifi. [%d]\n", res);
102         return -1;
103     }
104     DBG(LOG_VERBOSE, "WiFi power off\n");
105     __FUNC_EXIT__;
106     return 0;
107 }
108
109 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
110 {
111         __FUNC_ENTER__;
112
113         if (error != TETHERING_ERROR_NONE) {
114         
115                 if (code != TETHERING_DISABLED_BY_REQUEST) {
116                         return;
117                 }
118                 DBG(LOG_ERROR, "error !!! TETHERING is not disabled.\n");
119                 return;
120         }
121
122         DBG(LOG_VERBOSE, "TETHERING is disabled.\n");
123
124         __FUNC_EXIT__;
125
126         return;
127 }
128
129
130 #if 0
131 static device_type_s *wfd_client_find_peer_by_ssid(void *data, const char *ssid)
132 {
133     __FUNC_ENTER__;
134     struct ug_data *ugd = (struct ug_data*) data;
135     int i;
136
137     if(ugd == NULL)
138     {
139         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
140         return NULL;
141     }
142
143     for(i=0; i<ugd->gl_available_peer_cnt; i++)
144     {
145         DBG(LOG_VERBOSE, "check %dth peer\n", i);
146         if(!strcmp(ugd->gl_available_peers[i].ssid, ssid))
147         {
148             DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
149             __FUNC_EXIT__;
150             return &ugd->gl_available_peers[i];
151         }
152     }
153     __FUNC_EXIT__;
154
155     return NULL;
156 }
157 #endif
158
159 static device_type_s *wfd_client_find_peer_by_mac(void *data, const char *mac_addr)
160 {
161     __FUNC_ENTER__;
162     struct ug_data *ugd = (struct ug_data*) data;
163     int i;
164
165     if(ugd == NULL)
166     {
167         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
168         return NULL;
169     }
170
171     if (ugd->multi_connect_mode != WFD_MULTI_CONNECT_MODE_NONE)
172     {
173                 for(i=0; i<ugd->raw_multi_selected_peer_cnt; i++)
174                 {
175                         DBG(LOG_VERBOSE, "[Multi Connect] check %dth peer\n", i);
176                         if(!strncmp(mac_addr, (const char*) ugd->raw_multi_selected_peers[i].mac_addr, MAC_LENGTH))
177                         {
178                                 DBG(LOG_VERBOSE, "selected found peer. [%d]\n", i);
179                                 __FUNC_EXIT__;
180                                 return &ugd->raw_multi_selected_peers[i];
181                         }
182                 }
183     }
184     else
185     {
186                 for(i=0; i<ugd->raw_discovered_peer_cnt; i++)
187                 {
188                         DBG(LOG_VERBOSE, "check %dth peer\n", i);
189                         if(!strncmp(mac_addr, (const char*) ugd->raw_discovered_peers[i].mac_addr, MAC_LENGTH))
190                         {
191                                 DBG(LOG_VERBOSE, "found peer. [%d]\n", i);
192                                 __FUNC_EXIT__;
193                                 return &ugd->raw_discovered_peers[i];
194                         }
195                 }
196
197     }
198     __FUNC_EXIT__;
199
200     return NULL;
201 }
202
203 int _wfd_ug_view_clean_on_off(struct ug_data *ugd)
204 {
205         wfd_ug_view_update_peers(ugd);
206         return 0;
207 }
208
209 void _activation_cb(int error_code, wifi_direct_device_state_e device_state, void *user_data)
210 {
211     __FUNC_ENTER__;
212     int res;
213     struct ug_data *ugd = (struct ug_data*) user_data;
214
215     wfd_refresh_wifi_direct_state(ugd);
216
217     switch(device_state)
218     {
219         case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
220             DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
221             if(error_code != WIFI_DIRECT_ERROR_NONE)
222             {
223                 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
224                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_ACTIVATE_FAIL);
225
226                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
227                 ugd->wfd_onoff = 0;
228                 wfd_ug_view_refresh_glitem(ugd->head);
229                 return;
230             }
231
232             ugd->head_text_mode = HEAD_TEXT_TYPE_ACTIVATED;
233             ugd->wfd_onoff = 1;
234             wfd_ug_view_refresh_glitem(ugd->head);
235
236             wfg_ug_act_popup_remove(ugd);
237
238             res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
239             if(res == -1)
240             {
241                 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
242             }
243
244             res = wifi_direct_start_discovery(FALSE, 0);
245             if(res != WIFI_DIRECT_ERROR_NONE)
246             {
247                 DBG(LOG_ERROR, "Failed to start discovery. [%d]\n", res);
248             }
249             DBG(LOG_VERBOSE, "Discovery is started\n");
250             break;
251
252         case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
253             DBG(LOG_VERBOSE, "WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
254             if(error_code != WIFI_DIRECT_ERROR_NONE)
255             {
256                 DBG(LOG_ERROR, "Error in Activation/Deactivation [%d]\n", error_code);
257                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_DEACTIVATE_FAIL);
258                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
259                 ugd->wfd_onoff = 1;
260                 wfd_ug_view_refresh_glitem(ugd->head);
261                 return;
262             }
263
264             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
265             ugd->wfd_onoff = 0;
266
267             wfd_ug_view_update_peers(ugd);
268
269             break;
270         default:
271             break;
272     }
273
274     wfd_ug_view_refresh_glitem(ugd->head);
275
276     if (ugd->scan_btn) {
277         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
278     }
279
280     if (ugd->multi_connect_btn) {
281         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
282     }
283
284     __FUNC_EXIT__;
285     return;
286 }
287
288 bool _wfd_discoverd_peer_cb(wifi_direct_discovered_peer_info_s* peer, void *user_data)
289 {
290     __FUNC_ENTER__;
291
292     struct ug_data *ugd = (struct ug_data*) user_data;
293     int peer_cnt = ugd->raw_discovered_peer_cnt;
294
295     DBG(LOG_VERBOSE, "%dth discovered peer. [%s] [%s]\n", peer_cnt, peer->ssid, peer->mac_address);
296
297     strncpy(ugd->raw_discovered_peers[peer_cnt].ssid, peer->ssid, sizeof(ugd->raw_discovered_peers[peer_cnt].ssid));
298     ugd->raw_discovered_peers[peer_cnt].category = peer->primary_device_type;
299     strncpy(ugd->raw_discovered_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
300     strncpy(ugd->raw_discovered_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
301     ugd->raw_discovered_peers[peer_cnt].is_group_owner = peer->is_group_owner;
302     ugd->raw_discovered_peers[peer_cnt].is_persistent_group_owner = peer->is_persistent_group_owner;
303     ugd->raw_discovered_peers[peer_cnt].is_connected = peer->is_connected;
304
305     if (TRUE == peer->is_connected) {
306         ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
307     } else {
308         ugd->raw_discovered_peers[peer_cnt].conn_status = PEER_CONN_STATUS_DISCONNECTED;
309     }
310
311     DBG(LOG_VERBOSE, "\tSSID: [%s]\n", ugd->raw_discovered_peers[peer_cnt].ssid);
312     DBG(LOG_VERBOSE, "\tPeer category [%d] -> [%d]\n", peer->primary_device_type, ugd->raw_discovered_peers[peer_cnt].category);
313     DBG(LOG_VERBOSE, "\tStatus: [%d]\n", ugd->raw_discovered_peers[peer_cnt].conn_status);
314
315     ugd->raw_discovered_peer_cnt ++;
316
317     free(peer->ssid);
318     free(peer->mac_address);
319     free(peer->interface_address);
320     free(peer);
321
322     __FUNC_EXIT__;
323     return TRUE;
324 }
325
326 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s* peer, void *user_data)
327 {
328     __FUNC_ENTER__;
329     struct ug_data *ugd = (struct ug_data*) user_data;
330     int peer_cnt = ugd->raw_connected_peer_cnt;
331
332     DBG(LOG_VERBOSE, "%dth connected peer. [%s] [%s]\n", peer_cnt, peer->ssid, peer->mac_address);
333
334     strncpy(ugd->raw_connected_peers[peer_cnt].ssid, peer->ssid, sizeof(ugd->raw_connected_peers[peer_cnt].ssid));
335     ugd->raw_connected_peers[peer_cnt].category = peer->primary_device_type;
336     strncpy(ugd->raw_connected_peers[peer_cnt].mac_addr, peer->mac_address, MAC_LENGTH);
337     strncpy(ugd->raw_connected_peers[peer_cnt].if_addr, peer->interface_address, MAC_LENGTH);
338     ugd->raw_connected_peers[peer_cnt].conn_status = PEER_CONN_STATUS_CONNECTED;
339
340     DBG(LOG_VERBOSE, "\tStatus: [%d]\n", ugd->raw_connected_peers[peer_cnt].conn_status);
341     DBG(LOG_VERBOSE, "\tCategory: [%d]\n", ugd->raw_connected_peers[peer_cnt].category);
342     DBG(LOG_VERBOSE, "\tSSID: [%s]\n", ugd->raw_connected_peers[peer_cnt].ssid);
343
344     ugd->raw_connected_peer_cnt++;
345
346     free(peer->ssid);
347     free(peer->mac_address);
348     free(peer->interface_address);
349     free(peer);
350     __FUNC_EXIT__;
351     return TRUE;
352 }
353
354 int wfd_ug_get_discovered_peers(struct ug_data *ugd)
355 {
356         int res = 0;
357
358         if (ugd==NULL)
359                 return -1;
360
361         ugd->raw_discovered_peer_cnt = 0;
362     res = wifi_direct_foreach_discovered_peers(_wfd_discoverd_peer_cb, (void*) ugd);
363     if (res != WIFI_DIRECT_ERROR_NONE)
364     {
365         ugd->raw_discovered_peer_cnt = 0;
366         DBG(LOG_ERROR, "Get discovery result failed: %d\n", res);
367     }
368
369         return 0;
370 }
371
372
373 int wfd_ug_get_connected_peers(struct ug_data *ugd)
374 {
375         int res = 0;
376
377         if (ugd==NULL)
378                 return -1;
379
380         ugd->raw_connected_peer_cnt = 0;
381         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void*) ugd);
382         if(res != WIFI_DIRECT_ERROR_NONE)
383         {
384                 ugd->raw_connected_peer_cnt = 0;
385                 DBG(LOG_ERROR, "Get connected peer failed: %d\n", res);
386         }
387         return 0;
388 }
389
390 void _discover_cb(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
391 {
392     __FUNC_ENTER__;
393     struct ug_data *ugd = (struct ug_data*) user_data;
394
395     if(ugd == NULL)
396     {
397         DBG(LOG_ERROR, "Incorrect parameter(NULL)\n");
398         return;
399     }
400
401     if(discovery_state == WIFI_DIRECT_ONLY_LISTEN_STARTED)
402     {
403         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
404     }
405     else if(discovery_state == WIFI_DIRECT_DISCOVERY_STARTED)
406     {
407         ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
408     }
409     else if(discovery_state == WIFI_DIRECT_DISCOVERY_FOUND)
410     {
411         ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
412     }
413
414     wfd_ug_view_refresh_glitem(ugd->head);
415
416     if (WIFI_DIRECT_DISCOVERY_STARTED == discovery_state) {
417         if (ugd->scan_btn) {
418                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
419         }
420
421         if (ugd->multi_connect_btn) {
422                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_STOPSCAN"), TRUE);
423         }
424     } else {
425         if (ugd->scan_btn) {
426                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
427         }
428
429         if (ugd->multi_connect_btn) {
430                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
431         }
432     }
433
434     wfd_ug_get_discovered_peers(ugd);
435     wfd_ug_get_connected_peers(ugd);
436
437     wfd_ug_view_update_peers(ugd);
438
439     _wfd_free_multiconnect_device(ugd);
440     _wfd_update_multiconnect_device(ugd);
441     //_change_multi_button_title(ugd);
442
443     __FUNC_EXIT__;
444     return;
445 }
446
447 void _connection_cb(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
448 {
449     __FUNC_ENTER__;
450
451     struct ug_data *ugd = (struct ug_data*) user_data;
452     device_type_s *peer = NULL;
453     bool owner = FALSE;
454     int res = 0;
455
456     DBG(LOG_VERBOSE, "Connection event [%d], error_code [%d]\n", connection_state, error_code);
457
458     if(mac_address == NULL)
459     {
460         DBG(LOG_ERROR, "Incorrect parameter(peer mac is NULL)\n");
461         return;
462     }
463     DBG(LOG_VERBOSE, "Connection event from %s", mac_address);
464
465     if (ugd->multi_connect_mode == WFD_MULTI_CONNECT_MODE_IN_PROGRESS)
466     {
467         peer = wfd_client_find_peer_by_mac(ugd, mac_address);
468         if (peer != NULL)
469         {
470                         switch(connection_state)
471                         {
472                         case WIFI_DIRECT_CONNECTION_RSP:
473                                 if(error_code == WIFI_DIRECT_ERROR_NONE)
474                                 {
475                                         ugd->wfd_status = WFD_LINK_STATUS_CONNECTED;
476                                         peer->conn_status = PEER_CONN_STATUS_CONNECTED;
477                                 }
478                                 else
479                                 {
480                                         peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
481                                 }
482                                 ugd->g_source_multi_connect_next = g_timeout_add(1000, wfd_multi_connect_next_cb, ugd);
483                                 break;
484                         default:
485                                 break;
486                         }
487                         wfd_ug_get_connected_peers(ugd);
488                         wfd_ug_view_update_peers(ugd);
489         }
490         else
491         {
492             DBG(LOG_VERBOSE, "peer is not found [%s]", mac_address);
493         }
494         goto refresh_button;
495     }
496
497
498     peer = wfd_client_find_peer_by_mac(ugd, mac_address);
499
500     if (NULL == peer || NULL == peer->ssid) {
501             DBG(LOG_ERROR, "SSID from connection is NULL !!\n");
502             goto refresh_button;
503     }
504
505     switch(connection_state)
506     {
507         case WIFI_DIRECT_CONNECTION_RSP:
508             DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_RSP\n");
509
510             if(error_code == WIFI_DIRECT_ERROR_NONE)
511             {
512                 ugd->wfd_status = WFD_LINK_STATUS_CONNECTED;
513                 peer->conn_status = PEER_CONN_STATUS_CONNECTED;
514             }
515             else
516             {
517                 peer->conn_status = PEER_CONN_STATUS_FAILED_TO_CONNECT;
518             }
519
520             wfd_ug_get_connected_peers(ugd);
521             wfd_ug_view_update_peers(ugd);
522             break;
523         case WIFI_DIRECT_DISCONNECTION_RSP:
524         case WIFI_DIRECT_DISCONNECTION_IND:
525         case WIFI_DIRECT_DISASSOCIATION_IND:
526             DBG(LOG_VERBOSE, "WIFI_DIRECT_DISCONNECTION_X\n");
527             if(error_code != WIFI_DIRECT_ERROR_NONE)
528             {
529                 // TODO: show disconnection error popup
530                 return;
531             }
532
533             if (peer!=NULL)
534                 peer->conn_status = PEER_CONN_STATUS_DISCONNECTED;
535             else
536             {
537                 // In case of disconnect_all(), no specific peer is found.
538             }
539
540             wifi_direct_start_discovery(FALSE, 0);
541             ugd->wfd_status = WFD_LINK_STATUS_DISCOVERING;
542             ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
543
544             wfd_ug_view_refresh_glitem(ugd->head);
545
546             wfd_ug_get_discovered_peers(ugd);
547             wfd_ug_get_connected_peers(ugd);
548             wfd_ug_view_update_peers(ugd);
549             break;
550
551         case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
552             DBG(LOG_VERBOSE, "WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
553             peer->conn_status = PEER_CONN_STATUS_CONNECTING;
554             break;
555         case WIFI_DIRECT_CONNECTION_REQ:
556         case WIFI_DIRECT_CONNECTION_WPS_REQ:
557             DBG(LOG_VERBOSE, "WIFI_DIRECT_CLI_EVENT_CONNECTION_REQ\n");
558             break;
559         default:
560             break;
561     }
562
563     if(peer != NULL)
564         wfd_ug_view_refresh_glitem(peer->gl_item);
565
566     _change_multi_button_title(ugd);
567
568 refresh_button:
569     /* refresh the scan button */
570     wfd_refresh_wifi_direct_state(ugd);
571     if (WIFI_DIRECT_STATE_CONNECTING == ugd->wfd_status ||
572             WIFI_DIRECT_STATE_DISCONNECTING == ugd->wfd_status) {
573
574         res = wifi_direct_is_group_owner(&owner);
575         if (res == WIFI_DIRECT_ERROR_NONE) {
576             if (!owner) {
577                 if (ugd->scan_btn) {
578                         wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
579                 }
580
581                 if (ugd->multi_connect_btn) {
582                         wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), FALSE);
583                 }
584             }
585         } else {
586             DBG(LOG_ERROR, "Failed to get whether client is group owner. [%d]\n", res);
587         }
588     } else {
589         if (ugd->scan_btn) {
590                 wfd_ug_view_refresh_button(ugd->scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
591         }
592
593         if (ugd->multi_connect_btn) {
594                 wfd_ug_view_refresh_button(ugd->multi_scan_btn, _("IDS_WFD_BUTTON_SCAN"), TRUE);
595         }
596     }
597
598     __FUNC_EXIT__;
599     return;
600 }
601
602 int wfd_get_vconf_status(void *data)
603 {
604     __FUNC_ENTER__;
605     struct ug_data *ugd = (struct ug_data*) data;
606     char *dev_name;
607
608     // TODO: get wifi direct status from vconf
609     // db/mobile_hotspot/wifi_key (string)
610
611     dev_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);  // "db/setting/device_name" (VCONF_WFD_APNAME)
612     if (dev_name == NULL)
613     {
614         ugd->dev_name = strdup(DEFAULT_DEV_NAME);
615         DBG(LOG_ERROR, "The AP name is NULL(setting default value)\n");
616     }
617     else
618     {
619         ugd->dev_name = strdup(dev_name);
620         free(dev_name);
621     }
622
623     __FUNC_EXIT__;
624
625     return 0;
626 }
627
628 int wfd_refresh_wifi_direct_state(void *data)
629 {
630     struct ug_data *ugd = (struct ug_data*) data;
631         int res;
632         wifi_direct_state_e wfd_status;
633     res = wifi_direct_get_state(&wfd_status);
634     if(res != WIFI_DIRECT_ERROR_NONE)
635     {
636         DBG(LOG_ERROR, "Failed to get link status. [%d]\n", res);
637         return -1;
638     }
639     DBG(LOG_VERBOSE, "WFD status [%d]", wfd_status);
640     ugd->wfd_status = wfd_status;
641     return 0;
642 }
643
644 int init_wfd_client(void *data)
645 {
646     __FUNC_ENTER__;
647     struct ug_data *ugd = (struct ug_data*) data;
648     int res = 0;
649
650     res = wifi_direct_initialize();
651     if(res != WIFI_DIRECT_ERROR_NONE)
652     {
653         DBG(LOG_ERROR, "Failed to initialize wifi direct. [%d]\n", res);
654         return -1;
655     }
656
657     res = wifi_direct_set_device_state_changed_cb(_activation_cb, (void*) ugd);
658     res = wifi_direct_set_discovery_state_changed_cb(_discover_cb, (void*) ugd);
659     res = wifi_direct_set_connection_state_changed_cb(_connection_cb, (void*) ugd);
660
661     /* update WFD status */
662     wfd_refresh_wifi_direct_state(ugd);
663     if (ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
664         ugd->wfd_onoff = 1;
665     else
666         ugd->wfd_onoff = 0;
667
668     DBG(LOG_VERBOSE, "WFD link status. [%d]\n", ugd->wfd_status);
669
670     __FUNC_EXIT__;
671
672     return 0;
673 }
674
675 int deinit_wfd_client(void *data)
676 {
677         __FUNC_ENTER__;
678         struct ug_data *ugd = (struct ug_data*) data;
679         int res = 0;
680         tethering_error_e ret = TETHERING_ERROR_NONE;
681         tethering_h th = NULL;
682
683         wfd_refresh_wifi_direct_state(ugd);
684
685         if(ugd->wfd_status == WIFI_DIRECT_STATE_DISCOVERING)
686         {
687                 DBG(LOG_VERBOSE, "Stop discovery before deregister client\n");
688                 wifi_direct_cancel_discovery();
689         }
690
691         res = wifi_direct_deinitialize();
692         if(res != WIFI_DIRECT_ERROR_NONE)
693         {
694                 DBG(LOG_ERROR, "Failed to deregister client. [%d]\n", res);
695         }
696
697         res = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wifi_state_cb);
698         if(res == -1)
699         {
700                 DBG(LOG_ERROR, "Failed to ignore vconf key callback for wifi state\n");
701         }
702
703         res = net_deregister_client();
704         if(res != NET_ERR_NONE)
705         {
706                 DBG(LOG_ERROR, "Failed to deregister network client. [%d]\n", res);
707         }
708
709         __FUNC_EXIT__;
710
711         return 0;
712 }
713
714 int wfd_client_switch_on(void *data)
715 {
716     __FUNC_ENTER__;
717     struct ug_data *ugd = (struct ug_data*) data;
718     int res;
719
720     DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
721
722     if(ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
723     {
724         ugd->wfd_status = WFD_LINK_STATUS_ACTIVATING;
725
726         int wifi_state;
727         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
728         if (res != 0)
729         {
730             DBG(LOG_ERROR, "Failed to get wifi state from vconf. [%d]\n", res);
731             // TODO: set genlist head item as "WiFi Direct"
732             return -1;
733         }
734
735         if(wifi_state > VCONFKEY_WIFI_OFF)
736         {
737             DBG(LOG_VERBOSE, "WiFi is connected, so have to turn off WiFi");
738             wfd_ug_act_popup(ugd, _("IDS_WFD_POP_WIFI_OFF"), POPUP_TYPE_WIFI_OFF); // "This will turn off Wi-Fi client operation.<br>Continue?"
739         }
740         else    // (wifi_state < VCONFKEY_WIFI_CONNECTED && !(hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI))
741         {
742             res = wifi_direct_activate();
743             if(res != WIFI_DIRECT_ERROR_NONE)
744             {
745                 DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
746                 wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
747
748                 ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
749                 wfd_ug_view_refresh_glitem(ugd->head);
750                 return -1;
751             }
752         }
753     }
754     else
755     {
756         DBG(LOG_VERBOSE, "Wi-Fi Direct is already activated\n");
757     }
758
759     __FUNC_EXIT__;
760     return 0;
761 }
762
763 int wfd_client_switch_off(void *data)
764 {
765     __FUNC_ENTER__;
766     struct ug_data *ugd = (struct ug_data*) data;
767     int res;
768
769     DBG(LOG_VERBOSE, "WFD status [%d]\n", ugd->wfd_status);
770
771     if(ugd->wfd_status < WFD_LINK_STATUS_ACTIVATING)
772     {
773         DBG(LOG_VERBOSE, "Wi-Fi Direct is already deactivated\n");
774     }
775     else
776     {
777         ugd->wfd_status = WFD_LINK_STATUS_DEACTIVATING;
778
779         res = wifi_direct_deactivate();
780         if(res != WIFI_DIRECT_ERROR_NONE)
781         {
782             DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
783             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
784
785             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
786             wfd_ug_view_refresh_glitem(ugd->head);
787             return -1;
788         }
789     }
790
791     __FUNC_EXIT__;
792     return 0;
793 }
794
795 int wfd_client_swtch_force(void *data, int onoff)
796 {
797     __FUNC_ENTER__;
798     struct ug_data *ugd = (struct ug_data*) data;
799     int res;
800
801     if(onoff)
802     {
803         res = wifi_direct_activate();
804         if(res != WIFI_DIRECT_ERROR_NONE)
805         {
806             DBG(LOG_ERROR, "Failed to activate Wi-Fi Direct. error code = [%d]\n", res);
807             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_ACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
808
809             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
810             wfd_ug_view_refresh_glitem(ugd->head);
811             return -1;
812         }
813     }
814     else
815     {
816         res = wifi_direct_deactivate();
817         if(res != WIFI_DIRECT_ERROR_NONE)
818         {
819             DBG(LOG_ERROR, "Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
820             wfd_ug_warn_popup(ugd, _("IDS_WFD_POP_DEACTIVATE_FAIL"), POPUP_TYPE_TERMINATE);
821
822             ugd->head_text_mode = HEAD_TEXT_TYPE_DIRECT;
823             wfd_ug_view_refresh_glitem(ugd->head);
824             return -1;
825         }
826     }
827     __FUNC_EXIT__;
828     return 0;
829 }
830
831 int wfd_client_start_discovery(void *data)
832 {
833     __FUNC_ENTER__;
834     struct ug_data *ugd = (struct ug_data*) data;
835     int res = -1;
836
837 #if 0
838     ret = wifi_direct_cancel_discovery();
839 //    ret = wifi_direct_cancel_discovery();
840     if (ret != WIFI_DIRECT_ERROR_NONE) {
841         DBG(LOG_ERROR, "Failed wfd discover() : %d", ret);
842         return FALSE;
843     }
844
845
846     if(ugd->wfd_status >= WIFI_DIRECT_STATE_ACTIVATED)
847     {
848         res = wifi_direct_start_discovery(FALSE, 30);
849         if (res != WIFI_DIRECT_ERROR_NONE)
850         {
851             DBG(LOG_ERROR, "Failed to start wfd discovery. [%d]", res);
852             return -1;
853         }
854     }
855 #endif
856
857     ugd->wfd_status = WIFI_DIRECT_DISCOVERY_STARTED;
858     wfd_refresh_wifi_direct_state(ugd);
859     ugd->head_text_mode = HEAD_TEXT_TYPE_SCANING;
860     wfd_ug_view_refresh_glitem(ugd->head);
861     wifi_direct_cancel_discovery();
862
863     res = wifi_direct_start_discovery(FALSE, 0);
864     if (res != WIFI_DIRECT_ERROR_NONE) {
865         DBG(LOG_ERROR, "Fail to restart scanning. %d\n", res);
866         return -1;
867     }
868
869     ugd->wfd_status = WIFI_DIRECT_DISCOVERY_FOUND;
870     wfd_refresh_wifi_direct_state(ugd);
871
872     __FUNC_EXIT__;
873     return 0;
874 }
875
876 int wfd_client_connect(const char *mac_addr)
877 {
878     __FUNC_ENTER__;
879     int res;
880
881     DBG(LOG_ERROR, "connect to peer=[%s]\n", mac_addr);
882     res = wifi_direct_connect(mac_addr);
883     if(res != WIFI_DIRECT_ERROR_NONE)
884     {
885         DBG(LOG_ERROR, "Failed to send connection request. [%d]\n", res);
886         return -1;
887     }
888     __FUNC_EXIT__;
889     return 0;
890 }
891
892 int wfd_client_disconnect(const char *mac_addr)
893 {
894     __FUNC_ENTER__;
895     int res;
896
897     if(mac_addr == NULL)
898     {
899         res = wifi_direct_disconnect_all();
900         if(res != WIFI_DIRECT_ERROR_NONE)
901         {
902             DBG(LOG_ERROR, "Failed to send disconnection request to all. [%d]\n", res);
903             return -1;
904         }
905     }
906     else
907     {
908         res = wifi_direct_disconnect(mac_addr);
909         if(res != WIFI_DIRECT_ERROR_NONE)
910         {
911             DBG(LOG_ERROR, "Failed to send disconnection request. [%d]\n", res);
912             return -1;
913         }
914     }
915     __FUNC_EXIT__;
916     return 0;
917 }
918
919 int wfd_client_set_p2p_group_owner_intent(int go_intent)
920 {
921     __FUNC_ENTER__;
922     int res;
923
924         res = wifi_direct_set_group_owner_intent(go_intent);
925         if(res != WIFI_DIRECT_ERROR_NONE)
926         {
927                 DBG(LOG_ERROR, "Failed to wifi_direct_set_go_intent(%d). [%d]\n", go_intent, res);
928                 return -1;
929         }
930     __FUNC_EXIT__;
931     return 0;
932 }
933
934 int wfd_client_get_peers(struct ug_data *ugd)
935 {
936
937         if(ugd->wfd_status < WFD_LINK_STATUS_ACTIVATED)
938         {
939                 ugd->raw_discovered_peer_cnt = 0;
940                 ugd->raw_connected_peer_cnt = 0;
941                 return 0;
942         }
943
944     if(ugd->wfd_status > WIFI_DIRECT_STATE_ACTIVATING)
945     {
946         wfd_ug_get_discovered_peers(ugd);
947     }
948
949     if(ugd->wfd_status >= WIFI_DIRECT_STATE_CONNECTED)
950     {
951         wfd_ug_get_connected_peers(ugd);
952     }
953
954     wfd_ug_view_update_peers(ugd);
955     _change_multi_button_title(ugd);
956     return 0;
957 }