4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>,
7 * Injun Yang <injun.yang@samsung.com>,
8 * Seungyoun Ju <sy39.ju@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <dbus/dbus.h>
26 #include <dbus/dbus-glib.h>
27 #include <dbus/dbus-glib-lowlevel.h>
31 #include <ss_manager.h>
33 #include "mobileap_agent.h"
34 #include "mobileap_common.h"
35 #include "mobileap_wifi.h"
37 static int __generate_initial_passphrase(char *passphrase_buf);
38 static mobile_ap_error_code_e __get_hide_mode(int *hide_mode);
39 static mobile_ap_error_code_e __set_hide_mode(const int hide_mode);
40 static mobile_ap_error_code_e __get_ssid(char *ssid, unsigned int size);
41 static mobile_ap_error_code_e __get_security_type(char *security_type, unsigned int len);
42 static mobile_ap_error_code_e __set_security_type(const char *security_type);
43 static mobile_ap_error_code_e __get_passphrase(char *passphrase, unsigned int size, unsigned int *passphrase_len);
44 static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size);
45 static gboolean __send_station_event_cb(gpointer data);
46 static void __handle_station_signal(int sig);
47 static mobile_ap_error_code_e __update_wifi_data(MobileAPObject *obj);
49 static int __generate_initial_passphrase(char *passphrase_buf)
56 for (index = 0; index < MOBILE_AP_WIFI_KEY_MIN_LEN; index++) {
57 rand_int = g_random_int_range('a', 'z');
58 passphrase_buf[index] = rand_int;
60 passphrase_buf[index] = '\0';
65 static mobile_ap_error_code_e __get_hide_mode(int *hide_mode)
67 if (hide_mode == NULL) {
68 ERR("Invalid param\n");
69 return MOBILE_AP_ERROR_INVALID_PARAM;
72 if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, hide_mode) < 0) {
73 ERR("vconf_get_int is failed\n");
74 return MOBILE_AP_ERROR_RESOURCE;
77 return MOBILE_AP_ERROR_NONE;
80 static mobile_ap_error_code_e __set_hide_mode(const int hide_mode)
82 if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, hide_mode) < 0) {
83 ERR("vconf_set_int is failed\n");
84 return MOBILE_AP_ERROR_RESOURCE;
87 return MOBILE_AP_ERROR_NONE;
90 static mobile_ap_error_code_e __get_ssid(char *ssid, unsigned int size)
93 return MOBILE_AP_ERROR_INVALID_PARAM;
98 ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
100 return MOBILE_AP_ERROR_RESOURCE;
102 if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp))
105 g_strlcpy(ssid, ptr, size);
108 return MOBILE_AP_ERROR_NONE;
111 static mobile_ap_error_code_e __get_security_type(char *security_type, unsigned int len)
113 if (security_type == NULL)
114 return MOBILE_AP_ERROR_INVALID_PARAM;
116 char *type_str = NULL;
117 softap_security_type_e type;
119 if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, (int *)&type) < 0) {
120 ERR("vconf_get_int is failed\n");
121 return MOBILE_AP_ERROR_RESOURCE;
125 case SOFTAP_SECURITY_TYPE_OPEN:
126 type_str = SOFTAP_SECURITY_TYPE_OPEN_STR;
129 case SOFTAP_SECURITY_TYPE_WPA2_PSK:
130 type_str = SOFTAP_SECURITY_TYPE_WPA2_PSK_STR;
134 ERR("Invalid data\n");
135 return MOBILE_AP_ERROR_RESOURCE;
138 g_strlcpy(security_type, type_str, len);
140 return MOBILE_AP_ERROR_NONE;
143 static mobile_ap_error_code_e __set_security_type(const char *security_type)
145 if (security_type == NULL) {
146 ERR("Invalid param\n");
147 return MOBILE_AP_ERROR_INVALID_PARAM;
150 softap_security_type_e type;
152 if (!strcmp(security_type, SOFTAP_SECURITY_TYPE_OPEN_STR)) {
153 type = SOFTAP_SECURITY_TYPE_OPEN;
154 } else if (!strcmp(security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR)) {
155 type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
157 ERR("Invalid param\n");
158 return MOBILE_AP_ERROR_INVALID_PARAM;
161 if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, type) < 0) {
162 ERR("vconf_set_int is failed\n");
163 return MOBILE_AP_ERROR_RESOURCE;
166 return MOBILE_AP_ERROR_NONE;
169 static mobile_ap_error_code_e __get_passphrase(char *passphrase,
170 unsigned int size, unsigned int *passphrase_len)
172 if (passphrase == NULL || passphrase_len == NULL) {
173 ERR("Invalid parameter\n");
174 return MOBILE_AP_ERROR_INVALID_PARAM;
180 ret = ssm_getinfo(SOFTAP_PASSPHRASE_PATH, &sfi,
181 SSM_FLAG_SECRET_OPERATION, NULL);
182 if (ret == -SS_FILE_OPEN_ERROR) {
183 *passphrase_len = __generate_initial_passphrase(passphrase);
185 ret = __set_passphrase(passphrase, *passphrase_len);
186 if (ret != MOBILE_AP_ERROR_NONE) {
187 memset(passphrase, 0x00, size);
192 ret = ssm_getinfo(SOFTAP_PASSPHRASE_PATH, &sfi,
193 SSM_FLAG_SECRET_OPERATION, NULL);
195 ERR("ssm_getinfo is failed : %d\n", ret);
196 memset(passphrase, 0x00, size);
198 return MOBILE_AP_ERROR_RESOURCE;
200 } else if (ret < 0) {
201 ERR("ssm_getinfo is failed : %d\n", ret);
202 return MOBILE_AP_ERROR_RESOURCE;
205 memset(passphrase, 0x00, size);
206 ret = ssm_read(SOFTAP_PASSPHRASE_PATH, passphrase, sfi.originSize,
207 passphrase_len, SSM_FLAG_SECRET_OPERATION, NULL);
209 ERR("ssm_read is failed : %d\n", ret);
210 return MOBILE_AP_ERROR_RESOURCE;
213 return MOBILE_AP_ERROR_NONE;
216 static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size)
218 if (size < MOBILE_AP_WIFI_KEY_MIN_LEN || size > MOBILE_AP_WIFI_KEY_MAX_LEN ||
219 passphrase == NULL) {
220 ERR("Invalid parameter\n");
221 return MOBILE_AP_ERROR_INVALID_PARAM;
226 ret = ssm_write_buffer((char *)passphrase, size, SOFTAP_PASSPHRASE_PATH,
227 SSM_FLAG_SECRET_OPERATION, NULL);
229 ERR("ssm_write_buffer is failed : %d\n", ret);
230 return MOBILE_AP_ERROR_RESOURCE;
233 return MOBILE_AP_ERROR_NONE;
236 static gboolean __send_station_event_cb(gpointer data)
238 int sig = GPOINTER_TO_INT(data);
239 mobile_ap_station_info_t *si = NULL;
241 if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
245 if (sig == SIGUSR1) {
246 DBG("STA connected(%d)\n", sig);
247 /* STA connection is handled in the dnsmasq signal handler */
248 } else if (sig == SIGUSR2) {
249 DBG("STA disconnected(%d)\n", sig);
251 /* Temporarily care only one station.
252 * Driver team should be support detail information */
253 if (_get_station_info(MOBILE_AP_TYPE_WIFI,
254 _slist_find_station_by_interface,
255 &si) != MOBILE_AP_ERROR_NONE) {
258 _remove_station_info(si->mac, _slist_find_station_by_mac);
264 static void __handle_station_signal(int sig)
266 g_idle_add(__send_station_event_cb, GINT_TO_POINTER(sig));
270 void _register_wifi_station_handler(void)
274 memset(&sa, 0, sizeof(sa));
275 sa.sa_handler = __handle_station_signal;
276 sigaction(SIGUSR1, &sa, NULL);
277 sigaction(SIGUSR2, &sa, NULL);
280 void _add_wifi_device_to_array(softap_device_info_t *di, GPtrArray *array)
283 GIOChannel *io = NULL;
285 gchar *device_name = NULL;
286 gchar ip_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
287 gchar mac_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
288 gchar name[MOBILE_AP_STR_HOSTNAME_LEN] = {0, };
289 gchar expire[MOBILE_AP_STR_INFO_LEN] = {0, };
290 gchar extra[MOBILE_AP_STR_INFO_LEN] = {0, };
294 for (i = 0; i < di->number; i++)
295 DBG("bssid[%d]:%s\n", i, di->bssid[i]);
297 DBG("Number of connected device:%d\n", di->number);
299 io = g_io_channel_new_file(DNSMASQ_LEASES_FILE, "r", NULL);
301 while (g_io_channel_read_line(io, &line, NULL, NULL, NULL) ==
302 G_IO_STATUS_NORMAL) {
303 sscanf(line, "%19s %19s %19s %19s %19s", expire, mac_addr,
304 ip_addr, name, extra);
305 DBG("mac_addr:%s ip_addr:%s name:%s expire:%s\n", mac_addr,
306 ip_addr, name, expire);
308 for (i = 0; i < di->number; i++) {
309 if (g_ascii_strcasecmp(di->bssid[i], mac_addr) == 0) {
310 if (!strcmp(name, "*"))
311 device_name = MOBILE_AP_NAME_UNKNOWN;
315 _mh_core_add_data_to_array(array, MOBILE_AP_TYPE_WIFI,
326 g_io_channel_unref(io);
328 /* Set the name UNKNOWN unless we got the name. */
329 for (i = found; i < di->number; i++) {
330 _mh_core_add_data_to_array(array, MOBILE_AP_TYPE_WIFI,
331 MOBILE_AP_NAME_UNKNOWN);
335 mobile_ap_error_code_e _disable_wifi_tethering(MobileAPObject *obj)
337 int ret = MOBILE_AP_ERROR_NONE;
339 if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
340 ERR("Wi-Fi tethering has not been activated\n");
341 ret = MOBILE_AP_ERROR_NOT_ENABLED;
345 if (_remove_station_info_all(MOBILE_AP_TYPE_WIFI) !=
346 MOBILE_AP_ERROR_NONE) {
347 ERR("_remove_station_info_all is failed. Ignore it.\n");
350 ret = _mh_core_disable_softap();
351 if (ret != MOBILE_AP_ERROR_NONE) {
352 ERR("_mh_core_disable_softap is failed : %d\n", ret);
356 _deinit_tethering(obj);
357 _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
359 DBG("_disable_wifi_tethering is done\n");
364 static mobile_ap_error_code_e __update_wifi_data(MobileAPObject *obj)
367 ERR("Invalid param\n");
368 return MOBILE_AP_ERROR_INVALID_PARAM;
371 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
372 unsigned int read_len = 0;
374 ret = __get_ssid(obj->ssid, sizeof(obj->ssid));
375 if (ret != MOBILE_AP_ERROR_NONE)
378 ret = __get_security_type(obj->security_type, sizeof(obj->security_type));
379 if (ret != MOBILE_AP_ERROR_NONE)
382 ret = __get_hide_mode(&obj->hide_mode);
383 if (ret != MOBILE_AP_ERROR_NONE)
386 if (strcmp(obj->security_type, SOFTAP_SECURITY_TYPE_OPEN_STR) == 0) {
387 g_strlcpy(obj->key, "00000000", sizeof(obj->key));
388 } else if (strcmp(obj->security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR) == 0) {
389 ret = __get_passphrase(obj->key, sizeof(obj->key), &read_len);
390 if (ret != MOBILE_AP_ERROR_NONE)
393 ERR("Unknown security type\n");
394 return MOBILE_AP_ERROR_INTERNAL;
397 DBG("ssid : %s security type : %s hide mode : %d\n",
398 obj->ssid, obj->security_type, obj->hide_mode);
400 return MOBILE_AP_ERROR_NONE;
403 gboolean mobileap_enable_wifi_tethering(MobileAPObject *obj, gchar *ssid,
404 gchar *key, gint hide_mode, DBusGMethodInvocation *context)
406 int ret = MOBILE_AP_ERROR_NONE;
408 g_assert(obj != NULL);
409 g_assert(context != NULL);
412 if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
413 ERR("Wi-Fi tethering is already enabled\n");
414 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
415 dbus_g_method_return(context,
416 MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
420 /* Update global state */
421 if (!_mobileap_set_state(MOBILE_AP_STATE_WIFI)) {
422 ret = MOBILE_AP_ERROR_RESOURCE;
426 /* Update Wi-Fi hotspot data to common object */
427 ret = __update_wifi_data(obj);
428 if (ret != MOBILE_AP_ERROR_NONE) {
432 /* Initialize tethering */
433 if (!_init_tethering(obj)) {
434 ret = MOBILE_AP_ERROR_RESOURCE;
439 ret = _mh_core_enable_softap(obj->ssid, obj->security_type,
440 obj->key, obj->hide_mode);
441 if (ret != MOBILE_AP_ERROR_NONE) {
442 _deinit_tethering(obj);
446 _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_TETHER_ON, NULL);
447 dbus_g_method_return(context, MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
452 _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
453 dbus_g_method_return(context, MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
458 gboolean mobileap_disable_wifi_tethering(MobileAPObject *obj,
459 DBusGMethodInvocation *context)
461 int ret = MOBILE_AP_ERROR_NONE;
464 g_assert(obj != NULL);
465 g_assert(context != NULL);
467 ret = _disable_wifi_tethering(obj);
469 _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_TETHER_OFF, NULL);
470 dbus_g_method_return(context, MOBILE_AP_DISABLE_WIFI_TETHERING_CFM, ret);
472 if (ret != MOBILE_AP_ERROR_NONE)
478 gboolean mobileap_get_wifi_tethering_hide_mode(MobileAPObject *obj,
479 DBusGMethodInvocation *context)
481 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
485 g_assert(obj != NULL);
486 g_assert(context != NULL);
488 ret = __get_hide_mode(&hide_mode);
489 if (ret != MOBILE_AP_ERROR_NONE) {
490 ERR("__get_hide_mode is failed : %d\n", ret);
493 dbus_g_method_return(context, hide_mode);
498 gboolean mobileap_set_wifi_tethering_hide_mode(MobileAPObject *obj,
499 gint hide_mode, DBusGMethodInvocation *context)
504 g_assert(obj != NULL);
505 g_assert(context != NULL);
507 ret = __set_hide_mode(hide_mode);
509 ERR("__set_hide_mode is failed : %d\n", ret);
512 dbus_g_method_return(context);
517 gboolean mobileap_get_wifi_tethering_ssid(MobileAPObject *obj,
518 DBusGMethodInvocation *context)
520 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
521 char ssid[MOBILE_AP_WIFI_SSID_MAX_LEN + 1] = {0, };
524 g_assert(obj != NULL);
525 g_assert(context != NULL);
527 ret = __get_ssid(ssid, sizeof(ssid));
528 if (ret != MOBILE_AP_ERROR_NONE) {
529 ERR("__get_ssid is failed : %d\n", ret);
532 dbus_g_method_return(context, ssid);
538 gboolean mobileap_get_wifi_tethering_security_type(MobileAPObject *obj,
539 DBusGMethodInvocation *context)
541 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
542 char security_type[SECURITY_TYPE_LEN] = {0, };
545 g_assert(obj != NULL);
546 g_assert(context != NULL);
548 ret = __get_security_type(security_type, sizeof(security_type));
549 if (ret != MOBILE_AP_ERROR_NONE) {
550 ERR("__get_security_type is failed : %d\n", ret);
553 dbus_g_method_return(context, security_type);
558 gboolean mobileap_set_wifi_tethering_security_type(MobileAPObject *obj,
559 gchar *security_type, DBusGMethodInvocation *context)
564 g_assert(obj != NULL);
565 g_assert(context != NULL);
567 ret = __set_security_type(security_type);
569 ERR("__set_security_type is failed: %d\n", ret);
572 dbus_g_method_return(context);
577 gboolean mobileap_get_wifi_tethering_passphrase(MobileAPObject *obj,
578 DBusGMethodInvocation *context)
580 int ret = MOBILE_AP_ERROR_NONE;
581 char passphrase[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, };
582 unsigned int len = 0;
585 g_assert(obj != NULL);
586 g_assert(context != NULL);
588 ret = __get_passphrase(passphrase, sizeof(passphrase), &len);
589 if (ret != MOBILE_AP_ERROR_NONE) {
591 ERR("__get_password is failed : %d\n", ret);
594 dbus_g_method_return(context, passphrase, len);
599 gboolean mobileap_set_wifi_tethering_passphrase(MobileAPObject *obj,
600 gchar *passphrase, guint len, DBusGMethodInvocation *context)
602 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
605 g_assert(obj != NULL);
606 g_assert(context != NULL);
608 ret = __set_passphrase(passphrase, len);
609 if (ret != MOBILE_AP_ERROR_NONE) {
610 ERR("__set_passphrase is failed : %d\n", ret);
613 dbus_g_method_return(context);