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