tizen 2.4 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_wifi.c
1 /*
2  * mobileap-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <glib.h>
19 #include <dbus/dbus.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <wifi.h>
24 #include <wifi-direct.h>
25
26 #include "mobileap_softap.h"
27 #include "mobileap_common.h"
28 #include "mobileap_wifi.h"
29 #include "mobileap_handler.h"
30 #include "mobileap_notification.h"
31
32 #define WIFI_RECOVERY_GUARD_TIME        1000    /* ms */
33
34 static mobile_ap_error_code_e __update_softap_settings(softap_settings_t *st,
35         gchar *ssid, gchar *passphrase, int hide_mode, softap_security_type_e security_type);
36 static int __turn_off_wifi(Tethering *obj);
37
38 static GDBusMethodInvocation *g_context = NULL;
39 static guint wifi_recovery_timeout_id = 0;
40 static gboolean prev_wifi_on = FALSE;
41 static wifi_saved_settings wifi_settings = {0, NULL, NULL, 0};
42 static softap_settings_t obj_softap_settings = {0, "", "", ""};
43
44 softap_settings_t *_get_softap_settings()
45 {
46         return &obj_softap_settings;
47 }
48 static void _wifi_direct_state_cb(int error_code, wifi_direct_device_state_e state, void *user_data)
49 {
50         bool wifi_state = false;
51
52         DBG("+\n");
53
54         if (user_data == NULL) {
55                 ERR("The param is NULL\n");
56                 return;
57         }
58
59         Tethering *obj = (Tethering *)user_data;
60         int ret = 0;
61
62         if (state != WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) {
63                 ERR("Unknown state : %d\n", state);
64                 return;
65         }
66
67         wifi_direct_unset_device_state_changed_cb();
68         wifi_direct_deinitialize();
69
70         if (error_code != 0) {
71                 ERR("wifi_direct_deactivate fail in cb : %d\n", error_code);
72                 ret = MOBILE_AP_ERROR_INTERNAL;
73                 goto DONE;
74         }
75         DBG("Wi-Fi direct is turned off\n");
76
77         wifi_is_activated(&wifi_state);
78         if (wifi_state) {
79                 DBG("Wi-Fi is turned on. Turn off Wi-Fi");
80                 if (__turn_off_wifi(obj) != MOBILE_AP_ERROR_NONE) {
81                         ERR("_turn_off_wifi is failed\n");
82                         ret = MOBILE_AP_ERROR_INTERNAL;
83                         goto DONE;
84                 }
85                 return;
86         }
87
88         ret = _enable_wifi_tethering(obj, wifi_settings.ssid, wifi_settings.key,
89                         wifi_settings.hide_mode, wifi_settings.security_type);
90         if (ret != MOBILE_AP_ERROR_NONE) {
91                 ERR("_enable_wifi_tethering is failed\n");
92         } else {
93                 tethering_emit_wifi_on(obj);
94                 _create_tethering_active_noti();
95         }
96
97 DONE:
98         tethering_complete_enable_wifi_tethering(obj, g_context, ret);
99         g_context = NULL;
100
101         g_free(wifi_settings.ssid);
102         g_free(wifi_settings.key);
103         memset(&wifi_settings, 0, sizeof(wifi_settings));
104
105         DBG("-\n");
106         return;
107 }
108
109 static void __wifi_activated_cb(wifi_error_e result, void *user_data)
110 {
111         DBG("Wi-Fi on is done\n");
112
113         return;
114 }
115
116 static void __wifi_deactivated_cb(wifi_error_e result, void *user_data)
117 {
118         DBG("+\n");
119
120         if (user_data == NULL) {
121                 ERR("The param is NULL\n");
122                 return;
123         }
124
125         Tethering *obj = (Tethering *)user_data;
126         int ret;
127
128         if (result != WIFI_ERROR_NONE) {
129                 ERR("__wifi_deactivated_cb error : %d\n", result);
130                 ret = MOBILE_AP_ERROR_INTERNAL;
131                 goto DONE;
132         }
133
134         DBG("Wi-Fi is turned off\n");
135
136         ret = _enable_wifi_tethering(obj, wifi_settings.ssid, wifi_settings.key,
137                         wifi_settings.hide_mode, wifi_settings.security_type);
138         if (ret != MOBILE_AP_ERROR_NONE) {
139                 ERR("_enable_wifi_tethering is failed\n");
140         } else {
141                 prev_wifi_on = TRUE;
142                 tethering_emit_wifi_on(obj);
143                 _create_tethering_active_noti();
144         }
145
146 DONE:
147         tethering_complete_enable_wifi_tethering(obj, g_context, ret);
148
149         g_context = NULL;
150
151         g_free(wifi_settings.ssid);
152         g_free(wifi_settings.key);
153         memset(&wifi_settings, 0, sizeof(wifi_settings));
154
155         DBG("-\n");
156         return;
157 }
158
159 static int __turn_off_wifi(Tethering *obj)
160 {
161         int ret;
162
163         ret = wifi_deactivate(__wifi_deactivated_cb, (void *)obj);
164         if (ret != WIFI_ERROR_NONE) {
165                 ERR("wifi_deactivate() is failed : %d\n", ret);
166                 return MOBILE_AP_ERROR_INTERNAL;
167         }
168
169         return MOBILE_AP_ERROR_NONE;
170 }
171
172 static gboolean __turn_on_wifi_timeout_cb(gpointer user_data)
173 {
174         int ret;
175         guint idle_id;
176
177         wifi_recovery_timeout_id = 0;
178
179         ret = wifi_activate(__wifi_activated_cb, NULL);
180         if (ret != WIFI_ERROR_NONE) {
181                 ERR("wifi_activate() is failed : %d\n", ret);
182         }
183
184         idle_id = g_idle_add(_terminate_mobileap_agent, NULL);
185         if (idle_id == 0) {
186                 ERR("g_idle_add is failed\n");
187         }
188
189         return FALSE;
190 }
191
192 static int __turn_on_wifi(void)
193 {
194         if (wifi_recovery_timeout_id > 0) {
195                 g_source_remove(wifi_recovery_timeout_id);
196                 wifi_recovery_timeout_id = 0;
197         }
198
199         wifi_recovery_timeout_id = g_timeout_add(WIFI_RECOVERY_GUARD_TIME,
200                         __turn_on_wifi_timeout_cb, NULL);
201         if (wifi_recovery_timeout_id == 0) {
202                 ERR("g_timeout_add is failed\n");
203                 return MOBILE_AP_ERROR_INTERNAL;
204         }
205
206         return MOBILE_AP_ERROR_NONE;
207 }
208
209 static gboolean __is_wifi_direct_on(void)
210 {
211         int wifi_direct_state = 0;
212         int ret;
213
214         ret = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
215         if (ret < 0) {
216                 ERR("vconf_get_int() is failed : %d\n", ret);
217                 return FALSE;
218         }
219
220         return wifi_direct_state != 0 ? TRUE : FALSE;
221 }
222
223 static int __turn_off_wifi_direct(Tethering *obj)
224 {
225         int ret;
226
227         ret = wifi_direct_initialize();
228         if (ret < 0) {
229                 ERR("wifi_direct_initialize() is failed : %d\n", ret);
230                 return MOBILE_AP_ERROR_INTERNAL;
231         }
232
233         ret = wifi_direct_set_device_state_changed_cb(_wifi_direct_state_cb, (void *)obj);
234         if (ret < 0) {
235                 ERR("wifi_direct_set_device_state_changed_cb() is failed : %d\n", ret);
236                 ret = wifi_direct_deinitialize();
237                 DBG("wifi_direct_deinitialize() ret : %d\n", ret);
238                 return MOBILE_AP_ERROR_INTERNAL;
239         }
240
241         ret = wifi_direct_deactivate();
242         if (ret < 0) {
243                 ERR("wifi_direct_deactivate() is failed : %d\n", ret);
244                 ret = wifi_direct_unset_device_state_changed_cb();
245                 DBG("wifi_direct_unset_device_state_changed_cb() ret : %d\n", ret);
246                 ret = wifi_direct_deinitialize();
247                 DBG("wifi_direct_deinitialize() ret : %d\n", ret);
248                 return MOBILE_AP_ERROR_INTERNAL;
249         }
250
251         return MOBILE_AP_ERROR_NONE;
252 }
253
254 static mobile_ap_error_code_e __update_softap_settings(softap_settings_t *st,
255         gchar *ssid, gchar *passphrase, int hide_mode, softap_security_type_e security_type)
256 {
257         if (st == NULL) {
258                 ERR("Invalid param\n");
259                 return MOBILE_AP_ERROR_INVALID_PARAM;
260         }
261
262         g_strlcpy(st->ssid, ssid, sizeof(st->ssid));
263
264         if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK) {
265                 g_strlcpy(st->security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR,
266                         sizeof(st->security_type));
267                 g_strlcpy(st->key, passphrase, sizeof(st->key));
268         } else if (security_type == SOFTAP_SECURITY_TYPE_OPEN) {
269                 g_strlcpy(st->security_type, SOFTAP_SECURITY_TYPE_OPEN_STR,
270                         sizeof(st->security_type));
271                 g_strlcpy(st->key, "00000000", sizeof(st->key));
272         } else {
273                 ERR("Unknown security type\n");
274                 return MOBILE_AP_ERROR_INTERNAL;
275         }
276
277         st->hide_mode = hide_mode;
278
279         SDBG("ssid : %s security type : %s hide mode : %d\n",
280                         st->ssid, st->security_type, st->hide_mode);
281
282         return MOBILE_AP_ERROR_NONE;
283 }
284
285 static gboolean __is_equal_softap_settings(softap_settings_t *a, softap_settings_t *b)
286 {
287         if (a->hide_mode != b->hide_mode)
288                 return FALSE;
289
290         if (strcmp(a->ssid, b->ssid) != 0)
291                 return FALSE;
292
293         if (strcmp(a->key, b->key) != 0)
294                 return FALSE;
295
296         if (strcmp(a->security_type, b->security_type) != 0)
297                 return FALSE;
298
299         return TRUE;
300 }
301
302 mobile_ap_error_code_e _reload_softap_settings(Tethering *obj,
303                 gchar *ssid, gchar *key, gint hide_mode, gint security_type)
304 {
305         gboolean backup_prev_wifi_on = prev_wifi_on;
306         mobile_ap_error_code_e ret;
307         softap_settings_t *old_settings = _get_softap_settings();
308         softap_settings_t new_settings;
309
310         if (obj == NULL || ssid == NULL || !strlen(ssid)) {
311                 ERR("invalid parameters\n");
312                 return MOBILE_AP_ERROR_INVALID_PARAM;
313         }
314
315         if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
316                 return MOBILE_AP_ERROR_NONE;
317
318         ret = __update_softap_settings(&new_settings, ssid, key, hide_mode,
319                         (softap_security_type_e)security_type);
320         if (ret != MOBILE_AP_ERROR_NONE) {
321                 ERR("__update_softap_settings is failed\n");
322                 return ret;
323         }
324
325         if (__is_equal_softap_settings(&new_settings, old_settings) == TRUE) {
326                 DBG("No need to reload settings\n");
327                 return MOBILE_AP_ERROR_NONE;
328         }
329
330         prev_wifi_on = FALSE;
331         ret = _disable_wifi_tethering(obj);
332
333         prev_wifi_on = backup_prev_wifi_on;
334         if (ret != MOBILE_AP_ERROR_NONE) {
335                 ERR("_disable_wifi_tethering is failed : %d\n", ret);
336                 return ret;
337         }
338
339         ret = _enable_wifi_tethering(obj, ssid, key, hide_mode,
340                         (softap_security_type_e)security_type);
341         if (ret != MOBILE_AP_ERROR_NONE) {
342                 ERR("_enable_wifi_tethering is failed : %d\n", ret);
343                 return ret;
344         }
345         tethering_emit_wifi_on(obj);
346         _create_tethering_active_noti();
347
348         return MOBILE_AP_ERROR_NONE;
349 }
350
351 mobile_ap_error_code_e _reload_softap_settings_for_ap(Tethering *obj,
352         gchar *ssid, gchar *key, gint hide_mode, gint security_type)
353 {
354         gboolean backup_prev_wifi_on = prev_wifi_on;
355         mobile_ap_error_code_e ret;
356         softap_settings_t *old_settings = _get_softap_settings();
357         softap_settings_t new_settings;
358
359         if (obj == NULL || ssid == NULL || !strlen(ssid)) {
360                 ERR("invalid parameters\n");
361                 return MOBILE_AP_ERROR_INVALID_PARAM;
362         }
363
364         ret = __update_softap_settings(&new_settings, ssid, key, hide_mode,
365                         (softap_security_type_e)security_type);
366         if (ret != MOBILE_AP_ERROR_NONE) {
367                 ERR("__update_softap_settings is failed\n");
368                 return ret;
369         }
370
371         if (__is_equal_softap_settings(&new_settings, old_settings) == TRUE) {
372                 DBG("No need to reload settings\n");
373                 return MOBILE_AP_ERROR_NONE;
374         }
375
376         prev_wifi_on = FALSE;
377
378         ret = _disable_wifi_ap(obj);
379         prev_wifi_on = backup_prev_wifi_on;
380         if (ret != MOBILE_AP_ERROR_NONE) {
381                 ERR("_disable_wifi_ap is failed : %d\n", ret);
382                 return ret;
383         }
384
385         ret = _enable_wifi_ap(obj, ssid, key, hide_mode,
386                         (softap_security_type_e)security_type);
387         if (ret != MOBILE_AP_ERROR_NONE) {
388                 ERR("_enable_wifi_ap is failed : %d\n", ret);
389                 return ret;
390         }
391
392         return MOBILE_AP_ERROR_NONE;
393 }
394
395 int _get_wifi_name_from_lease_info(const char *mac, char **name_buf)
396 {
397         if (mac == NULL || name_buf == NULL) {
398                 return MOBILE_AP_ERROR_INVALID_PARAM;
399         }
400
401         GIOChannel *io = NULL;
402         char *line = NULL;
403         char *device_name = MOBILE_AP_NAME_UNKNOWN;
404         char ip_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
405         char mac_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
406         char name[MOBILE_AP_STR_HOSTNAME_LEN] = {0, };
407         char expire[MOBILE_AP_STR_INFO_LEN] = {0, };
408         char extra[MOBILE_AP_STR_INFO_LEN] = {0, };
409
410         io = g_io_channel_new_file(DNSMASQ_LEASES_FILE, "r", NULL);
411         if (io == NULL) {
412                 return MOBILE_AP_ERROR_RESOURCE;
413         }
414
415         while (g_io_channel_read_line(io, &line, NULL, NULL, NULL) ==
416                         G_IO_STATUS_NORMAL) {
417                 sscanf(line, "%19s %19s %19s %19s %19s",
418                                 expire, mac_addr, ip_addr, name, extra);
419                 g_free(line);
420
421                 if (g_ascii_strcasecmp(mac_addr, mac) == 0) {
422                         if (g_strcmp0(name, "*") != 0)
423                                 device_name = name;
424                         break;
425                 }
426         }
427         g_io_channel_unref(io);
428
429         *name_buf = g_strdup(device_name);
430
431         return MOBILE_AP_ERROR_NONE;
432 }
433
434 mobile_ap_error_code_e _enable_wifi_tethering(Tethering *obj, gchar *ssid,
435         gchar *passphrase, int hide_mode, softap_security_type_e security_type)
436 {
437         mobile_ap_error_code_e ret;
438
439         if (obj == NULL || ssid == NULL || !strlen(ssid)) {
440                 ERR("invalid parameters\n");
441                 return MOBILE_AP_ERROR_INVALID_PARAM;
442         }
443
444         if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK && passphrase == NULL) {
445                 ERR("passphrase is null\n");
446                 return MOBILE_AP_ERROR_INVALID_PARAM;
447         }
448
449         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
450                 ERR("Wi-Fi AP is already enabled\n");
451                 ret = MOBILE_AP_ERROR_RESOURCE;
452                 return ret;
453         }
454
455         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
456                 ERR("Wi-Fi tethering is already enabled\n");
457                 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
458                 return ret;
459         }
460
461         /* Update global state */
462         if (!_mobileap_set_state(MOBILE_AP_STATE_WIFI)) {
463                 ret = MOBILE_AP_ERROR_RESOURCE;
464                 return ret;
465         }
466
467         /* Update Wi-Fi hotspot data to global settings pointer */
468         ret = __update_softap_settings(&obj_softap_settings, ssid, passphrase,
469                         hide_mode, security_type);
470         if (ret != MOBILE_AP_ERROR_NONE) {
471                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
472                 return ret;
473         }
474
475         if (vconf_set_str(VCONFKEY_MOBILE_HOTSPOT_SSID,
476                         obj_softap_settings.ssid) < 0) {
477                 ERR("vconf_set_str is failed\n");
478         }
479
480         /* Initialize tethering */
481         _block_device_sleep();
482         ret = _init_tethering();
483         if (ret != MOBILE_AP_ERROR_NONE) {
484                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
485                 goto DONE;
486         }
487
488         /* Upload driver */
489         ret = _mh_core_enable_softap(MOBILE_AP_TYPE_WIFI,
490                         obj_softap_settings.ssid,
491                         obj_softap_settings.security_type,
492                         obj_softap_settings.key,
493                         obj_softap_settings.hide_mode);
494         if (ret != MOBILE_AP_ERROR_NONE) {
495                 _deinit_tethering();
496                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
497                 goto DONE;
498         }
499         _delete_timeout_noti();
500
501         _init_timeout_cb(MOBILE_AP_TYPE_WIFI, (void *)obj);
502         _start_timeout_cb(MOBILE_AP_TYPE_WIFI, time(NULL) + TETHERING_CONN_TIMEOUT);
503
504         _add_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
505         _add_routing_rule(WIFI_IF);
506
507 DONE:
508         _unblock_device_sleep();
509         return ret;
510 }
511
512 mobile_ap_error_code_e _enable_wifi_ap(Tethering *obj,
513                                         gchar *ssid, gchar *passphrase, int hide_mode,
514                                         softap_security_type_e security_type)
515 {
516         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
517
518         if (obj == NULL || ssid == NULL || !strlen(ssid)) {
519                 ERR("invalid parameters\n");
520                 return MOBILE_AP_ERROR_INVALID_PARAM;
521         }
522
523         if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK &&
524                 (passphrase == NULL || strlen(passphrase) >= MOBILE_AP_WIFI_KEY_MAX_LEN)) {
525                 ERR("hex key length is not correct\n");
526                 return MOBILE_AP_ERROR_INVALID_PARAM;
527         }
528
529         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_BT
530                         | MOBILE_AP_STATE_USB)) {
531                 ERR("Tethering is already enabled\n");
532                 return MOBILE_AP_ERROR_RESOURCE;
533         }
534
535         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
536                 ERR("Wi-Fi AP is already enabled\n");
537                 return MOBILE_AP_ERROR_ALREADY_ENABLED;
538         }
539
540         if (!_mobileap_set_state(MOBILE_AP_STATE_WIFI_AP)) {
541                 return MOBILE_AP_ERROR_RESOURCE;
542         }
543         ret = __update_softap_settings(&obj_softap_settings, ssid, passphrase,
544                         hide_mode, security_type);
545         if (ret != MOBILE_AP_ERROR_NONE) {
546                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
547                 return ret;
548         }
549
550         _block_device_sleep();
551
552         if (_init_tethering() != MOBILE_AP_ERROR_NONE) {
553                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
554                 ret = MOBILE_AP_ERROR_RESOURCE;
555                 goto DONE;
556         }
557
558         /* Upload driver */
559         ret = _mh_core_enable_softap(MOBILE_AP_TYPE_WIFI_AP,
560                         obj_softap_settings.ssid,
561                         obj_softap_settings.security_type,
562                         obj_softap_settings.key,
563                         obj_softap_settings.hide_mode);
564         if (ret != MOBILE_AP_ERROR_NONE) {
565                 _deinit_tethering();
566                 _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
567                 goto DONE;
568         }
569
570         _delete_timeout_noti();
571         _init_timeout_cb(MOBILE_AP_TYPE_WIFI_AP, (void *)obj);
572         _start_timeout_cb(MOBILE_AP_TYPE_WIFI_AP, time(NULL) + WIFI_AP_CONN_TIMEOUT);
573         _add_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
574         _add_routing_rule(WIFI_IF);
575
576 DONE:
577         _unblock_device_sleep();
578         return ret;
579 }
580
581 mobile_ap_error_code_e _disable_wifi_tethering(Tethering *obj)
582 {
583         int ret;
584         int state;
585         mobile_ap_type_e type;
586
587         type = MOBILE_AP_TYPE_WIFI;
588         state = MOBILE_AP_STATE_WIFI;
589
590         if (!_mobileap_is_enabled(state)) {
591                 ERR("Wi-Fi tethering ap has not been activated\n");
592                 ret = MOBILE_AP_ERROR_NOT_ENABLED;
593                 return ret;
594         }
595
596         _block_device_sleep();
597         _del_routing_rule(WIFI_IF);
598         _del_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
599         _flush_ip_address(WIFI_IF);
600         _deinit_timeout_cb(type);
601
602         if (_remove_station_info_all(type) != MOBILE_AP_ERROR_NONE) {
603                 ERR("_remove_station_info_all is failed. Ignore it.\n");
604         }
605
606         ret = _mh_core_disable_softap();
607         if (ret != MOBILE_AP_ERROR_NONE) {
608                 ERR("_mh_core_disable_softap is failed : %d\n", ret);
609                 goto DONE;
610         }
611
612         _deinit_tethering();
613         _mobileap_clear_state(state);
614
615         if (prev_wifi_on == TRUE) {
616                 DBG("Previous Wi-Fi was turned on. Recover it\n");
617                 if (__turn_on_wifi() != MOBILE_AP_ERROR_NONE) {
618                         ERR("__turn_on_wifi() is failed\n");
619                 }
620                 prev_wifi_on = FALSE;
621         }
622         DBG("_disable_wifi_tethering is done\n");
623
624 DONE:
625         _unblock_device_sleep();
626         return ret;
627 }
628
629 mobile_ap_error_code_e _disable_wifi_ap(Tethering *obj)
630 {
631         int ret;
632         int state;
633         mobile_ap_type_e type;
634
635         type = MOBILE_AP_TYPE_WIFI_AP;
636         state = MOBILE_AP_STATE_WIFI_AP;
637
638         if (!_mobileap_is_enabled(state)) {
639                 ERR("Wi-Fi ap tethering has not been activated\n");
640                 ret = MOBILE_AP_ERROR_NOT_ENABLED;
641                 return ret;
642         }
643
644         _block_device_sleep();
645         _del_routing_rule(WIFI_IF);
646         _del_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
647         _flush_ip_address(WIFI_IF);
648         _deinit_timeout_cb(type);
649
650         if (_remove_station_info_all(type) != MOBILE_AP_ERROR_NONE) {
651                 ERR("_remove_station_info_all is failed. Ignore it.\n");
652         }
653
654         ret = _mh_core_disable_softap();
655         if (ret != MOBILE_AP_ERROR_NONE) {
656                 ERR("_mh_core_disable_softap is failed : %d\n", ret);
657                 goto DONE;
658         }
659
660         _deinit_tethering();
661         _mobileap_clear_state(state);
662
663         DBG("_disable_wifi_ap is done\n");
664
665 DONE:
666         _unblock_device_sleep();
667         return ret;
668 }
669
670 gboolean tethering_enable_wifi_tethering(Tethering *obj,
671                 GDBusMethodInvocation *context, gchar *ssid,
672                 gchar *key, gint visibility, gint security_type)
673 {
674         DBG("+\n");
675         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
676         gboolean ret_val = FALSE;
677         bool wifi_state = false;
678         g_assert(obj != NULL);
679         g_assert(context != NULL);
680
681         if (g_context) {
682                 DBG("It is turnning on\n");
683                 tethering_complete_enable_wifi_tethering(obj, g_context,
684                                 MOBILE_AP_ERROR_IN_PROGRESS);
685                 return FALSE;
686         }
687         g_context = context;
688
689         wifi_settings.ssid = g_strdup(ssid);
690         if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK) {
691                 wifi_settings.key = g_strdup(key);
692                 wifi_settings.security_type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
693         } else {
694                 wifi_settings.security_type = SOFTAP_SECURITY_TYPE_OPEN;
695         }
696         wifi_settings.hide_mode = (!visibility);
697
698         if (wifi_recovery_timeout_id) {
699                 DBG("Wi-Fi recovery is cancelled\n");
700                 g_source_remove(wifi_recovery_timeout_id);
701                 wifi_recovery_timeout_id = 0;
702                 prev_wifi_on = TRUE;
703         }
704
705         if (__is_wifi_direct_on() == TRUE) {
706                 DBG("Wi-Fi and Wi-Fi direct are turned on\n");
707                 if (__turn_off_wifi_direct(obj) != MOBILE_AP_ERROR_NONE) {
708                         ERR("_turn_off_wifi_direct is failed\n");
709                         ret = MOBILE_AP_ERROR_INTERNAL;
710                         goto DONE;
711                 }
712
713                 return TRUE;
714         }
715
716         wifi_is_activated(&wifi_state);
717         if (wifi_state == true) {
718                 DBG("Wi-Fi is turned on\n");
719                 if (__turn_off_wifi(obj) != MOBILE_AP_ERROR_NONE) {
720                         ERR("_turn_off_wifi is failed\n");
721                         ret = MOBILE_AP_ERROR_INTERNAL;
722                         goto DONE;
723                 }
724
725                 return TRUE;
726         }
727
728         ret = _enable_wifi_tethering(obj, ssid, key, !visibility,
729                         (softap_security_type_e)security_type);
730         if (ret != MOBILE_AP_ERROR_NONE) {
731                 ERR("_enable_wifi_tethering is failed\n");
732         } else {
733                 tethering_emit_wifi_on(obj);
734                 _create_tethering_active_noti();
735                 ret_val = TRUE;
736         }
737
738 DONE:
739         tethering_complete_enable_wifi_tethering(obj, g_context, ret);
740         g_context = NULL;
741
742         g_free(wifi_settings.ssid);
743         g_free(wifi_settings.key);
744         memset(&wifi_settings, 0, sizeof(wifi_settings));
745
746         return ret_val;
747 }
748
749 gboolean tethering_disable_wifi_tethering(Tethering *obj,
750                 GDBusMethodInvocation *context)
751 {
752         int ret = MOBILE_AP_ERROR_NONE;
753
754         DBG("+\n");
755         g_assert(obj != NULL);
756         g_assert(context != NULL);
757
758         ret = _disable_wifi_tethering(obj);
759
760         tethering_emit_wifi_off(obj, NULL);
761         tethering_complete_disable_wifi_tethering(obj, context,
762                         MOBILE_AP_DISABLE_WIFI_TETHERING_CFM, ret);
763
764
765         if (ret != MOBILE_AP_ERROR_NONE)
766                 return FALSE;
767
768         return TRUE;
769 }
770
771 gboolean tethering_enable_wifi_ap(Tethering *obj, GDBusMethodInvocation *context,
772                 gchar *ssid, gchar *key, gint visibility, gint security_type)
773 {
774         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
775         gboolean ret_val = FALSE;
776
777         DBG("+\n");
778         g_assert(obj != NULL);
779         g_assert(context != NULL);
780
781         if (wifi_recovery_timeout_id) {
782                 DBG("Wi-Fi recovery is cancelled\n");
783                 g_source_remove(wifi_recovery_timeout_id);
784                 wifi_recovery_timeout_id = 0;
785         }
786
787         ret = _enable_wifi_ap(obj, ssid, key, !visibility,
788                         (softap_security_type_e)security_type);
789         if (ret != MOBILE_AP_ERROR_NONE) {
790                 ERR("_enable_wifi_tethering is failed\n");
791         } else {
792                 tethering_emit_wifi_ap_on(obj);
793                 ret_val = TRUE;
794         }
795         tethering_complete_enable_wifi_ap(obj, context, ret);
796         return ret_val;
797 }
798
799 gboolean tethering_disable_wifi_ap(Tethering *obj,
800                 GDBusMethodInvocation *context)
801 {
802         int ret = MOBILE_AP_ERROR_NONE;
803
804         DBG("+\n");
805         g_assert(obj != NULL);
806         g_assert(context != NULL);
807
808         ret = _disable_wifi_ap(obj);
809         tethering_emit_wifi_ap_off(obj, NULL);
810         tethering_complete_disable_wifi_ap(obj, g_context,
811                         MOBILE_AP_ENABLE_WIFI_AP_CFM, ret);
812
813         if (ret != MOBILE_AP_ERROR_NONE)
814                 return FALSE;
815
816         return TRUE;
817 }
818
819 gboolean tethering_reload_wifi_settings(Tethering *obj,
820                 GDBusMethodInvocation *context, gchar *ssid,
821                 gchar *key, gint visibility, gint security_type)
822 {
823         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
824         gboolean ret_val = TRUE;
825
826         DBG("+\n");
827         g_assert(obj != NULL);
828         g_assert(context != NULL);
829
830         ret = _reload_softap_settings(obj, ssid, key, !visibility, security_type);
831         if (ret != MOBILE_AP_ERROR_NONE) {
832                 ERR("_reload_softap_settings is failed\n");
833                 ret_val = FALSE;
834         }
835
836         tethering_complete_reload_wifi_settings(obj, context, ret);
837
838         return ret_val;
839 }
840
841 gboolean tethering_reload_wifi_ap_settings(Tethering *obj,
842                 GDBusMethodInvocation *context, gchar *ssid,
843         gchar *key, gint visibility, gint security)
844 {
845
846         mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
847         gboolean ret_val = TRUE;
848
849         DBG("+\n");
850         g_assert(obj != NULL);
851         g_assert(context != NULL);
852
853         ret = _reload_softap_settings_for_ap(obj, ssid, key, !visibility, security);
854         if (ret != MOBILE_AP_ERROR_NONE) {
855                 ERR("_reload_softap_settings_for_ap is failed\n");
856                 ret_val = FALSE;
857         }
858
859         tethering_complete_reload_wifi_ap_settings(obj, context, ret);
860         return ret_val;
861 }
862
863 gboolean _is_trying_wifi_operation(void)
864 {
865         return (g_context || wifi_recovery_timeout_id ? TRUE : FALSE);
866 }