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