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