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