Merge branch 'master' into tizen_2.1
[apps/native/ug-mobile-ap.git] / src / mh_func_onoff.c
1 /*
2 * ug-mobile-ap
3 *
4 * Copyright 2012  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://www.tizenopensource.org/license
11
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #include <stdlib.h>
21 #include <wifi-direct.h>
22
23 #include "mh_func_onoff.h"
24
25 static bool __get_vconf_prev_wifi_state()
26 {
27         int value = 0;
28
29         if (vconf_get_bool(VCONF_MOBILE_AP_PREV_WIFI_STATUS, &value) < 0) {
30                 ERR("vconf_get_bool is failed\n");
31                 return false;
32         }
33
34         DBG("%s : %d\n", VCONF_MOBILE_AP_PREV_WIFI_STATUS, value);
35
36         return value ? true : false;
37 }
38
39 int _get_vconf_usb_state()
40 {
41         int value = VCONFKEY_SYSMAN_USB_DISCONNECTED;
42
43         if (vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &value) < 0) {
44                 ERR("vconf_get_int is failed\n");
45                 return 0;
46         }
47
48         DBG("%s : %d\n", VCONFKEY_SYSMAN_USB_STATUS, value);
49
50         return value;
51 }
52
53 static bool __is_connected_wifi_net(mh_appdata_t *ad)
54 {
55         connection_wifi_state_e wifi_state = CONNECTION_WIFI_STATE_DEACTIVATED;
56         int ret;
57
58         ret = connection_get_wifi_state(ad->conn_handle, &wifi_state);
59         if (ret != CONNECTION_ERROR_NONE) {
60                 ERR("connection_get_wifi_state() is failed : %d\n");
61                 return false;
62         }
63
64         if (wifi_state != CONNECTION_WIFI_STATE_CONNECTED) {
65                 ERR("Wi-Fi network is not connected : %d\n", wifi_state);
66                 return false;
67         }
68
69         DBG("Wi-Fi network is connected\n");
70         return true;
71 }
72
73 static bool __is_connected_ethernet_net(mh_appdata_t *ad)
74 {
75         connection_ethernet_state_e ethernet_state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
76         int ret;
77
78         ret = connection_get_ethernet_state(ad->conn_handle, &ethernet_state);
79         if (ret != CONNECTION_ERROR_NONE) {
80                 ERR("connection_get_ethernet_state() is failed : %d\n");
81                 return false;
82         }
83
84         if (ethernet_state != CONNECTION_ETHERNET_STATE_CONNECTED) {
85                 ERR("Ethernet network is not connected : %d\n", ethernet_state);
86                 return false;
87         }
88
89         DBG("Ethernet network is connected\n");
90         return true;
91 }
92
93 static bool __is_connected_cellular_net(mh_appdata_t *ad)
94 {
95         connection_cellular_state_e cellular_state = CONNECTION_CELLULAR_STATE_OUT_OF_SERVICE;
96         sim_state_e sim_state = SIM_STATE_UNAVAILABLE;
97         int ret;
98
99         /* Check SIM state */
100         ret = sim_get_state(&sim_state);
101         if (ret != SIM_ERROR_NONE) {
102                 ERR("sim_get_state() is failed : %d\n", ret);
103                 _prepare_popup(MH_POP_INFORMATION,
104                                 _("IDS_MOBILEAP_POP_INSERT_SIM_CARD_AND_RESTART_DEVICE_TO_USE_TETHERING"));
105                 _create_popup(ad);
106                 return false;
107         }
108         DBG("SIM State : %d\n", sim_state);
109         if (sim_state != SIM_STATE_AVAILABLE) {
110                 _prepare_popup(MH_POP_INFORMATION,
111                                 _("IDS_MOBILEAP_POP_INSERT_SIM_CARD_AND_RESTART_DEVICE_TO_USE_TETHERING"));
112                 _create_popup(ad);
113                 return false;
114         }
115
116         ret = connection_get_cellular_state(ad->conn_handle, &cellular_state);
117         if (ret != CONNECTION_ERROR_NONE) {
118                 ERR("connection_get_cellular_state() is failed : %d\n");
119                 return false;
120         }
121
122         if (cellular_state == CONNECTION_CELLULAR_STATE_FLIGHT_MODE) {
123                 _prepare_popup(MH_POP_INFORMATION_WO_BUTTON,
124                                 _("IDS_MOBILEAP_POP_UNABLE_TO_USE_TETHERING_IN_FLIGHT_MODE_TO_USE_TETHERING_DISABLE_FLIGHT_MODE"));
125                 _create_popup(ad);
126                 ERR("Cellular network is not connected\n");
127                 return false;
128         } else if (cellular_state != CONNECTION_CELLULAR_STATE_CONNECTED &&
129                         cellular_state != CONNECTION_CELLULAR_STATE_AVAILABLE) {
130                 _prepare_popup(MH_POP_INFORMATION,
131                                 _("IDS_MOBILEAP_POP_UNABLE_TO_USE_PACKET_DATA_SERVICE_OUT_OF_COVERAGE"));
132                 _create_popup(ad);
133                 ERR("Cellular network is not connected : %d\n", cellular_state);
134                 return false;
135         }
136
137         DBG("Cellular network is connected\n");
138         return true;
139 }
140
141 static int __create_wifi_hotspot_on_popup(mh_appdata_t *ad)
142 {
143         char *fmt;
144         char *str;
145         bool wifi_state = false;
146
147         wifi_is_activated(&wifi_state);
148         if (wifi_state == true || _is_wifi_direct_on() == true)
149                 fmt = _("IDS_ST_BODY_WI_FI_NETWORK_WILL_BE_DISCONNECTED_TETHERING_CONSUMES_MORE_BATTERY_POWER_AND_INCREASES_YOUR_DATA_USAGE_THE_MAXIMUM_NUMBER_OF_TETHERED_DEVICES_ALLOWED_IS_PD");
150         else
151                 fmt = _("IDS_ST_BODY_TETHERING_CONSUMES_MORE_BATTERY_POWER_AND_INCREASES_YOUR_DATA_USAGE_THE_MAXIMUM_NUMBER_OF_TETHERED_DEVICES_ALLOWED_IS_PD");
152
153         str = malloc(MH_LABEL_LENGTH_MAX);
154         snprintf(str, MH_LABEL_LENGTH_MAX, fmt, TETHERING_WIFI_MAX_CONNECTED_STA);
155         _prepare_popup(MH_POP_WIFI_ON_CONF, str);
156         free(str);
157
158         _create_popup(ad);
159
160         return 0;
161 }
162
163 static int __create_bt_tethering_on_popup(mh_appdata_t *ad)
164 {
165         char *str;
166
167         str = malloc(MH_LABEL_LENGTH_MAX);
168         snprintf(str, MH_LABEL_LENGTH_MAX,
169                         _("IDS_ST_BODY_TETHERING_CONSUMES_MORE_BATTERY_POWER_AND_INCREASES_YOUR_DATA_USAGE_THE_MAXIMUM_NUMBER_OF_TETHERED_DEVICES_ALLOWED_IS_PD"),
170                         TETHERING_BT_MAX_CONNECTED_STA);
171         _prepare_popup(MH_POP_BT_ON_CONF, str);
172         free(str);
173
174         _create_popup(ad);
175
176         return 0;
177 }
178
179 static int __create_usb_tethering_on_popup(mh_appdata_t *ad)
180 {
181         char *str;
182
183         str = _("IDS_MOBILEAP_POP_TETHERING_CONSUMES_MORE_BATTERY_POWER_AND_INCREASES_YOUR_DATA_USAGE");
184         _prepare_popup(MH_POP_USB_ON_CONF, str);
185         _create_popup(ad);
186
187         return 0;
188 }
189
190 static void __disable_tethering_by_ind(mh_appdata_t *ad, tethering_disabled_cause_e cause)
191 {
192         if (ad == NULL) {
193                 ERR("Param is NULL\n");
194                 return;
195         }
196
197         DBG("cause : %d\n", cause);
198         switch (cause) {
199         case TETHERING_DISABLED_BY_WIFI_ON:
200                 DBG("TETHERING_DISABLED_IND by WIFI\n");
201                 break;
202
203         case TETHERING_DISABLED_BY_BT_OFF:
204                 DBG("TETHERING_DISABLED_BY_BT_DEACTIVATION\n");
205                 break;
206
207         case TETHERING_DISABLED_BY_USB_DISCONNECTION:
208                 DBG("TETHERING_DISABLED_IND by USB DISCONNECT\n");
209                 break;
210
211         case TETHERING_DISABLED_BY_FLIGHT_MODE:
212                 DBG("TETHERING_DISABLED_IND by FLIGHT_MODE\n");
213                 break;
214
215         case TETHERING_DISABLED_BY_TIMEOUT:
216                 DBG("TETHERING_DISABLED_BY_TIMEOUT\n");
217                 break;
218
219         case TETHERING_DISABLED_BY_OTHERS:
220                 DBG("TETHERING_DISABLED_IND by OTHERS\n");
221                 break;
222
223         case TETHERING_DISABLED_BY_LOW_BATTERY:
224                 DBG("TETHERING_DISABLED_IND by LOW_BATTERY\n");
225                 break;
226
227         case TETHERING_DISABLED_BY_MDM_ON:
228                 DBG("TETHERING_DISABLED_IND by MDM\n");
229                 break;
230
231         default:
232                 DBG("TETHERING_DISABLED_IND Default\n");
233                 break;
234         }
235
236         return;
237 }
238
239 static void __recover_wifi_station_mode(void)
240 {
241         DBG("+\n");
242
243         if (__get_vconf_prev_wifi_state() == false) {
244                 DBG("No need to recover wifi station mode\n");
245                 return;
246         }
247
248         if (_turn_on_wifi() != 0)
249                 ERR("_turn_on_wifi is failed\n");
250         if (vconf_set_bool(VCONF_MOBILE_AP_PREV_WIFI_STATUS, 0) < 0)
251                 ERR("vconf_set_bool failed\n");
252
253         return;
254 }
255
256 /* Wi-Fi Direct callback */
257 static void _wifi_direct_state_cb(int error_code, wifi_direct_device_state_e state, void *user_data)
258 {
259         DBG("+\n");
260
261         if (user_data == NULL) {
262                 ERR("The param is NULL\n");
263                 return;
264         }
265
266         mh_appdata_t *ad = (mh_appdata_t *)user_data;
267         int ret = 0;
268
269         wifi_direct_unset_device_state_changed_cb();
270         wifi_direct_deinitialize();
271         DBG("-\n");
272
273         if (error_code != 0) {
274                 ERR("wifi_direct_deactivate fail in cb : %d\n", error_code);
275                 _update_main_view(ad);
276                 return;
277         }
278
279         if (state != WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) {
280                 ERR("Unknown state : %d\n", state);
281                 return;
282         }
283
284         ret = tethering_enable(ad->handle, TETHERING_TYPE_WIFI);
285         if (ret != TETHERING_ERROR_NONE) {
286                 ERR("wifi tethering on is failed : %d\n", ret);
287                 _update_main_view(ad);
288                 return;
289         }
290
291         DBG("-\n");
292         return;
293 }
294
295 /* Wi-Fi callbacks */
296 static void __wifi_activated_cb(wifi_error_e result, void *user_data)
297 {
298         __MOBILE_AP_FUNC_ENTER__;
299
300         DBG("Wi-Fi on is done\n");
301
302         __MOBILE_AP_FUNC_EXIT__;
303         return;
304 }
305
306 static void __wifi_deactivated_cb(wifi_error_e result, void *user_data)
307 {
308         __MOBILE_AP_FUNC_ENTER__;
309
310         if (user_data == NULL) {
311                 ERR("The param is NULL\n");
312                 return;
313         }
314
315         mh_appdata_t *ad = (mh_appdata_t *)user_data;
316         int ret;
317
318         if (result != WIFI_ERROR_NONE) {
319                 ERR("__wifi_deactivated_cb error : %d\n", result);
320                 _update_main_view(ad);
321                 return;
322         }
323
324         DBG("Wi-Fi is turned off\n");
325
326         ret = vconf_set_bool(VCONF_MOBILE_AP_PREV_WIFI_STATUS, 1);
327         if (ret < 0)
328                 ERR("vconf_set_bool() is failed : %d\n", ret);
329
330         ret = tethering_enable(ad->handle, TETHERING_TYPE_WIFI);
331         if (ret != TETHERING_ERROR_NONE) {
332                 ERR("wifi tethering on is failed : %d\n", ret);
333                 _update_main_view(ad);
334                 return;
335         }
336
337         __MOBILE_AP_FUNC_EXIT__;
338         return;
339 }
340
341 /* Tethering callbacks */
342 void _enabled_cb(tethering_error_e result, tethering_type_e type, bool is_requested, void *user_data)
343 {
344         if (user_data == NULL) {
345                 ERR("user_data is NULL\n");
346                 return;
347         }
348
349         mh_appdata_t *ad = (mh_appdata_t *)user_data;
350
351         ad->main.need_recover_wifi_tethering = false;
352
353         if (!is_requested) {
354                 if (NULL != ad->popup) {
355                         evas_object_del(ad->popup);
356                         ad->popup = NULL;
357                 }
358                 _update_main_view(ad);
359
360                 return;
361         }
362
363         if (result != TETHERING_ERROR_NONE) {
364                 _prepare_popup(MH_POP_INFORMATION,
365                                 _("IDS_MOBILEAP_POP_UNABLE_TO_USE_TETHERING"));
366                 _create_popup(ad);
367         }
368
369         _update_main_view(ad);
370
371         return;
372 }
373
374 void _disabled_cb(tethering_error_e result, tethering_type_e type, tethering_disabled_cause_e cause, void *user_data)
375 {
376         if (user_data == NULL) {
377                 ERR("user_data is NULL\n");
378                 return;
379         }
380
381         mh_appdata_t *ad = (mh_appdata_t *)user_data;
382
383         if (ad->main.need_recover_wifi_tethering == true) {
384                 DBG("Wi-Fi tethering will be turned on again\n");
385                 return;
386         }
387
388         if (cause != TETHERING_DISABLED_BY_REQUEST) {
389                 DBG("Tethering [%d] is disabled because of [%d]\n", type, cause);
390                 if (NULL != ad->popup) {
391                         evas_object_del(ad->popup);
392                         ad->popup = NULL;
393                 }
394                 _update_main_view(ad);
395                 __disable_tethering_by_ind(ad, cause);
396                 return;
397         }
398
399         if (result != TETHERING_ERROR_NONE) {
400                 _prepare_popup(MH_POP_INFORMATION,
401                                 _("IDS_MOBILEAP_POP_UNABLE_TO_USE_TETHERING"));
402                 _create_popup(ad);
403                 _update_main_view(ad);
404                 return;
405         }
406
407         DBG("Tethering [%d] is disabled by reqeust\n", type);
408         if (type == TETHERING_TYPE_WIFI) {
409                 __recover_wifi_station_mode();
410         }
411
412         _update_main_view(ad);
413
414         return;
415 }
416
417 void _connection_changed_cb(tethering_client_h client, bool is_opened, void *user_data)
418 {
419         if (user_data == NULL) {
420                 ERR("user_data is NULL\n");
421                 return;
422         }
423
424         mh_appdata_t *ad = (mh_appdata_t *)user_data;
425         char *name = NULL;
426
427         tethering_client_get_name(client, &name);
428         DBG("Client %s is %s\n", name, is_opened ?  "connected" : "disconnected");
429         if (name)
430                 free(name);
431
432         ap_update_data_device(ad);
433
434         return;
435 }
436
437 void _data_usage_cb(tethering_error_e result, unsigned long long received_data, unsigned long long sent_data, void *user_data)
438 {
439         if (user_data == NULL) {
440                 ERR("user_data is NULL\n");
441                 return;
442         }
443
444         mh_appdata_t *ad = (mh_appdata_t *)user_data;
445
446         if (ad->data_statistics.pdp_total_sent != sent_data ||
447                         ad->data_statistics.pdp_total_receive != received_data) {
448                 ad->data_statistics.pdp_total_sent = sent_data;
449                 ad->data_statistics.pdp_total_receive = received_data;
450                 ap_update_data_packet_usage(ad);
451         }
452
453         ad->data_statistics.is_updated = true;
454
455         return;
456 }
457 /* End of Tethering callbacks */
458
459 int _handle_wifi_onoff_change(mh_appdata_t *ad)
460 {
461         __MOBILE_AP_FUNC_ENTER__;
462
463         int ret;
464         int connected_wifi_clients = 0;
465
466         /* Turn off WiFi hotspot */
467         if (ad->main.hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) {
468                 if (_get_no_of_connected_device(ad->handle, &connected_wifi_clients,
469                                         TETHERING_TYPE_WIFI) == FALSE) {
470                         ERR("Getting the number of connected device is failed\n");
471                 }
472                 if (connected_wifi_clients > 0) {
473                         _prepare_popup(MH_POP_WIFI_OFF_CONF,
474                                         _("IDS_MOBILEAP_POP_DISABLING_TETHERING_WILL_PREVENT_LINKED_DEVICES_FROM_ACCESSING_THE_INTERNET_CONTINUE_Q"));
475                         _create_popup(ad);
476                 } else {
477                         ret = tethering_disable(ad->handle, TETHERING_TYPE_WIFI);
478                         if (ret != TETHERING_ERROR_NONE) {
479                                 ERR("wifi tethering off is failed : %d\n", ret);
480                                 return -1;
481                         }
482                 }
483                 return 0;
484         }
485
486         /* Turn on WiFi hotspot */
487         if (!__is_connected_ethernet_net(ad) && !__is_connected_cellular_net(ad)) {
488                 ERR("There is no connected network\n");
489                 return -1;
490         }
491
492         if (__create_wifi_hotspot_on_popup(ad) < 0) {
493                 ERR("__create_wifi_hotspot_on_popup fail\n");
494                 return -1;
495         }
496
497         __MOBILE_AP_FUNC_EXIT__;
498
499         return 0;
500 }
501
502 int _handle_bt_onoff_change(mh_appdata_t *ad)
503 {
504         __MOBILE_AP_FUNC_ENTER__;
505
506         int ret;
507
508         /* Turn off Bluetooth tethering */
509         if (ad->main.hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_BT) {
510                 ret = tethering_disable(ad->handle, TETHERING_TYPE_BT);
511                 if (ret) {
512                         ERR("Error disable bt tethering [%d]\n", ret);
513                         return -1;
514                 }
515                 return 0;
516         }
517
518         /* Turn on Bluetooth tethering */
519         if (!__is_connected_ethernet_net(ad) && !__is_connected_wifi_net(ad) &&
520                         !__is_connected_cellular_net(ad)) {
521                 ERR("There is no connected network\n");
522                 return -1;
523         }
524
525         if (__create_bt_tethering_on_popup(ad) < 0) {
526                 ERR("__create_bt_tethering_on_popup fail\n");
527                 return -1;
528         }
529
530         __MOBILE_AP_FUNC_EXIT__;
531
532         return 0;
533 }
534
535 int _handle_usb_onoff_change(mh_appdata_t *ad)
536 {
537         __MOBILE_AP_FUNC_ENTER__;
538
539         int ret;
540
541         /* Turn off USB tethering */
542         if (ad->main.hotspot_mode & VCONFKEY_MOBILE_HOTSPOT_MODE_USB) {
543                 ret = tethering_disable(ad->handle, TETHERING_TYPE_USB);
544                 if (ret) {
545                         DBG("Error disable usb tethering : %d\n", ret);
546                         return -1;
547                 }
548                 return 0;
549         }
550
551         /* Turn on USB tethering */
552         if (!__is_connected_ethernet_net(ad) && !__is_connected_wifi_net(ad) &&
553                         !__is_connected_cellular_net(ad)) {
554                 ERR("There is no connected network\n");
555                 return -1;
556         }
557
558         if (__create_usb_tethering_on_popup(ad) < 0) {
559                 ERR("__create_usb_tethering_on_popup fail\n");
560                 return -1;
561         }
562
563         __MOBILE_AP_FUNC_EXIT__;
564
565         return 0;
566 }
567
568 int _turn_off_wifi(mh_appdata_t *ad)
569 {
570         int ret;
571
572         ret = wifi_deactivate(__wifi_deactivated_cb, (void *)ad);
573         if (ret != WIFI_ERROR_NONE) {
574                 ERR("wifi_deactivate() is failed : %d\n", ret);
575                 return -1;
576         }
577
578         return 0;
579 }
580
581 int _turn_on_wifi(void)
582 {
583         int ret;
584
585         ret = wifi_activate(__wifi_activated_cb, NULL);
586         if (ret != WIFI_ERROR_NONE) {
587                 ERR("wifi_activate() is failed : %d\n", ret);
588                 return -1;
589         }
590
591         return 0;
592 }
593
594 bool _is_wifi_direct_on(void)
595 {
596         int wifi_direct_state = 0;
597         int ret;
598
599         ret = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
600         if (ret < 0) {
601                 ERR("vconf_get_int() is failed : %d\n", ret);
602                 return false;
603         }
604
605         return wifi_direct_state != 0 ? true : false;
606 }
607
608 int _turn_off_wifi_direct(mh_appdata_t *ad)
609 {
610         int ret;
611
612         ret = wifi_direct_initialize();
613         if (ret < 0) {
614                 ERR("wifi_direct_initialize() is failed : %d\n", ret);
615                 return -1;
616         }
617
618         ret = wifi_direct_set_device_state_changed_cb(_wifi_direct_state_cb, (void *)ad);
619         if (ret < 0) {
620                 ERR("wifi_direct_set_device_state_changed_cb() is failed : %d\n", ret);
621                 ret = wifi_direct_deinitialize();
622                 DBG("wifi_direct_deinitialize() ret : %d\n", ret);
623                 return -1;
624         }
625
626         ret = wifi_direct_deactivate();
627         if (ret < 0) {
628                 ERR("wifi_direct_deactivate() is failed : %d\n", ret);
629                 ret = wifi_direct_unset_device_state_changed_cb();
630                 DBG("wifi_direct_unset_device_state_changed_cb() ret : %d\n", ret);
631                 ret = wifi_direct_deinitialize();
632                 DBG("wifi_direct_deinitialize() ret : %d\n", ret);
633                 return -1;
634         }
635
636         return 0;
637 }