printf removed
[apps/native/ug-wifi-direct.git] / popup-wifidirect / src / wfd-app-client.c
1 /*
2 *  WiFi-Direct UG
3 *
4 * Copyright 2012 Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://floralicense.org/license
11
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 /**
21  * This file implements wifi direct application client  functions.
22  *
23  * @file    wfd-app-client.c
24  * @author  Sungsik Jang (sungsik.jang@samsung.com)
25  * @version 0.1
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <notification.h>
33 #include <vconf.h>
34
35 #include "wfd-app.h"
36 #include "wfd-app-util.h"
37 #include "wfd-app-strings.h"
38
39 /**
40  *      This function let the app make a callback for connected peer
41  *      @return   TRUE
42  *      @param[in] peer the pointer to the connected peer
43  *      @param[in] user_data the pointer to the main data structure
44  */
45 bool _wfd_connected_peer_cb(wifi_direct_connected_peer_info_s *peer, void *user_data)
46 {
47         __WDPOP_LOG_FUNC_ENTER__;
48
49         wfd_appdata_t *ad = (wfd_appdata_t *) user_data;
50         if (NULL == ad || NULL == peer || NULL == peer->device_name || NULL == peer->mac_address) {
51                 WDPOP_LOGD( "NULL parameters.\n");
52                 return FALSE;
53         }
54
55         int peer_cnt = ad->raw_connected_peer_cnt;
56         WDPOP_LOGD( "%dth connected peer. [%s]\n", peer_cnt, peer->device_name);
57
58         strncpy(ad->raw_connected_peers[peer_cnt].ssid, peer->device_name, sizeof(ad->raw_connected_peers[peer_cnt].ssid));
59         ad->raw_connected_peers[peer_cnt].ssid[31] = '\0';
60         strncpy(ad->raw_connected_peers[peer_cnt].mac_address, peer->mac_address, WFD_MAC_ADDRESS_SIZE);
61         ad->raw_connected_peers[peer_cnt].mac_address[17] = '\0';
62         WDPOP_LOGD( "\tSSID: [%s]\n", ad->raw_connected_peers[peer_cnt].ssid);
63         ad->raw_connected_peer_cnt++;
64
65         free(peer->device_name);
66         free(peer->mac_address);
67         free(peer);
68
69         __WDPOP_LOG_FUNC_EXIT__;
70         return TRUE;
71 }
72
73 /**
74  *      This function let the app get the connected peers
75  *      @return   If success, return 0, else return -1
76  *      @param[in] ugd the pointer to the main data structure
77  */
78 int _wfd_app_get_connected_peers(void *user_data)
79 {
80         __WDPOP_LOG_FUNC_ENTER__;
81
82         wfd_appdata_t *ad = (wfd_appdata_t *) user_data;
83         if (NULL == ad) {
84                 WDPOP_LOGD( "NULL parameters.\n");
85                 return -1;
86         }
87
88         int res = 0;
89
90         ad->raw_connected_peer_cnt = 0;
91         res = wifi_direct_foreach_connected_peers(_wfd_connected_peer_cb, (void *)ad);
92         if (res != WIFI_DIRECT_ERROR_NONE) {
93                 ad->raw_connected_peer_cnt = 0;
94                 WDPOP_LOGD( "Get connected peer failed: %d\n", res);
95         }
96
97         __WDPOP_LOG_FUNC_EXIT__;
98         return 0;
99 }
100
101 /**
102  *      This function let the app delete the notification
103  *      @return   void
104  */
105 void _del_wfd_notification()
106 {
107         __WDPOP_LOG_FUNC_ENTER__;
108
109         /* delete the notification */
110         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
111         noti_err  = notification_delete_all_by_type(NULL, NOTIFICATION_TYPE_NOTI);
112         if (noti_err != NOTIFICATION_ERROR_NONE) {
113                 WDPOP_LOGD( "Fail to notification_delete_all_by_type.(%d)\n", noti_err);
114                 return;
115         }
116
117         __WDPOP_LOG_FUNC_EXIT__;
118 }
119
120 /**
121  *      This function let the app add the notification when it is connected
122  *      @return   void
123  *      @param[in] user_data the pointer to the main data structure
124  */
125 void _add_wfd_peers_connected_notification(void *user_data)
126 {
127         __WDPOP_LOG_FUNC_ENTER__;
128
129         wfd_appdata_t *ad = (wfd_appdata_t *) user_data;
130         if (NULL == ad || NULL == ad->noti) {
131                 WDPOP_LOGD( "NULL parameters.\n");
132                 return;
133         }
134
135         char msg[WFD_MAX_SIZE] = {0};
136         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
137
138         /* delete all notifications */
139         _del_wfd_notification();
140
141         /* set the icon */
142         noti_err = notification_set_image(ad->noti, NOTIFICATION_IMAGE_TYPE_ICON,  RESDIR"/images/A09_notification_icon.png");
143         if (noti_err != NOTIFICATION_ERROR_NONE) {
144                 WDPOP_LOGD( "Fail to notification_set_image. (%d)\n", noti_err);
145                 return;
146         }
147
148         /* set the title and content */
149         _wfd_app_get_connected_peers(ad);
150         snprintf(msg, WFD_MAX_SIZE, "Connected with %d devices via Wi-Fi Direct", ad->raw_connected_peer_cnt);
151         noti_err = notification_set_text(ad->noti, NOTIFICATION_TEXT_TYPE_TITLE, msg, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
152         if (noti_err != NOTIFICATION_ERROR_NONE) {
153                 WDPOP_LOGD( "Fail to notification_set_text. (%d)\n", noti_err);
154                 return;
155         }
156
157         noti_err = notification_set_text(ad->noti, NOTIFICATION_TEXT_TYPE_CONTENT,
158                 "Tap to change settings", NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
159         if (noti_err != NOTIFICATION_ERROR_NONE) {
160                 WDPOP_LOGD( "Fail to notification_set_text. (%d)\n", noti_err);
161                 return;
162         }
163
164         bundle *b = NULL;
165         b = bundle_create();
166         appsvc_set_pkgname(b, PACKAGE);
167         appsvc_add_data(b, NOTIFICATION_BUNDLE_PARAM, NOTIFICATION_BUNDLE_VALUE);
168
169         int res = NOTIFICATION_ERROR_NONE;
170         res = notification_set_execute_option(ad->noti, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, /*Button Text*/NULL, NULL, b);
171         if (res != NOTIFICATION_ERROR_NONE) {
172                 WDPOP_LOGD( "Failed to notification_set_execute_option. [%d]", res);
173                 bundle_free(b);
174                 return;
175         }
176         bundle_free(b);
177
178         /* set display application list */
179         noti_err = notification_set_display_applist(ad->noti, NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY);
180         if (noti_err != NOTIFICATION_ERROR_NONE) {
181                 WDPOP_LOGD( "Fail to notification_set_display_applist : %d\n", noti_err);
182                 return;
183         }
184
185         /* notify the quick panel */
186         noti_err = notification_insert(ad->noti, NULL);
187         if (noti_err != NOTIFICATION_ERROR_NONE) {
188                 WDPOP_LOGD( "Fail to notification_insert.(%d)\n", noti_err);
189                 return;
190         }
191
192         __WDPOP_LOG_FUNC_EXIT__;
193 }
194
195 /**
196  *      This function let the app add the notification when it shoule be turned off
197  *      @return   void
198  *      @param[in] user_data the pointer to the main data structure
199  */
200 void _add_wfd_turn_off_notification(void *user_data)
201 {
202         __WDPOP_LOG_FUNC_ENTER__;
203
204         wfd_appdata_t *ad = (wfd_appdata_t *) user_data;
205         if (NULL == ad || NULL == ad->noti) {
206                 WDPOP_LOGD( "NULL parameters.\n");
207                 return;
208         }
209
210         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
211
212         /* delete all notifications */
213         _del_wfd_notification();
214
215         /* set the icon */
216         noti_err = notification_set_image(ad->noti, NOTIFICATION_IMAGE_TYPE_ICON,  RESDIR"/images/A09_notification_icon.png");
217         if (noti_err != NOTIFICATION_ERROR_NONE) {
218                 WDPOP_LOGD( "Fail to notification_set_image. (%d)\n", noti_err);
219                 return;
220         }
221
222         /* set the title and content */
223         noti_err = notification_set_text(ad->noti, NOTIFICATION_TEXT_TYPE_TITLE,
224                 "Disable Wi-Fi Direct after use", NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
225         if (noti_err != NOTIFICATION_ERROR_NONE) {
226                 WDPOP_LOGD( "Fail to notification_set_text. (%d)\n", noti_err);
227                 return;
228         }
229
230         noti_err = notification_set_text(ad->noti, NOTIFICATION_TEXT_TYPE_CONTENT,
231                 "Disable Wi-Fi Direct after use to save battery", NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
232         if (noti_err != NOTIFICATION_ERROR_NONE) {
233                 WDPOP_LOGD( "Fail to notification_set_text. (%d)\n", noti_err);
234                 return;
235         }
236
237         bundle *b = NULL;
238         b = bundle_create();
239         appsvc_set_pkgname(b, PACKAGE);
240         appsvc_add_data(b, NOTIFICATION_BUNDLE_PARAM, NOTIFICATION_BUNDLE_VALUE);
241
242         int res = NOTIFICATION_ERROR_NONE;
243         res = notification_set_execute_option(ad->noti, NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH, /*Button Text*/NULL, NULL, b);
244         if (res != NOTIFICATION_ERROR_NONE) {
245                 WDPOP_LOGD( "Failed to notification_set_execute_option. [%d]", res);
246                 bundle_free(b);
247                 return;
248         }
249         bundle_free(b);
250
251         /* set display application list */
252         noti_err = notification_set_display_applist(ad->noti, NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY);
253         if (noti_err != NOTIFICATION_ERROR_NONE) {
254                 WDPOP_LOGD( "Fail to notification_set_display_applist : %d\n", noti_err);
255                 return;
256         }
257
258         /* notify the quick panel */
259         noti_err = notification_insert(ad->noti, NULL);
260         if (noti_err != NOTIFICATION_ERROR_NONE) {
261                 WDPOP_LOGD( "Fail to notification_insert.(%d)\n", noti_err);
262                 return;
263         }
264
265         __WDPOP_LOG_FUNC_EXIT__;
266 }
267
268 /**
269  *      This function let the app make a callback for deactivating wfd automatically when connected
270  *      @return   if stop the timer, return ECORE_CALLBACK_CANCEL, else return ECORE_CALLBACK_RENEW
271  *      @param[in] user_data the pointer to the main data structure
272  */
273 static Eina_Bool _wfd_automatic_deactivated_for_connection_cb(void *user_data)
274 {
275         int interval = 0;
276         int wfd_transfer_state = 0;
277         wfd_appdata_t *ad = (wfd_appdata_t *)user_data;
278
279         if (NULL == ad) {
280                 WDPOP_LOGD( "NULL parameters.\n");
281                 return ECORE_CALLBACK_CANCEL;
282         }
283
284         /* check the timeout, if not timeout, keep the cb */
285         interval = time(NULL) - ad->last_wfd_transmit_time;
286         if (interval < NO_ACTION_TIME_OUT) {
287                 return ECORE_CALLBACK_RENEW;
288         }
289
290         /* get transfer state */
291         if (vconf_get_int(VCONFKEY_WIFI_DIRECT_TRANSFER_STATE, &wfd_transfer_state) < 0) {
292                 WDPOP_LOGD( "Error reading vconf (%s)\n",
293                         VCONFKEY_WIFI_DIRECT_TRANSFER_STATE);
294                 return ECORE_CALLBACK_CANCEL;
295         }
296
297         /* show tickernoti*/
298         if (wfd_transfer_state > VCONFKEY_WIFI_DIRECT_TRANSFER_START) {
299                 WDPOP_LOGD( "No RX/TX packet, turn off WFD automatically.\n");
300                 _add_wfd_turn_off_notification(ad);
301         } else {
302                 WDPOP_LOGD( "Has RX/TX packet, restart.\n");
303                 ad->last_wfd_transmit_time = time(NULL);
304                 return ECORE_CALLBACK_RENEW;
305         }
306
307         return ECORE_CALLBACK_CANCEL;
308 }
309
310 /**
311  *      This function let the app make a callback for registering activation event
312  *      @return   void
313  *      @param[in] error_code the returned error code
314  *      @param[in] device_state the state of device
315  *      @param[in] user_data the pointer to the main data structure
316  */
317 void _cb_activation(int error_code, wifi_direct_device_state_e device_state, void *user_data)
318 {
319         __WDPOP_LOG_FUNC_ENTER__;
320         wfd_appdata_t *ad = (wfd_appdata_t *)user_data;
321
322         switch (device_state) {
323         case WIFI_DIRECT_DEVICE_STATE_ACTIVATED:
324                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DEVICE_STATE_ACTIVATED\n");
325                 break;
326
327         case WIFI_DIRECT_DEVICE_STATE_DEACTIVATED:
328                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DEVICE_STATE_DEACTIVATED\n");
329                 WDPOP_LOGD( "Termination process of wifi-direct popup begins...\n");
330
331                 /* when deactivated, stop the timer */
332                 if (ad->transmit_timer) {
333                         ecore_timer_del(ad->transmit_timer);
334                         ad->transmit_timer = NULL;
335                 }
336
337                 elm_exit();
338                 break;
339
340         default:
341                 break;
342         }
343
344         __WDPOP_LOG_FUNC_EXIT__;
345 }
346
347 /**
348  *      This function let the app find the peer by mac address
349  *      @return   the found peer
350  *      @param[in] data the pointer to the main data structure
351  *      @param[in] mac_address the pointer to mac address
352  */
353 static wfd_device_info_t *_wfd_app_find_peer_by_mac_address(void *data, const char *mac_address)
354 {
355         __WDPOP_LOG_FUNC_ENTER__;
356         wfd_appdata_t *ad = (wfd_appdata_t *) data;
357         int i;
358
359         if (ad == NULL) {
360                 WDPOP_LOGD( "Incorrect parameter(NULL)\n");
361                 return NULL;
362         }
363
364         WDPOP_LOGD( "find peer by MAC [%s] \n", mac_address);
365
366         for (i = 0; i < ad->discovered_peer_count; i++) {
367                 WDPOP_LOGD( "check %dth peer\n", i);
368
369                 if (!strncmp(mac_address, (const char *) ad->discovered_peers[i].mac_address, 18)) {
370                         WDPOP_LOGD( "found peer. [%d]\n", i);
371                         __WDPOP_LOG_FUNC_EXIT__;
372                         return &ad->discovered_peers[i];
373                 }
374         }
375
376         __WDPOP_LOG_FUNC_EXIT__;
377         return NULL;
378 }
379
380 /**
381  *      This function let the app make a callback for discovering peer
382  *      @return   TRUE
383  *      @param[in] peer the pointer to the discovered peer
384  *      @param[in] user_data the pointer to the main data structure
385  */
386 bool _wfd_app_discoverd_peer_cb(wifi_direct_discovered_peer_info_s *peer, void *user_data)
387 {
388         __WDPOP_LOG_FUNC_ENTER__;
389         wfd_appdata_t *ad = (wfd_appdata_t *) user_data;
390
391         if (NULL != peer->device_name) {
392                 WDPOP_LOGD( "discovered peer ssid[%s]\n", peer->device_name);
393                 strncpy(ad->discovered_peers[ad->discovered_peer_count].ssid, peer->device_name, 32);
394                 ad->discovered_peers[ad->discovered_peer_count].ssid[31] = '\0';
395         } else {
396                 WDPOP_LOGD( "peer's device name is NULL\n");
397         }
398
399         if (NULL != peer->mac_address) {
400                 WDPOP_LOGD( "discovered peer mac[%s]\n", peer->mac_address);
401                 strncpy(ad->discovered_peers[ad->discovered_peer_count].mac_address, peer->mac_address, 18);
402                 ad->discovered_peers[ad->discovered_peer_count].mac_address[17] = '\0';
403         } else {
404                 WDPOP_LOGD( "peer's mac is NULL\n");
405         }
406
407         ad->discovered_peer_count++;
408
409         __WDPOP_LOG_FUNC_EXIT__;
410         return TRUE;
411
412 }
413
414 /**
415  *      This function let the app make a callback for registering discover event
416  *      @return   void
417  *      @param[in] error_code the returned error code
418  *      @param[in] discovery_state the state of discover
419  *      @param[in] user_data the pointer to the main data structure
420  */
421 void _cb_discover(int error_code, wifi_direct_discovery_state_e discovery_state, void *user_data)
422 {
423         __WDPOP_LOG_FUNC_ENTER__;
424         wfd_appdata_t *ad = (wfd_appdata_t *)user_data;
425         int ret;
426
427         switch (discovery_state) {
428         case WIFI_DIRECT_DISCOVERY_STARTED:
429                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DISCOVERY_STARTED\n");
430                 break;
431
432         case WIFI_DIRECT_ONLY_LISTEN_STARTED:
433                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_ONLY_LISTEN_STARTED\n");
434                 break;
435
436         case WIFI_DIRECT_DISCOVERY_FINISHED:
437                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DISCOVERY_FINISHED\n");
438                 break;
439
440         case WIFI_DIRECT_DISCOVERY_FOUND:
441                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DISCOVERY_FOUND\n");
442
443                 if (NULL != ad->discovered_peers) {
444                         free(ad->discovered_peers);
445                         ad->discovered_peers = NULL;
446                 }
447
448                 ad->discovered_peers = calloc(10, sizeof(wfd_device_info_t));
449                 ad->discovered_peer_count = 0;
450
451                 ret = wifi_direct_foreach_discovered_peers(_wfd_app_discoverd_peer_cb, (void *) ad);
452                 if (ret != WIFI_DIRECT_ERROR_NONE) {
453                         WDPOP_LOGD( "get discovery result failed: %d\n", ret);
454                 }
455                 break;
456
457         default:
458                 break;
459         }
460
461         __WDPOP_LOG_FUNC_EXIT__;
462 }
463
464 /**
465  *      This function let the app make a callback for registering connection event
466  *      @return   void
467  *      @param[in] error_code the returned error code
468  *      @param[in] connection_state the state of connection
469  *      @param[in] mac_address the mac address of peer
470  *      @param[in] user_data the pointer to the main data structure
471  */
472 void _cb_connection(int error_code, wifi_direct_connection_state_e connection_state, const char *mac_address, void *user_data)
473 {
474         __WDPOP_LOG_FUNC_ENTER__;
475
476         wfd_appdata_t *ad = (wfd_appdata_t *)user_data;
477         int result = -1;
478         char msg[WFD_POP_STR_MAX_LEN] = {0};
479         wfd_device_info_t *peer_info = NULL;
480
481         /* find the peer's name by the mac address */
482         if (NULL == mac_address) {
483                 WDPOP_LOGE("ERROR : mac address is NULL !!\n");
484                 return;
485         }
486
487         /* when disconnection, mac_address is empty */
488         if (connection_state <= WIFI_DIRECT_CONNECTION_RSP ||
489                 connection_state == WIFI_DIRECT_INVITATION_REQ) {
490                 memset(ad->peer_mac, 0, sizeof(ad->peer_mac));
491                 memset(ad->peer_name, 0, sizeof(ad->peer_name));
492                 strncpy(ad->peer_mac, mac_address, strlen(mac_address));
493                 ad->peer_mac[17] = '\0';
494                 peer_info = _wfd_app_find_peer_by_mac_address(ad, mac_address);
495
496                 if (NULL == peer_info) {
497                         WDPOP_LOGD( "peer_info is NULL !!\n");
498                 } else if (0 == strlen(peer_info->ssid)) {
499                         WDPOP_LOGD( "SSID from connection is invalid !!\n");
500                 } else {
501                         WDPOP_LOGD( "SSID from connection is %s.\n", peer_info->ssid);
502                         strncpy(ad->peer_name, peer_info->ssid, strlen(peer_info->ssid));
503                         ad->peer_name[31] = '\0';
504                 }
505
506                 if (0 == strlen(ad->peer_name)) {
507                         strncpy(ad->peer_name, ad->peer_mac, strlen(ad->peer_mac));
508                         ad->peer_name[31] = '\0';
509                 }
510         }
511
512         switch (connection_state) {
513         case WIFI_DIRECT_CONNECTION_RSP:
514         {
515                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_CONNECTION_RSP\n");
516                 wfd_destroy_popup();
517
518                 if (error_code == WIFI_DIRECT_ERROR_NONE) {
519                         WDPOP_LOGD( "Link Complete!\n");
520
521                         /* add connected notification */
522                         _add_wfd_peers_connected_notification(ad);
523
524                         /* tickernoti popup */
525                         snprintf(msg, WFD_POP_STR_MAX_LEN, IDS_WFD_POP_CONNECTED, ad->peer_name);
526                         notification_status_message_post(msg);
527                 } else if (error_code == WIFI_DIRECT_ERROR_AUTH_FAILED) {
528                         WDPOP_LOGD(
529                                         "Error Code - WIFI_DIRECT_ERROR_AUTH_FAILED\n");
530                         notification_status_message_post(_("IDS_WFD_POP_PIN_INVALID"));
531                 } else {
532                         if (error_code == WIFI_DIRECT_ERROR_CONNECTION_TIME_OUT) {
533                                 WDPOP_LOGD(
534                                                 "Error Code - WIFI_DIRECT_ERROR_CONNECTION_TIME_OUT\n");
535                         } else if (error_code == WIFI_DIRECT_ERROR_CONNECTION_FAILED) {
536                                 WDPOP_LOGD(
537                                                 "Error Code - WIFI_DIRECT_ERROR_CONNECTION_FAILED\n");
538                         }
539
540                         /* tickernoti popup */
541                         snprintf(msg, WFD_POP_STR_MAX_LEN, IDS_WFD_POP_CONNECT_FAILED, ad->peer_name);
542                         notification_status_message_post(msg);
543                 }
544         }
545         break;
546
547         case WIFI_DIRECT_CONNECTION_WPS_REQ:
548         {
549                 wifi_direct_wps_type_e wps_mode;
550
551                 memcpy(ad->peer_mac, mac_address, sizeof(ad->peer_mac));
552
553                 WDPOP_LOGD(
554                                 "event ------------------ WIFI_DIRECT_CONNECTION_WPS_REQ\n");
555                 result = wifi_direct_get_wps_type(&wps_mode);
556                 WDPOP_LOGD(
557                                 "wifi_direct_get_wps_type() result=[%d]\n", result);
558
559                 if (wps_mode == WIFI_DIRECT_WPS_TYPE_PBC) {
560                         WDPOP_LOGD(
561                                         "wps_config is WIFI_DIRECT_WPS_TYPE_PBC. Ignore it..\n");
562                 } else if (wps_mode == WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY) {
563                         char *pin;
564                         WDPOP_LOGD( "wps_config is WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY\n");
565
566                         if (wifi_direct_generate_wps_pin() != WIFI_DIRECT_ERROR_NONE) {
567                                 WDPOP_LOGD( "wifi_direct_generate_wps_pin() is failed\n");
568                                 return;
569                         }
570
571                         if (wifi_direct_get_wps_pin(&pin) != WIFI_DIRECT_ERROR_NONE) {
572                                 WDPOP_LOGD( "wifi_direct_generate_wps_pin() is failed\n");
573                                 return;
574                         }
575
576                         strncpy(ad->pin_number, pin, 64);
577                         ad->pin_number[63] = '\0';
578                         free(pin);
579                         pin = NULL;
580
581                         WDPOP_LOGD( "pin=[%s]\n", ad->pin_number);
582
583                         wfd_prepare_popup(WFD_POP_PROG_CONNECT_WITH_PIN, NULL);
584                 } else if (wps_mode == WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
585                         WDPOP_LOGD( "wps_config is WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD\n");
586                         wfd_prepare_popup(WFD_POP_PROG_CONNECT_WITH_KEYPAD, (void *) NULL);
587                 } else {
588                         WDPOP_LOGD( "wps_config is unkown!\n");
589
590                 }
591         }
592         break;
593
594         case WIFI_DIRECT_CONNECTION_REQ:
595         {
596                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_CONNECTION_REQ\n");
597
598                 wifi_direct_wps_type_e wps_mode;
599                 bool auto_connection_mode;
600
601                 result = wifi_direct_get_wps_type(&wps_mode);
602                 WDPOP_LOGD( "wifi_direct_get_wps_type() result=[%d]\n", result);
603
604                 result = wifi_direct_is_autoconnection_mode(&auto_connection_mode);
605                 WDPOP_LOGD( "wifi_direct_is_autoconnection_mode() result=[%d]\n", result);
606
607                 if (auto_connection_mode == TRUE) {
608                         result = wifi_direct_accept_connection(ad->peer_mac);
609                         WDPOP_LOGD("wifi_direct_accept_connection() result=[%d]\n", result);
610                 } else {
611                         if (wps_mode == WIFI_DIRECT_WPS_TYPE_PBC) {
612                                 WDPOP_LOGD( "wps_config is WIFI_DIRECT_WPS_TYPE_PBC\n");
613                                 wfd_prepare_popup(WFD_POP_APRV_CONNECTION_WPS_PUSHBUTTON_REQ, NULL);
614                         } else if (wps_mode == WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY) {
615                                 WDPOP_LOGD( "wps_config is WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY\n");
616                                 wfd_prepare_popup(WFD_POP_APRV_CONNECTION_WPS_DISPLAY_REQ, NULL);
617                         } else if (wps_mode == WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
618                                 WDPOP_LOGD( "wps_config is WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD\n");
619                                 wfd_prepare_popup(WFD_POP_APRV_CONNECTION_WPS_KEYPAD_REQ, (void *) NULL);
620                         } else {
621                                 WDPOP_LOGD( "wps_config is unkown!\n");
622                         }
623                 }
624         }
625         break;
626
627         case WIFI_DIRECT_DISCONNECTION_IND:
628         {
629                 _del_wfd_notification();
630                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_DISCONNECTION_IND\n");
631
632                 result = wifi_direct_set_autoconnection_mode(false);
633                 WDPOP_LOGD( "wifi_direct_set_autoconnection_mode() result=[%d]\n", result);
634
635                 /* tickernoti popup */
636                 snprintf(msg, WFD_POP_STR_MAX_LEN, IDS_WFD_POP_DISCONNECTED, ad->peer_name);
637                 notification_status_message_post(msg);
638         }
639         break;
640
641         case WIFI_DIRECT_DISCONNECTION_RSP:
642         {
643                 _del_wfd_notification();
644                 wfd_destroy_popup();
645
646                 result = wifi_direct_set_autoconnection_mode(false);
647                 WDPOP_LOGD( "wifi_direct_set_autoconnection_mode() result=[%d]\n", result);
648
649                 /* tickernoti popup */
650                 snprintf(msg, WFD_POP_STR_MAX_LEN, IDS_WFD_POP_DISCONNECTED, ad->peer_name);
651                 notification_status_message_post(msg);
652         }
653         break;
654         case WIFI_DIRECT_CONNECTION_IN_PROGRESS:
655         {
656                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_CONNECTION_IN_PROGRESS\n");
657                 /* tickernoti popup */
658                 notification_status_message_post(_("IDS_WFD_POP_CONNECTING"));
659         }
660         break;
661         case WIFI_DIRECT_INVITATION_REQ:
662         {
663                 WDPOP_LOGD( "event ------------------ WIFI_DIRECT_INVITATION_REQ\n");
664                 bool auto_connection_mode = FALSE;
665
666                 wifi_direct_is_autoconnection_mode(&auto_connection_mode);
667                 if (auto_connection_mode == TRUE) {
668                         result = wifi_direct_connect(ad->peer_mac);
669                         WDPOP_LOGD("wifi_direct_accept_connection() result=[%d]\n", result);
670                 } else {
671                         wfd_prepare_popup(WFD_POP_APRV_CONNECTION_INVITATION_REQ, NULL);
672                 }
673         }
674         break;
675         default:
676                 break;
677
678         }
679
680         /* if connected, start the transmit timer */
681         wifi_direct_get_state(&ad->wfd_status);
682         WDPOP_LOGD( "status: %d", ad->wfd_status);
683
684         if (ad->wfd_status < WIFI_DIRECT_STATE_CONNECTED) {
685             if (ad->transmit_timer) {
686                     ecore_timer_del(ad->transmit_timer);
687                     ad->transmit_timer = NULL;
688             }
689         } else {
690                 if (NULL == ad->transmit_timer) {
691                         WDPOP_LOGD( "start the transmit timer\n");
692                         ad->last_wfd_transmit_time = time(NULL);
693                         ad->transmit_timer = ecore_timer_add(5.0,
694                                 (Ecore_Task_Cb)_wfd_automatic_deactivated_for_connection_cb, ad);
695                 }
696         }
697
698         __WDPOP_LOG_FUNC_EXIT__;
699 }
700
701 /**
702  *      This function let the app make a change callback for flight mode
703  *      @return   void
704  *      @param[in] key the pointer to the key
705  *      @param[in] user_data the pointer to the main data structure
706  */
707 static void _wfd_flight_mode_changed(keynode_t *node, void *user_data)
708 {
709         __WDPOP_LOG_FUNC_ENTER__;
710         int res = -1;
711         int flight_mode = 0;
712         wfd_appdata_t *ad = (wfd_appdata_t *)user_data;
713
714         if (NULL == ad) {
715                 WDPOP_LOGE("NULL parameters.\n");
716                 return;
717         }
718
719         res = vconf_get_bool(VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL, &flight_mode);
720         if (res != 0) {
721                 WDPOP_LOGE("Failed to get flight state from vconf. [%d]\n", res);
722                 return;
723         }
724
725         if (flight_mode == FALSE) {
726                 WDPOP_LOGD( "Flight mode is off\n");
727                 return;
728         }
729
730         /* If flight mode is on, turn off WFD */
731         wifi_direct_get_state(&ad->wfd_status);
732         if (WIFI_DIRECT_STATE_DEACTIVATED == ad->wfd_status) {
733                 WDPOP_LOGD( "Wi-Fi Direct is deactivated.\n");
734                 return;
735         }
736
737         /*if connected, disconnect all devices*/
738         if (WIFI_DIRECT_STATE_CONNECTED == ad->wfd_status) {
739                 res = wifi_direct_disconnect_all();
740                 if (res != WIFI_DIRECT_ERROR_NONE) {
741                         WDPOP_LOGE("Failed to send disconnection request to all. [%d]\n", res);
742                         return;
743                 }
744         }
745
746         res = wifi_direct_deactivate();
747         if (res != WIFI_DIRECT_ERROR_NONE) {
748                 WDPOP_LOGE("Failed to deactivate Wi-Fi Direct. error code = [%d]\n", res);
749                 return;
750         }
751
752         __WDPOP_LOG_FUNC_EXIT__;
753 }
754
755 /**
756  *      This function let the app do initialization
757  *      @return   If success, return TRUE, else return FALSE
758  *      @param[in] ad the pointer to the main data structure
759  */
760 int init_wfd_popup_client(wfd_appdata_t *ad)
761 {
762         __WDPOP_LOG_FUNC_ENTER__;
763
764         if (NULL == ad) {
765                 WDPOP_LOGD( "NULL parameters.\n");
766                 return FALSE;
767         }
768
769         int ret = -1;
770
771         ret = wifi_direct_initialize();
772         if (ret != WIFI_DIRECT_ERROR_NONE) {
773                 WDPOP_LOGE("Failed to initialize Wi-Fi Direct. error code = [%d]\n", ret);
774                 return FALSE;
775         }
776
777         ret = wifi_direct_set_device_state_changed_cb(_cb_activation, (void *)ad);
778         if (ret != WIFI_DIRECT_ERROR_NONE) {
779                 WDPOP_LOGE("Failed to register _cb_activation. error code = [%d]\n", ret);
780                 return FALSE;
781         }
782
783         ret = wifi_direct_set_discovery_state_changed_cb(_cb_discover, (void *)ad);
784         if (ret != WIFI_DIRECT_ERROR_NONE) {
785                 WDPOP_LOGE("Failed to register _cb_discover. error code = [%d]\n", ret);
786                 return FALSE;
787         }
788
789         ret = wifi_direct_set_connection_state_changed_cb(_cb_connection, (void *)ad);
790         if (ret != WIFI_DIRECT_ERROR_NONE) {
791                 WDPOP_LOGE("Failed to register _cb_connection. error code = [%d]\n", ret);
792                 return FALSE;
793         }
794
795         /* initialize notification */
796         ad->noti = notification_new(NOTIFICATION_TYPE_NOTI, NOTIFICATION_GROUP_ID_NONE, NOTIFICATION_PRIV_ID_NONE);
797         if (NULL == ad->noti) {
798                 WDPOP_LOGD( "notification_new failed.\n");
799                 return FALSE;
800         }
801
802         /* register flight mode */
803         int result = -1;
804         result = vconf_notify_key_changed(VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL, _wfd_flight_mode_changed, ad);
805         if (result == -1) {
806                 WDPOP_LOGE("Failed to register vconf callback for flight mode\n");
807                 return FALSE;
808         }
809
810         __WDPOP_LOG_FUNC_EXIT__;
811         return TRUE;
812 }
813
814 /**
815  *      This function let the app do de-initialization
816  *      @return   If success, return TRUE, else return FALSE
817  *      @param[in] ad the pointer to the main data structure
818  */
819 int deinit_wfd_popup_client(wfd_appdata_t *ad)
820 {
821         __WDPOP_LOG_FUNC_ENTER__;
822
823         if (NULL == ad || NULL == ad->noti) {
824                 WDPOP_LOGD( "NULL parameters.\n");
825                 return FALSE;
826         }
827
828         int ret = -1;
829
830         ret = wifi_direct_deinitialize();
831
832         _del_wfd_notification(ad);
833         notification_error_e noti_err = NOTIFICATION_ERROR_NONE;
834         noti_err = notification_free(ad->noti);
835         if (noti_err != NOTIFICATION_ERROR_NONE) {
836                 WDPOP_LOGD( "Fail to notification_free.(%d)\n", noti_err);
837                 ret = WIFI_DIRECT_ERROR_RESOURCE_BUSY;
838         }
839
840         /* remove callback for flight mode */
841         int result = -1;
842         result = vconf_ignore_key_changed(VCONFKEY_WIFI_STATE, _wfd_flight_mode_changed);
843         if (result == -1) {
844                 WDPOP_LOGE("Failed to ignore vconf key callback for flight mode\n");
845         }
846
847         if (ad->transmit_timer) {
848                 ecore_timer_del(ad->transmit_timer);
849                 ad->transmit_timer = NULL;
850         }
851
852         __WDPOP_LOG_FUNC_EXIT__;
853         if (ret == WIFI_DIRECT_ERROR_NONE) {
854                 return TRUE;
855         } else {
856                 return FALSE;
857         }
858 }