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