CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(mobileap-agent C)
-SET(SRCS src/mobileap_agent.c
+SET(SRCS src/mobileap_softap.c
src/mobileap_main.c
src/mobileap_wifi.c
src/mobileap_usb.c
src/mobileap_common.c
src/mobileap_notification.c
src/mobileap_network.c
+ src/mobileap_iptables.c
)
SET(CMAKE_INSTALL_PREFIX /usr)
-SET(APP_VENDOR "tizen")
+SET(APP_VENDOR "samsung")
SET(APP_NAME mobileap-agent)
SET(APP_DIR ${CMAKE_INSTALL_PREFIX}/bin)
SET(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
INCLUDE_DIRECTORIES(${INCLUDE_DIR})
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED dlog dbus-glib-1 pmapi vconf notification libssl secure-storage capi-network-connection capi-network-bluetooth appcore-common ${PRIVATE_REQUIRED_PKGS})
+pkg_check_modules(pkgs REQUIRED gio-2.0 dlog dbus-glib-1 deviced vconf notification capi-network-connection capi-network-bluetooth appcore-common capi-network-wifi capi-network-wifi-direct alarm-service appsvc libssl)
FOREACH(flag ${pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/org.tizen.tethering.service DESTINATION share/dbus-1/services)
-INSTALL(FILES ${CMAKE_BINARY_DIR}/mobileap-agent.rule DESTINATION /opt/etc/smack/accesses.d)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tethering_dump.sh DESTINATION /opt/etc/dump.d/module.d/)
#define SIGNAL_NAME_USB_TETHER_OFF "usb_off"
#define SIGNAL_NAME_BT_TETHER_ON "bluetooth_on"
#define SIGNAL_NAME_BT_TETHER_OFF "bluetooth_off"
+#define SIGNAL_NAME_WIFI_AP_ON "wifi_ap_on"
+#define SIGNAL_NAME_WIFI_AP_OFF "wifi_ap_off"
#define SIGNAL_NAME_NO_DATA_TIMEOUT "no_data_timeout"
#define SIGNAL_NAME_LOW_BATTERY_MODE "low_batt_mode"
#define SIGNAL_NAME_FLIGHT_MODE "flight_mode"
+#define SIGNAL_NAME_POWER_SAVE_MODE "power_save_mode"
#define SIGNAL_NAME_DHCP_STATUS "dhcp_status"
#define SIGNAL_NAME_SECURITY_TYPE_CHANGED "security_type_changed"
#define SIGNAL_NAME_SSID_VISIBILITY_CHANGED "ssid_visibility_changed"
E_SIGNAL_USB_TETHER_OFF,
E_SIGNAL_BT_TETHER_ON,
E_SIGNAL_BT_TETHER_OFF,
+ E_SIGNAL_WIFI_AP_ON,
+ E_SIGNAL_WIFI_AP_OFF,
E_SIGNAL_NO_DATA_TIMEOUT,
E_SIGNAL_LOW_BATTERY_MODE,
E_SIGNAL_FLIGHT_MODE,
+ E_SIGNAL_POWER_SAVE_MODE,
E_SIGNAL_SECURITY_TYPE_CHANGED,
E_SIGNAL_SSID_VISIBILITY_CHANGED,
E_SIGNAL_PASSPHRASE_CHANGED,
*/
#define MOBILE_AP_WIFI_CHANNEL 6 /**< Channel number */
#define MOBILE_AP_WIFI_BSSID_LEN 6 /**< BSSID Length */
-#define MOBILE_AP_WIFI_SSID_MAX_LEN 31 /**< Maximum length of ssid */
+#define MOBILE_AP_WIFI_SSID_MAX_LEN 32 /**< Maximum length of ssid */
#define MOBILE_AP_WIFI_KEY_MIN_LEN 8 /**< Minimum length of wifi key */
-#define MOBILE_AP_WIFI_KEY_MAX_LEN 63 /**< Maximum length of wifi key */
+#define MOBILE_AP_WIFI_PLAIN_TEXT_KEY_MAX_LEN 63 /**< Maximum length of wifi plain text key */
+#define MOBILE_AP_WIFI_KEY_MAX_LEN 64 /**< Maximum length of wifi hash key */
/**
* Common configuration
*/
-#define MOBILE_AP_MAX_WIFI_STA 8
-#define MOBILE_AP_MAX_BT_STA 7
-#define MOBILE_AP_MAX_USB_STA 1
-#define MOBILE_AP_MAX_CONNECTED_STA 16 /**< Maximum connected station. 8(Wi-Fi) + 7(BT) + 1(USB) */
+#define MOBILE_AP_MAX_WIFI_STA 10 /**< Firmware limitation (BCM4339) */
+#define MOBILE_AP_MAX_BT_STA 4 /**< Bluetooth specification (1 Master and 4 Slaves) */
+#define MOBILE_AP_MAX_USB_STA 1 /**< Only one usb connection is possible */
+#define MOBILE_AP_MAX_CONNECTED_STA 15 /**< Maximum connected station. 10(Wi-Fi) + 4(BT) + 1(USB) */
#define MOBILE_AP_STR_INFO_LEN 20 /**< length of the ip or mac address*/
-#define MOBILE_AP_STR_HOSTNAME_LEN 32 /**< length of the hostname */
+#define MOBILE_AP_STR_HOSTNAME_LEN 33 /**< length of the hostname */
#define MOBILE_AP_NAME_UNKNOWN "UNKNOWN"
/**
MOBILE_AP_ERROR_DHCP, /**< DHCP error */
MOBILE_AP_ERROR_IN_PROGRESS, /**< Request is in progress */
MOBILE_AP_ERROR_NOT_PERMITTED, /**< Operation is not permitted */
+ MOBILE_AP_ERROR_PERMISSION_DENIED, /**< Permission Denied */
MOBILE_AP_ERROR_MAX
} mobile_ap_error_code_e;
MOBILE_AP_ENABLE_BT_TETHERING_CFM, /* mobile_ap_enable_bt_tethering() */
MOBILE_AP_DISABLE_BT_TETHERING_CFM, /* mobile_ap_disable_bt_tethering() */
+ MOBILE_AP_ENABLE_WIFI_AP_CFM, /* mobile_ap_enable_wifi_ap() */
+ MOBILE_AP_DISABLE_WIFI_AP_CFM, /* mobile_ap_disable_wifi_ap() */
+
MOBILE_AP_GET_STATION_INFO_CFM, /* mobile_ap_get_station_info() */
MOBILE_AP_GET_DATA_PACKET_USAGE_CFM, /* mobile_ap_get_data_packet_usage() */
MOBILE_AP_ENABLED_BT_TETHERING_IND, /* Turning on BT tethering indication */
MOBILE_AP_DISABLED_BT_TETHERING_IND, /* Turning off BT tethering indication */
+ MOBILE_AP_ENABLED_WIFI_AP_IND, /* Turning on WiFi AP indication */
+ MOBILE_AP_DISABLED_WIFI_AP_IND, /* Turning off WiFi AP indication */
+
MOBILE_AP_STATION_CONNECT_IND, /* Station connection indication */
MOBILE_AP_STATION_DISCONNECT_IND, /* Station disconnection indication */
MOBILE_AP_USB_STATION_CONNECT_IND,
MOBILE_AP_TYPE_WIFI,
MOBILE_AP_TYPE_USB,
MOBILE_AP_TYPE_BT,
+ MOBILE_AP_TYPE_WIFI_AP,
MOBILE_AP_TYPE_MAX,
} mobile_ap_type_e;
mobile_ap_type_e interface; /**< interface type */
char ip[MOBILE_AP_STR_INFO_LEN]; /**< assigned IP address */
char mac[MOBILE_AP_STR_INFO_LEN]; /**< MAC Address */
- char hostname[MOBILE_AP_STR_HOSTNAME_LEN]; /**< alphanumeric name */
+ char *hostname;
time_t tm; /**< connection time*/
} mobile_ap_station_info_t;
#ifndef __MOBILEAP_BLUETOOTH_H__
#define __MOBILEAP_BLUETOOTH_H__
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
+
+#define PS_RECHECK_INTERVAL 500
+#define PS_RECHECK_COUNT_MAX 5
void _bt_get_remote_device_name(TetheringObject *obj, const char *mac, char **name);
mobile_ap_error_code_e _disable_bt_tethering(TetheringObject *obj);
+gboolean _is_trying_bt_operation(void);
gboolean tethering_enable_bt_tethering(TetheringObject *obj,
DBusGMethodInvocation *context);
#include <glib.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
gint _slist_find_station_by_interface(gconstpointer a, gconstpointer b);
gint _slist_find_station_by_mac(gconstpointer a, gconstpointer b);
mobile_ap_station_info_t **si);
int _get_station_count(gconstpointer data, GCompareFunc func, int *count);
int _station_info_foreach(GFunc func, void *user_data);
-int _add_data_usage_rule(const char *src, const char *dest);
-int _del_data_usage_rule(const char *src, const char *dest);
-int _get_data_usage(const char *src, const char *dest, unsigned long long *tx, unsigned long long *rx);
+int _add_interface_routing(const char *interface, const in_addr_t gateway);
+int _del_interface_routing(const char *interface, const in_addr_t gateway);
+int _add_routing_rule(const char *interface);
+int _del_routing_rule(const char *interface);
+int _flush_ip_address(const char *interface);
int _execute_command(const char *cmd);
int _get_tethering_type_from_ip(const char *ip, mobile_ap_type_e *type);
#ifndef __MOBILEAP_HANDLER_H__
#define __MOBILEAP_HANDLER_H__
+#include <time.h>
+#include <alarm.h>
+
+typedef struct {
+ void *obj;
+ unsigned int state;
+} changed_state_t;
+
void _register_vconf_cb(void *user_data);
void _unregister_vconf_cb(void *user_data);
+gboolean _is_power_save_survival_mode(void);
+int _sp_timeout_handler(alarm_id_t alarm_id, void *user_param);
void _init_timeout_cb(mobile_ap_type_e type, void *user_data);
-void _start_timeout_cb(mobile_ap_type_e type);
+void _start_timeout_cb(mobile_ap_type_e type, time_t end_time);
void _stop_timeout_cb(mobile_ap_type_e type);
void _deinit_timeout_cb(mobile_ap_type_e type);
-
#endif
--- /dev/null
+/*
+ * mobileap-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MOBILEAP_IPTABLES_H__
+#define __MOBILEAP_IPTABLES_H__
+
+#define IPTABLES "/usr/sbin/iptables"
+#define TABLE_FILTER "filter"
+#define TABLE_NAT "nat"
+#define TABLE_MANGLE "mangle"
+#define CHAIN_FW "FORWARD"
+#define CHAIN_POST "POSTROUTING"
+#define CHAIN_PRE "PREROUTING"
+#define TETH_FILTER_FW "teth_filter_fw"
+#define TETH_NAT_POST "teth_nat_post"
+#define TETH_NAT_PRE "teth_nat_pre"
+#define STATE_RELATED_ESTAB "RELATED,ESTABLISHED"
+#define STATE_INVALID "INVALID"
+#define ACTION_DROP "DROP"
+#define ACTION_RETURN "RETURN"
+
+typedef enum {
+ PKT_REDIRECTION_RULE,
+ FORWARD_RULE_WITH_ACTION,
+ FORWARD_RULE_WITH_ACTION_AND_STATE,
+ DEFAULT_RULE,
+ PORT_FW_RULE,
+ MASQ_RULE,
+ CLAMP_MSS_RULE,
+} iptables_rule_e;
+
+int _iptables_create_chain(const char *table_name, const char *chain_name);
+int _iptables_flush_rules(const char *table_name, const char *chain_name);
+int _iptables_delete_chain(const char *table_name, const char *chain_name);
+int _iptables_add_rule(iptables_rule_e rule_type, const char *table,
+ const char *chain, ...);
+int _iptables_delete_rule(iptables_rule_e rule_type, const char *table,
+ const char *chain, ...);
+int _get_data_usage(const char *src, const char *dest, unsigned long long *tx,
+ unsigned long long *rx);
+#endif
#include <glib.h>
+#define TETHERING_NET_OPEN_RETRY_INTERVAL 2000 /* 2 secs */
+
gboolean _get_network_interface_name(char **if_name);
+gboolean _get_network_gateway_address(char **ip);
gboolean _is_trying_network_operation(void);
gboolean _set_masquerade(void);
gboolean _unset_masquerade(void);
-gboolean _open_network(void);
-gboolean _close_network(void);
+gboolean _add_default_router(void);
+gboolean _del_default_router(void);
+void _add_port_forward_rule(void);
+void _del_port_forward_rule(void);
+int _open_network(void);
+void _close_network(void);
gboolean _init_network(void *user_data);
gboolean _deinit_network(void);
#ifndef __MOBILEAP_NOTIFICATION_H__
#define __MOBILEAP_NOTIFICATION_H__
+#include <appcore-common.h>
#include <notification.h>
-#define MH_NOTI_STR_MAX 50
-#define MH_NOTI_ICON_PATH "/usr/ug/res/images/ug-setting-mobileap-efl/tethering.png"
+#define MH_NOTI_STR_MAX 50
+#define MH_NOTI_PATH_MAX 256
-#define MOBILEAP_LOCALE_COMMON_PKG "ug-setting-mobileap-efl"
-#define MOBILEAP_LOCALE_COMMON_RES "/usr/ug/res/locale"
+#define MH_NOTI_ICON_PATH "/usr/ug/res/images/ug-setting-mobileap-efl"
+#define MH_NOTI_ICON_BT MH_NOTI_ICON_PATH"/noti_tethering_bluetooth.png"
+#define MH_NOTI_ICON_GENERAL MH_NOTI_ICON_PATH"/noti_tethering_general.png"
+#define MH_NOTI_ICON_USB MH_NOTI_ICON_PATH"/noti_tethering_usb.png"
+#define MH_NOTI_ICON_WIFI MH_NOTI_ICON_PATH"/noti_tethering_wifi_num.png"
+#define MH_NOTI_ICON_WIFI_PD MH_NOTI_ICON_PATH"/noti_tethering_wifi_num_%02d.png"
-#define _(str) dgettext(MOBILEAP_LOCALE_COMMON_PKG, str)
+#define MOBILEAP_LOCALE_COMMON_PKG "ug-setting-mobileap-efl"
+#define MOBILEAP_LOCALE_COMMON_RES "/usr/ug/res/locale"
-#define MH_NOTI_STR _("IDS_MOBILEAP_POP_CONNECTED_DEVICES_C_PD")
-#define MH_NOTI_TITLE _("IDS_MOBILEAP_BODY_TETHERING")
-#define MH_NOTI_TIMEOUT_STR _("IDS_MOBILEAP_BODY_TAP_TO_CONFIGURE_TETHERING")
-#define MH_NOTI_TIMEOUT_TITLE "Disable tethering by timeout"
-#define MH_NOTI_BT_VISIBILITY_STR _("IDS_ST_BODY_BLUETOOTH_VISIBILITY_HAS_TIMED_OUT_YOUR_DEVICE_MIGHT_NOT_BE_FOUND")
+#ifdef _
+#undef _
+#endif
+#define _(str) dgettext(MOBILEAP_LOCALE_COMMON_PKG, str)
+#define MH_STR_TETHERING "IDS_MOBILEAP_BODY_TETHERING"
+#define MH_STR_CONNECTED_DEV "IDS_MOBILEAP_POP_CONNECTED_DEVICES_C_PD"
+#define MH_STR_CONNECTION_TIMEOUT "IDS_ST_BODY_CONNECTION_TIMEOUT"
+#define MH_STR_CONFIGURE_TETHERING "IDS_MOBILEAP_BODY_TAP_TO_CONFIGURE_TETHERING"
+#define MH_STR_TETHERING_ACTIVE _("IDS_MOBILEAP_BODY_TETHERING_ACTIVE_ABB")
+#define MH_STR_BT_VISIBILITY _("IDS_ST_BODY_BLUETOOTH_VISIBILITY_HAS_TIMED_OUT_YOUR_DEVICE_MIGHT_NOT_BE_FOUND")
-int _create_timeout_noti(const char *content, const char *title,
- const char *icon_path);
+int _create_timeout_noti(const char *icon_path);
int _delete_timeout_noti(void);
-int _create_connected_noti(const char *content, const char *title,
- const char *icon_path);
-int _update_connected_noti(const char *content);
+int _create_connected_noti(int count, const char *icon_path);
+int _update_connected_noti(int count, const char *icon_path);
int _delete_connected_noti(void);
-int _create_status_noti(const char *content);
+void _create_tethering_active_noti(void);
+void _create_bt_tethering_active_noti(void);
#endif
* limitations under the License.
*/
-#ifndef __MOBILEAP_AGENT_H__
-#define __MOBILEAP_AGENT_H__
+#ifndef __MOBILEAP_SOFTAP_H__
+#define __MOBILEAP_SOFTAP_H__
+#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "mobileap.h"
-#define MH_MID "mh_agent"
-#define DBG(fmt, args...) LOG(LOG_DEBUG, MH_MID, "[%s()][Ln:%d] "fmt, \
- __func__, __LINE__, ##args)
-#define ERR(fmt, args...) LOG(LOG_ERROR, MH_MID, "[%s()][Ln:%d] "fmt, \
- __func__, __LINE__, ##args)
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MOBILEAP_AGENT"
+
+#define DBG(fmt, args...) LOGD(fmt, ##args)
+#define ERR(fmt, args...) LOGE(fmt, ##args)
+#define SDBG(fmt, args...) SECURE_LOGD(fmt, ##args)
+#define SERR(fmt, args...) SECURE_LOGE(fmt, ##args)
#define DRIVER_DELAY 250000 /* micro seconds */
#define IP_SUBNET_MASK "255.255.255.0"
#define WIFI_IF "wlan0"
-#define IP_ADDRESS_WIFI 0xC0A83D02 /* 192.168.61.2 */
+#define IP_ADDRESS_WIFI 0xC0A82B02 /* 192.168.43.2 */
#define SOFTAP_IF "wl0.1"
-#define IP_ADDRESS_SOFTAP 0xC0A83D01 /* 192.168.61.1 */
+#define IP_ADDRESS_SOFTAP 0xC0A82B01 /* 192.168.43.1 */
#define USB_IF "usb0"
#define IP_ADDRESS_USB 0xC0A88103 /* 192.168.129.3 */
#define MAX_BUF_SIZE (256u)
#define DNSMASQ_CONF_LEN 1024
-#define DNSMASQ_CONF "dhcp-range=192.168.61.3,192.168.61.150,255.255.255.0\n" \
+#define DNSMASQ_CONF \
+ "dhcp-range=192.168.43.3,192.168.43.254,255.255.255.0\n" \
"dhcp-range=192.168.130.2,192.168.130.150,255.255.255.0\n" \
"dhcp-range=192.168.131.2,192.168.131.150,255.255.255.0\n" \
"dhcp-range=192.168.132.2,192.168.132.150,255.255.255.0\n" \
"dhcp-range=192.168.137.2,192.168.137.150,255.255.255.0\n" \
"dhcp-range=set:blue,192.168.129.4,192.168.129.150,255.255.255.0\n"\
"enable-dbus\n" \
+ "group=app\n" \
+ "user=app\n" \
"dhcp-option=tag:blue,option:router,192.168.129.3\n"
#define DNSMASQ_CONF_FILE "/tmp/dnsmasq.conf"
"ssid=%s\n" \
"channel=%d\n" \
"ignore_broadcast_ssid=%d\n" \
+ "hw_mode=g\n" \
"max_num_sta=%d\n" \
- "ieee80211n=1\n" \
- "%s\n"
-#define HOSTAPD_DEBUG_FILE "/tmp/hostapd.log"
+ "ieee80211n=1\n"
+#define HOSTAPD_DEBUG_FILE "/var/log/hostapd.log"
#define HOSTAPD_REQ_MAX_LEN 128
#define HOSTAPD_RETRY_MAX 5
#define HOSTAPD_RETRY_DELAY 500000 /* us */
#define HOSTAPD_STA_DISCONN "AP-STA-DISCONNECTED " /* from wpa_ctrl.h */
+#define HOSTAPD_STA_CONN "AP-STA-CONNECTED "
+#define HOSTAPD_STA_DISCONN_LEN 20
+#define HOSTAPD_STA_CONN_LEN 17
#define HOSTAPD_MONITOR_ATTACH "ATTACH"
#define HOSTAPD_MONITOR_DETACH "DETACH"
-/* End of hostapd configuration */
+#define HOSTAPD_DHCP_MAX_INTERVAL 30000 /* 30 seconds */
-#define WLAN_SCRIPT "/usr/bin/wlan.sh"
+/* Samsung VSIE value in beacon / probe response.
+ * Wi-Fi station can identify AP whether it is tethering or AP only using this value.
+ */
+#define HOSTAPD_VENDOR_ELEMENTS_TETH "DD050016328000" /* Samsung tethering device */
+#define HOSTAPD_VENDOR_ELEMENTS_WIFI_AP "DD050016321000" /* Specific application mode AP (e.g. GroupPlay) */
+/* End of hostapd configuration */
#define IP_FORWARD "/proc/sys/net/ipv4/ip_forward"
-#define IPTABLES "/usr/sbin/iptables"
+#define IP_CMD "/usr/sbin/ip"
#define GREP "/bin/grep"
#define AWK "/usr/bin/awk"
#define DATA_USAGE_FILE "/tmp/tethering_data_usage.txt"
-#define MASQUERADE_RULE "-o %s -j MASQUERADE"
+
+#define TETHERING_ROUTING_TABLE 252
+#define SRC_ROUTING_RULE "iif %s lookup %d"
+#define DEFAULT_ROUTER "default via %s dev %s scope global table %d"
+#define INTERFACE_ROUTING "%s/24 table %d dev %s"
#define DNS_ORDER 1
#define TCP_DNS_FORWARD_RULE "-i %s -p tcp --dport 53 -j DNAT --to %s:53"
#define UDP_DNS_FORWARD_RULE "-i %s -p udp --dport 53 -j DNAT --to %s:53"
-#define FORWARD_RULE "-i %s -o %s"
#define MOBILE_AP_STATE_NONE 0
#define MOBILE_AP_STATE_WIFI 1
#define MOBILE_AP_STATE_USB 2
#define MOBILE_AP_STATE_BT 4
-#define MOBILE_AP_STATE_ALL 7
+#define MOBILE_AP_STATE_WIFI_AP 8
+#define MOBILE_AP_STATE_ALL 15
#define DNSMASQ_DBUS_INTERFACE "uk.org.thekelleys.dnsmasq"
#define PROC_NET_DEV "/proc/net/dev"
-#define TETHERING_CONN_TIMEOUT (1200000) /* 20 Mins */
+#define TETHERING_CONN_TIMEOUT (1200) /* 20 Mins */
+#define WIFI_AP_CONN_TIMEOUT (300) /* 5 Mins */
#define CHECK_NET_STATE_RETRY_COUNT 5
#define PSK_ITERATION_COUNT 4096
typedef struct {
- /* The parent class object state. */
- GObject parent;
-
- /* instance member */
- DBusGMethodInvocation *bt_context;
- DBusGMethodInvocation *usb_context;
- guint source_id;
- GSList *bt_device;
-
- int init_count;
int hide_mode;
- int transfer_check_count;
- unsigned long long rx_bytes;
- unsigned long long tx_bytes;
char ssid[MOBILE_AP_WIFI_SSID_MAX_LEN + 1];
+ /* in AP case, hex key will be passed from library, so one extra byte is needed */
char key[MOBILE_AP_WIFI_KEY_MAX_LEN + 1];
char security_type[SECURITY_TYPE_LEN];
+} softap_settings_t;
+
+typedef struct {
+ /* The parent class object state. */
+ GObject parent;
+
+ int init_count;
+
+ softap_settings_t softap_settings;
} TetheringObject;
typedef struct {
int *value;
} vconf_reg_t;
-
typedef enum {
MOBILE_AP_DRV_INTERFACE_NONE,
MOBILE_AP_WEXT,
MOBILE_AP_NL80211,
} mobile_ap_drv_interface_e;
+typedef struct {
+ guint tid;
+ char *mac_addr;
+} sta_timer_t;
+
/* ssid : 32 key : 64 */
-int _mh_core_enable_softap(const char *ssid, const char *security,
- const char *key, int hide_mode);
+int _mh_core_enable_softap(const mobile_ap_type_e type, const char *ssid,
+ const char *security, const char *key, int hide_mode);
int _mh_core_disable_softap(void);
int _mh_core_get_device_info(softap_device_info_t *di);
int _mh_core_execute_dhcp_server(void);
int _mh_core_disable_masquerade(const char *ext_if);
void _mh_core_add_data_to_array(GPtrArray *array, guint type, gchar *dev_name);
int _mh_core_set_ip_address(const char *if_name, const in_addr_t ip);
+void _register_wifi_station_handler(void);
+void _unregister_wifi_station_handler(void);
-gboolean _init_tethering(TetheringObject *obj);
+void _block_device_sleep(void);
+void _unblock_device_sleep(void);
+int _init_tethering(TetheringObject *obj);
gboolean _deinit_tethering(TetheringObject *obj);
gboolean _mobileap_clear_state(int state);
+gboolean _terminate_mobileap_agent(gpointer user_data);
gboolean _mobileap_is_disabled(void);
gboolean _mobileap_is_enabled(int state);
gboolean _mobileap_is_enabled_by_type(mobile_ap_type_e type);
gboolean _mobileap_set_state(int state);
+void _flush_dhcp_ack_timer(void);
+void _destroy_dhcp_ack_timer(char *mac_addr);
#endif
#ifndef __MOBILEAP_USB_H__
#define __MOBILEAP_USB_H__
-#include "mobileap_agent.h"
-
+#include "mobileap_softap.h"
mobile_ap_error_code_e _disable_usb_tethering(TetheringObject *obj);
+gboolean _is_trying_usb_operation(void);
gboolean tethering_enable_usb_tethering(TetheringObject *obj,
DBusGMethodInvocation *context);
gboolean tethering_disable_usb_tethering(TetheringObject *obj,
DBusGMethodInvocation *context);
-gboolean tethering_get_usb_station_info(TetheringObject *obj,
- DBusGMethodInvocation *context);
-gboolean tethering_get_usb_interface_info(TetheringObject *obj,
- DBusGMethodInvocation *context);
#endif /* __MOBILEAP_USB_H__ */
#ifndef __MOBILEAP_WIFI_H__
#define __MOBILEAP_WIFI_H__
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
+#define VCONFKEY_MOBILE_HOTSPOT_SSID "memory/private/mobileap-agent/ssid"
#define SOFTAP_SECURITY_TYPE_OPEN_STR "open"
#define SOFTAP_SECURITY_TYPE_WPA2_PSK_STR "wpa2-psk"
#define SOFTAP_PASSPHRASE_PATH "wifi_tethering.txt"
+#define SOFTAP_PASSPHRASE_GROUP_ID "secure-storage::tethering"
typedef enum {
SOFTAP_SECURITY_TYPE_OPEN,
SOFTAP_SECURITY_TYPE_WPA2_PSK,
} softap_security_type_e;
-void _register_wifi_station_handler(void);
+typedef struct {
+ int hide_mode;
+ char *ssid;
+ char *key;
+ softap_security_type_e security_type;
+} wifi_saved_settings;
+
+int _get_wifi_name_from_lease_info(const char *mac, char **name_buf);
void _add_wifi_device_to_array(softap_device_info_t *di, GPtrArray *array);
+mobile_ap_error_code_e _enable_wifi_tethering(TetheringObject *obj, gchar *ssid,
+ gchar *passphrase, int hide_mode, softap_security_type_e security_type);
mobile_ap_error_code_e _disable_wifi_tethering(TetheringObject *obj);
+gboolean _is_trying_wifi_operation(void);
+mobile_ap_error_code_e _reload_softap_settings(TetheringObject *obj,
+ gchar *ssid, gchar *key, gint hide_mode, gint security_type);
+mobile_ap_error_code_e _reload_softap_settings_for_ap(TetheringObject *obj,
+ gchar *ssid, gchar *key, gint hide_mode, gint security_type);
/* Dbus method */
+mobile_ap_error_code_e _enable_wifi_ap(TetheringObject *obj, gchar *ssid,
+ gchar *passphrase, int hide_mode,
+ softap_security_type_e security_type);
+mobile_ap_error_code_e _disable_wifi_ap(TetheringObject *obj);
gboolean tethering_enable_wifi_tethering(TetheringObject *obj, gchar *ssid,
- gchar *key, gint hide_mode,
+ gchar *key, gint hide_mode, gint security_type,
DBusGMethodInvocation *context);
gboolean tethering_disable_wifi_tethering(TetheringObject *obj,
DBusGMethodInvocation *context);
-gboolean tethering_get_wifi_tethering_hide_mode(TetheringObject *obj,
+gboolean tethering_reload_wifi_settings(TetheringObject *obj, gchar *ssid,
+ gchar *key, gint visibility, gint security_type,
DBusGMethodInvocation *context);
-gboolean tethering_set_wifi_tethering_hide_mode(TetheringObject *obj,
- gint hide_mode, DBusGMethodInvocation *context);
+gboolean tethering_reload_wifi_ap_settings(TetheringObject *obj, gchar *ssid,
+ gchar *key, gint hide_mode,
+ gint security, DBusGMethodInvocation *context);
-gboolean tethering_get_wifi_tethering_ssid(TetheringObject *obj,
+gboolean tethering_enable_wifi_ap(TetheringObject *obj, gchar *ssid,
+ gchar *key, gint hide_mode, gint security_type,
DBusGMethodInvocation *context);
-gboolean tethering_get_wifi_tethering_security_type(TetheringObject *obj,
+gboolean tethering_disable_wifi_ap(TetheringObject *obj,
DBusGMethodInvocation *context);
-
-gboolean tethering_set_wifi_tethering_security_type(TetheringObject *obj,
- gchar *security_type, DBusGMethodInvocation *context);
-
-gboolean tethering_get_wifi_tethering_passphrase(TetheringObject *obj,
- DBusGMethodInvocation *context);
-
-gboolean tethering_set_wifi_tethering_passphrase(TetheringObject *obj,
- gchar *passphrase, guint len, DBusGMethodInvocation *context);
#endif /* __MOBILEAP_WIFI_H__ */
<!-- Method definitions -->
- <method name="init">
- </method>
-
- <method name="deinit">
- </method>
-
<method name="disable">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg type="u" name="type" direction="out"/>
<arg type="s" name="ssid" direction="in"/>
<arg type="s" name="key" direction="in"/>
<arg type="i" name="visibility" direction="in"/>
+ <arg type="i" name="security" direction="in"/>
<arg type="u" name="type" direction="out"/>
<arg type="u" name="result" direction="out"/>
</method>
<arg type="u" name="result" direction="out"/>
</method>
- <method name="get_station_info">
+ <method name="enable_wifi_ap">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg type="s" name="ssid" direction="in"/>
+ <arg type="s" name="key" direction="in"/>
+ <arg type="i" name="visibility" direction="in"/>
+ <arg type="i" name="security" direction="in"/>
<arg type="u" name="type" direction="out"/>
- <arg type="a(usssu)" name="station" direction="out"/>
- </method>
-
- <method name="get_usb_station_info">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="a(sss)" name="usb_station" direction="out"/>
+ <arg type="u" name="result" direction="out"/>
</method>
- <method name="get_data_packet_usage">
+ <method name="disable_wifi_ap">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg type="u" name="type" direction="out"/>
- <arg type="t" name="rx_data" direction="out"/>
- <arg type="t" name="tx_data" direction="out"/>
- </method>
-
- <method name="get_usb_interface_info">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="a(ssss)" name="interface" direction="out"/>
- </method>
-
- <method name="set_ip_forward_status">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="i" name="forward_status" direction="in"/>
- <arg type="i" name="result" direction="out"/>
- </method>
-
- <method name="get_ip_forward_status">
- <arg type="i" name="forward_status" direction="out"/>
- </method>
-
- <method name="get_wifi_tethering_hide_mode">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="i" name="hide_mode" direction="out"/>
- </method>
-
- <method name="set_wifi_tethering_hide_mode">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="i" name="hide_mode" direction="in"/>
- </method>
-
- <method name="get_wifi_tethering_ssid">
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="s" name="ssid" direction="out"/>
+ <arg type="u" name="result" direction="out"/>
</method>
- <method name="get_wifi_tethering_security_type">
+ <method name="reload_wifi_settings">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="s" name="security_type" direction="out"/>
+ <arg type="s" name="ssid" direction="in"/>
+ <arg type="s" name="key" direction="in"/>
+ <arg type="i" name="visibility" direction="in"/>
+ <arg type="i" name="security" direction="in"/>
+ <arg type="u" name="result" direction="out"/>
</method>
- <method name="set_wifi_tethering_security_type">
+ <method name="reload_wifi_ap_settings">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="s" name="security_type" direction="in"/>
+ <arg type="s" name="ssid" direction="in"/>
+ <arg type="s" name="key" direction="in"/>
+ <arg type="i" name="visibility" direction="in"/>
+ <arg type="i" name="security" direction="in"/>
+ <arg type="u" name="result" direction="out"/>
</method>
- <method name="get_wifi_tethering_passphrase">
+ <method name="get_station_info">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="s" name="passphrase" direction="out"/>
- <arg type="u" name="len" direction="out"/>
+ <arg type="u" name="type" direction="out"/>
+ <arg type="a(usssu)" name="station" direction="out"/>
</method>
- <method name="set_wifi_tethering_passphrase">
+ <method name="get_data_packet_usage">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
- <arg type="s" name="passphrase" direction="in"/>
- <arg type="u" name="len" direction="in"/>
+ <arg type="u" name="type" direction="out"/>
+ <arg type="t" name="rx_data" direction="out"/>
+ <arg type="t" name="tx_data" direction="out"/>
</method>
<!-- Signal (D-Bus) definitions -->
<arg type="s" name="arg1" direction="out"/>
</signal>
- <signal name="no_data_timeout">
+ <signal name="wifi_ap_on">
<arg type="s" name="arg1" direction="out"/>
</signal>
- <signal name="low_batt_mode">
+ <signal name="wifi_ap_off">
<arg type="s" name="arg1" direction="out"/>
</signal>
- <signal name="flight_mode">
+ <signal name="no_data_timeout">
<arg type="s" name="arg1" direction="out"/>
</signal>
- <signal name="dhcp_status">
- <arg type="s" name="member" direction="out"/>
- <arg type="s" name="ip" direction="out"/>
- <arg type="s" name="mac" direction="out"/>
- <arg type="s" name="name" direction="out"/>
- <arg type="u" name="time" direction="out"/>
- </signal>
-
- <signal name="security_type_changed">
+ <signal name="low_batt_mode">
<arg type="s" name="arg1" direction="out"/>
</signal>
- <signal name="ssid_visibility_changed">
+ <signal name="flight_mode">
<arg type="s" name="arg1" direction="out"/>
</signal>
-
- <signal name="passphrase_changed">
+ <signal name="power_save_mode">
<arg type="s" name="arg1" direction="out"/>
</signal>
-
</interface>
-</node>
-
+</node>
\ No newline at end of file
<manifest>
- <request>
- <domain name="_"/>
- </request>
+ <define>
+ <domain name="mobileap-agent"/>
+ <request>
+ <smack request="bt-service" type="rw"/>
+ <smack request="bt-service::platform" type="w"/>
+ <smack request="bt-service::public" type="w"/>
+ <smack request="secure-storage::tethering" type="rw"/>
+ <smack request="mdm-server::admin" type="r"/>
+ <smack request="mdm-server::security" type="r"/>
+ <smack request="mdm-server::restriction" type="r"/>
+ <smack request="deviced::display" type="rw"/>
+ <smack request="connman" type="rw"/>
+ <smack request="connman::get" type="rw"/>
+ <smack request="net-config" type="rw"/>
+ <smack request="alarm-server::alarm" type="w"/>
+ <smack request="system::use_internet" type="w"/>
+ <smack request="telephony_framework::api_ps_public" type="rw"/>
+ </request>
+ <permit>
+ <smack permit="system::use_internet" type="w"/>
+ </permit>
+ </define>
+ <request>
+ <domain name="mobileap-agent"/>
+ </request>
+ <assign>
+ <filesystem path="/usr/share/dbus-1/services/org.tizen.tethering.service" label="_"/>
+ <dbus name="org.tizen.tethering" own="mobileap-agent" bus="system">
+ <node name="/Tethering">
+ <interface name="org.tizen.tethering">
+ <annotation name="org.tizen.smack" value="tethering::dbus-access"/>
+ </interface>
+ </node>
+ </dbus>
+ <filesystem path="/opt/etc/dump.d/module.d/tethering_dump.sh" label="_" exec_label="none" />
+ </assign>
</manifest>
+++ /dev/null
-root mobileap-agent rw---
-_default_ mobileap-agent rw---
-mobileap-agent secure-storage::tethering rw---
-mobileap-agent bt-service::admin -w---
-Name: mobileap-agent
-Summary: Mobile AP daemon for setting tethering environments
-Version: 0.1.94
-Release: 1
-Group: TO_BE/FILLED_IN
-License: Apache-2.0
-Source0: %{name}-%{version}.tar.gz
-BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(dbus-glib-1)
-BuildRequires: pkgconfig(glib-2.0)
-BuildRequires: pkgconfig(gthread-2.0)
-BuildRequires: pkgconfig(pmapi)
-BuildRequires: pkgconfig(vconf)
-BuildRequires: pkgconfig(notification)
-BuildRequires: pkgconfig(libssl)
-BuildRequires: pkgconfig(secure-storage)
-BuildRequires: pkgconfig(capi-network-connection)
-BuildRequires: pkgconfig(capi-network-bluetooth)
-BuildRequires: pkgconfig(appcore-common)
-BuildRequires: cmake
-Requires(post): /usr/bin/vconftool
-Requires: iptables
-Requires: dnsmasq
+Name: mobileap-agent
+Summary: Mobile AP daemon for setting tethering environments
+Version: 1.0.12
+Release: 1
+Group: System/Network
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gthread-2.0)
+BuildRequires: pkgconfig(deviced)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(capi-network-connection)
+BuildRequires: pkgconfig(capi-network-bluetooth)
+BuildRequires: pkgconfig(syspopup-caller)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(appcore-common)
+BuildRequires: pkgconfig(capi-network-wifi-direct)
+BuildRequires: pkgconfig(capi-network-wifi)
+BuildRequires: pkgconfig(alarm-service)
+BuildRequires: pkgconfig(appsvc)
+BuildRequires: pkgconfig(libssl)
+BuildRequires: cmake
+Requires(post): /usr/bin/vconftool
+Requires(post): bluetooth-agent
+Requires(post): ss-server
+Requires: iproute2
+Requires: iptables
+Requires: dnsmasq
+
%description
Mobile AP daemon for setting tethering environments
%prep
%setup -q
+
%build
-%cmake .
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
+%cmake -DCMAKE_BUILD_TYPE="" \
+ .
+
make %{?jobs:-j%jobs}
+
%install
%make_install
-mkdir -p %{buildroot}/usr/share/license
-cp LICENSE.APLv2.0 %{buildroot}/usr/share/license/%{name}
-
%post
-/usr/bin/vconftool set -t int memory/mobile_hotspot/connected_device "0" -u 0 -i -f
-/usr/bin/vconftool set -t int memory/mobile_hotspot/mode "0" -u 0 -i -f
-/usr/bin/vconftool set -t int db/mobile_hotspot/security "0" -u 0 -f
-/usr/bin/vconftool set -t int db/mobile_hotspot/hide "0" -u 0 -f
+/usr/bin/vconftool set -t string memory/private/mobileap-agent/ssid "" -u 0 -i -f -s system::vconf_network
+/usr/bin/vconftool set -t int memory/mobile_hotspot/connected_device "0" -u 0 -i -f -s system::vconf_network
+/usr/bin/vconftool set -t int memory/mobile_hotspot/mode "0" -u 0 -i -f -s system::vconf_network
+/usr/bin/vconftool set -t int db/mobile_hotspot/security "1" -u 5000 -f -s system::vconf_network
+/usr/bin/vconftool set -t int db/mobile_hotspot/hide "0" -u 5000 -f -s system::vconf_network
+
+/bin/chmod +x /opt/etc/dump.d/module.d/tethering_dump.sh
%files
%manifest mobileap-agent.manifest
-/opt/etc/smack/accesses.d/mobileap-agent.rule
%defattr(-,root,root,-)
/usr/share/dbus-1/services/org.tizen.tethering.service
%{_bindir}/mobileap-agent
-/usr/share/license/%{name}
-
-%changelog
-* Tue Apr 09 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.86-1
-- Fix the multiple notification issue
-- Support i80211n
-- Channel is changed to 6
-- Implement status notification for bluetooth visibility
-- Change the power manager api
-- Implement connection timer
-- Reference count is used
-- Support Mobile AP
-
-* Sat Feb 16 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.85-2
-- Function return value is checked
-- Private SSID is considered
-- Build option clean-up and g_type_init is deprecated from glib 2.35
-
-* Thu Feb 14 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.84-1
-- User is specified in service file for Dbus auto activation
-
-* Mon Jan 28 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.83-1
-- Remove unrequired log
-
-* Thu Jan 24 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.82-1
-- Indications for Wi-Fi tethering setting change are added
-- DNS Forward and Use of Tethering cellular profile are removed
-- Dbus service / interface / object names are changed
-
-* Mon Jan 14 2013 Seungyoun Ju <sy39.ju@samsung.com> 0.1.81-1
-- dhcp lease delete is handled based on IP Address
-- DNS Forward by netfilter is implemented
-- Vconf key for flight mode is changed
-
-* Fri Dec 07 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.80-1
-- Notification API's usage is changed
-- Duplicated station information issue is fixed
-- Improper notification type is used
-- Timeout(Auto disconnection) feature is implemented
-- Notification for timeout event is implemented
-
-* Thu Nov 08 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.79-1
-- Notification's API usage is changed
-
-* Tue Nov 06 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.78-1
-- Unnecessary BT API is removed
-
-* Sat Nov 03 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.77-1
-- Prevent issues are fixed
-
-* Tue Oct 30 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.76-1
-- Vconf enum is changed (SETTING_USB_MOBILE_HOTSPOT -> SETTING_USB_TETHERING_MODE)
-- Private code is separated
-
-* Mon Oct 29 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.75-1
-- Code clean-up and path for notification icon is changed
-
-* Thu Oct 22 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.74-1
-- License is added
-
-* Thu Oct 11 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.73-1
-- Source package name is changed (libmobileap -> mobileap-agent)
-
-* Thu Oct 11 2012 Injun Yang <injun.yang@samsung.com> 0.1.72-1
-- Launch kcp-agent
-
-* Fri Sep 28 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.71-1
-- Fix memory corruption
-
-* Fri Sep 21 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.70-1
-- Manifest file is added for SMACK
-
-* Wed Sep 19 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.69-1
-- The code for Legacy APIs is removed
-
-* Wed Sep 14 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.68-1
-- Bluetooth PAN Managed APIs are applied
-- MDM Phase 2 implementation
-
-* Wed Sep 06 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.67-1
-- Connection Managed APIs are applied
-- Network status is not checked in agent
-
-* Wed Aug 01 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.66-1
-- Wi-Fi tethering setting values are managed here
-- Deprecated APIs from glib-2.3.0 are replaced
-- Notification Icon is changed
-
-* Fri Jul 13 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.65-1
-- Wi-Fi tethering disable / enable issues are fixed
-
-* Fri Jul 06 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.64-1
-- Unnecessary dependency is removed
-
-* Mon Jun 25 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.63-1
-- Data usage is fixed
-
-* Thu May 31 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.62-1
-- Wi-Fi tethering security is implemented
-- API for getting USB interface information is implemented
-
-* Wed May 23 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.61-1
-- Tethering app. dependency is added
-
-* Tue May 22 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.60-1
-- Wi-Fi interface name is changed from eth0 to wlan0
-
-* Tue May 22 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.59-1
-- Below changes are applied
-- Ignore mdm failure case
-- CAPI bugs are fixed
-- Bug of _remove_station_info_all() is fixed
-- Launch tethering applicatoin from notification
-
-* Tue May 08 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.58-1
-- Hostapd control interface is implemented
-
-* Mon Apr 09 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.57-1
-- Unused vconfkey is removed
-
-* Wed Mar 14 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.56-1
-- Export API's are changed
-
-* Mon Feb 06 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.55-2
-- Fix build error
+/opt/etc/dump.d/module.d/tethering_dump.sh
-* Mon Feb 06 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.1.55-1
-- Test code is modified
-- Code clean-up
-- Notification is implemented
-- MDM bug fix
#include <dbus/dbus-glib-lowlevel.h>
#include <bluetooth.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_common.h"
#include "mobileap_bluetooth.h"
#include "mobileap_handler.h"
{NULL, NULL, IP_ADDRESS_BT_1},
{NULL, NULL, IP_ADDRESS_BT_2},
{NULL, NULL, IP_ADDRESS_BT_3},
- {NULL, NULL, IP_ADDRESS_BT_4},
- {NULL, NULL, IP_ADDRESS_BT_5},
- {NULL, NULL, IP_ADDRESS_BT_6},
- {NULL, NULL, IP_ADDRESS_BT_7}};
+ {NULL, NULL, IP_ADDRESS_BT_4}};
+
+static DBusGMethodInvocation *g_context = NULL;
+
+static void __bt_nap_connection_changed(bool connected, const char *remote_address,
+ const char *interface_name, void *user_data);
+static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data);
+static void __handle_bt_adapter_visibility();
+
+int __recheck_bt_adapter_timer = 0;
static __bt_remote_device_s *__find_bt_remote(const char *mac)
{
}
if (i == MOBILE_AP_MAX_BT_STA) {
- ERR("Not found : %s\n", mac);
+ SERR("Not found : %s\n", mac);
return NULL;
}
return NULL;
}
+ _add_interface_routing(__bt_remote_devices[i].intf_name,
+ __bt_remote_devices[i].intf_ip);
+ _add_routing_rule(__bt_remote_devices[i].intf_name);
__bt_remote_devices[i].info = info;
return &__bt_remote_devices[i];
}
if (i == MOBILE_AP_MAX_BT_STA) {
- ERR("Not found : %s\n", mac);
+ SERR("Not found : %s\n", mac);
return FALSE;
}
+ _del_routing_rule(__bt_remote_devices[i].intf_name);
+ _del_interface_routing(__bt_remote_devices[i].intf_name,
+ __bt_remote_devices[i].intf_ip);
bt_adapter_free_device_info(__bt_remote_devices[i].info);
g_free(__bt_remote_devices[i].intf_name);
}
if (__bt_remote_devices[i].intf_name) {
+ _del_routing_rule(__bt_remote_devices[i].intf_name);
+ _del_interface_routing(__bt_remote_devices[i].intf_name,
+ __bt_remote_devices[i].intf_ip);
g_free(__bt_remote_devices[i].intf_name);
__bt_remote_devices[i].intf_name = NULL;
}
return;
}
+static mobile_ap_error_code_e __init_bt(TetheringObject *obj)
+{
+ int ret;
+
+ ret = bt_initialize();
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_initialize is failed : %d\n", ret);
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_set_state_changed_cb is failed : %d\n", ret);
+ bt_deinitialize();
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+static void __deinit_bt(void)
+{
+ int ret;
+
+ ret = bt_adapter_unset_state_changed_cb();
+ if (ret != BT_ERROR_NONE)
+ ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", ret);
+
+ ret = bt_deinitialize();
+ if (ret != BT_ERROR_NONE)
+ ERR("bt_deinitialize is failed : %d\n", ret);
+
+ return;
+}
+
+static gboolean __is_bt_adapter_on(void)
+{
+ int ret;
+ bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
+
+ ret = bt_adapter_get_state(&adapter_state);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_get_state is failed : %d\n", ret);
+ return FALSE;
+ }
+
+ if (adapter_state == BT_ADAPTER_ENABLED)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+gboolean __bt_adapter_timeout_cb(gpointer data)
+{
+ DBG("+\n");
+
+ static int retry_count = 0;
+ if (__is_bt_adapter_on() == TRUE) {
+ DBG("BT Adapter is enabled by other process \n");
+ retry_count = 0;
+ DBG("-\n");
+ return FALSE;
+ } else {
+ if (++retry_count >= PS_RECHECK_COUNT_MAX) {
+ retry_count = 0;
+ ERR("_enable_bt_tethering() is failed because of bt_adapter_eanbled() failed:n");
+ _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ __deinit_bt();
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_BT_TETHERING_CFM, MOBILE_AP_ERROR_INTERNAL);
+ g_context = NULL;
+ _unblock_device_sleep();
+ DBG("-\n");
+ return FALSE;
+ } else {
+ DBG("-\n");
+ return TRUE;
+ }
+ }
+}
+
+static mobile_ap_error_code_e __turn_on_bt_adapter(TetheringObject *obj)
+{
+ int ret;
+
+ ret = bt_adapter_enable();
+ if (ret == BT_ERROR_NOW_IN_PROGRESS) {
+ if (__recheck_bt_adapter_timer) {
+ g_source_remove(__recheck_bt_adapter_timer);
+ }
+ __recheck_bt_adapter_timer = g_timeout_add(PS_RECHECK_INTERVAL,
+ __bt_adapter_timeout_cb, NULL);
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ if (ret != BT_ERROR_NONE && ret != BT_ERROR_ALREADY_DONE) {
+ ERR("bt_adapter_enable is failed : %d\n", ret);
+ if (ret == BT_ERROR_PERMISSION_DENIED)
+ return MOBILE_AP_ERROR_PERMISSION_DENIED;
+ else
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+static mobile_ap_error_code_e __turn_on_bt_nap(TetheringObject *obj)
+{
+ int bt_ret = BT_ERROR_NONE;
+
+ bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
+ if (bt_ret != BT_ERROR_NONE) {
+ ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ bt_ret = bt_nap_activate();
+ if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
+ bt_nap_unset_connection_state_changed_cb();
+ ERR("bt_nap_activate is failed : %d\n", bt_ret);
+ if (bt_ret == BT_ERROR_PERMISSION_DENIED)
+ return MOBILE_AP_ERROR_PERMISSION_DENIED;
+ else
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+static void __turn_off_bt_nap(void)
+{
+ int bt_ret;
+
+ bt_ret = bt_nap_disconnect_all();
+ if (bt_ret != BT_ERROR_NONE)
+ ERR("bt_nap_disconnect_all is failed : %d\n", bt_ret);
+ else
+ DBG("bt_nap_disconnect_all is called\n");
+
+ bt_ret = bt_nap_unset_connection_state_changed_cb();
+ if (bt_ret != BT_ERROR_NONE)
+ ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
+
+ return;
+}
+
+mobile_ap_error_code_e _enable_bt_tethering(TetheringObject *obj)
+{
+ mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
+
+ DBG("+\n");
+ if (__recheck_bt_adapter_timer) {
+ g_source_remove(__recheck_bt_adapter_timer);
+ __recheck_bt_adapter_timer = 0;
+ }
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ ERR("Wi-Fi AP is enabled\n");
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ ret = _init_tethering(obj);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ return ret;
+ }
+
+ ret = __turn_on_bt_nap(obj);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ _deinit_tethering(obj);
+ return ret;
+ }
+ _delete_timeout_noti();
+ _init_timeout_cb(MOBILE_AP_TYPE_BT, (void *)obj);
+ _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
+
+ return ret;
+}
+
+mobile_ap_error_code_e _disable_bt_tethering(TetheringObject *obj)
+{
+ int ret = BT_ERROR_NONE;
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
+ ERR("BT tethering has not been enabled\n");
+ return MOBILE_AP_ERROR_NOT_ENABLED;
+ }
+ ret = bt_adapter_unset_visibility_mode_changed_cb();
+ if (ret != BT_ERROR_NONE)
+ ERR("bt_adapter_unset_visibility_mode_changed_cb is failed : %d\n", ret);
+
+ _block_device_sleep();
+ if (__is_bt_adapter_on()) {
+ __turn_off_bt_nap();
+ __deinit_bt();
+ }
+
+ _remove_station_info_all(MOBILE_AP_TYPE_BT);
+ __del_bt_remote_all();
+ _deinit_timeout_cb(MOBILE_AP_TYPE_BT);
+
+ _deinit_tethering(obj);
+ _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ _unblock_device_sleep();
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+
static void __bt_nap_connection_changed(bool connected, const char *remote_address, const char *interface_name, void *user_data)
{
if (remote_address == NULL || interface_name == NULL || user_data == NULL) {
int ret;
int n_station = 0;
- DBG("Remote address : %s, Interface : %s, %s\n",
+ SDBG("Remote address : %s, Interface : %s, %s\n",
remote_address, interface_name,
connected ? "Connected" : "Disconnected");
-
if (connected) {
ret = bt_adapter_get_bonded_device_info(remote_address, &info);
if (ret != BT_ERROR_NONE) {
_get_station_count((gconstpointer)MOBILE_AP_TYPE_BT,
_slist_find_station_by_interface, &n_station);
if (n_station == 0)
- _start_timeout_cb(MOBILE_AP_TYPE_BT);
+ _start_timeout_cb(MOBILE_AP_TYPE_BT, time(NULL) + TETHERING_CONN_TIMEOUT);
}
return;
}
-static mobile_ap_error_code_e __activate_bt_nap(TetheringObject *obj)
-{
- int bt_ret = BT_ERROR_NONE;
-
- bt_ret = bt_nap_set_connection_state_changed_cb(__bt_nap_connection_changed, (void *)obj);
- if (bt_ret != BT_ERROR_NONE) {
- ERR("bt_nap_set_connection_state_changed_cb is failed : %d\n", bt_ret);
- return MOBILE_AP_ERROR_RESOURCE;
- }
-
- bt_ret = bt_nap_activate();
- if (bt_ret != BT_ERROR_NONE && bt_ret != BT_ERROR_ALREADY_DONE) {
- bt_nap_unset_connection_state_changed_cb();
- ERR("bt_nap_activate is failed : %d\n", bt_ret);
- return MOBILE_AP_ERROR_RESOURCE;
- }
-
- return MOBILE_AP_ERROR_NONE;
-}
-
-static void __deactivate_bt_nap(void)
-{
- int bt_ret;
-
- bt_ret = bt_nap_deactivate();
- if (bt_ret != BT_ERROR_NONE)
- ERR("bt_nap_deactivate is failed : %d\n", bt_ret);
-
- bt_ret = bt_nap_unset_connection_state_changed_cb();
- if (bt_ret != BT_ERROR_NONE)
- ERR("bt_nap_unset_connection_state_changed_cb is failed : %d\n", bt_ret);
-
- return;
-}
-
static void __bt_adapter_state_changed(int result, bt_adapter_state_e adapter_state, void *user_data)
{
if (user_data == NULL) {
return;
}
+ DBG("+\n");
+
if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT))
return;
- int ret;
- int duration;
- bt_adapter_visibility_mode_e mode;
+ int ret = MOBILE_AP_ERROR_RESOURCE;
TetheringObject *obj = (TetheringObject *)user_data;
- DBusGMethodInvocation *context = obj->bt_context;
- obj->bt_context = NULL;
if (result != BT_ERROR_NONE) {
ERR("BT Adapter operation is failed : %d\n", result);
- if (context) {
- ret = MOBILE_AP_ERROR_RESOURCE;
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
- _mobileap_clear_state(MOBILE_AP_STATE_BT);
- }
- return;
+ goto FAIL;
}
- DBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
+ SDBG("BT Adapter is %s\n", adapter_state == BT_ADAPTER_ENABLED ?
"enabled" : "disabled");
if (adapter_state == BT_ADAPTER_DISABLED) {
_disable_bt_tethering(obj);
SIGNAL_MSG_NOT_AVAIL_INTERFACE);
return;
} else {
- ret = bt_adapter_get_visibility(&mode, &duration);
- if (ret == BT_ERROR_NONE && mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE)
- _create_status_noti(MH_NOTI_BT_VISIBILITY_STR);
- }
+ ret = _enable_bt_tethering(obj);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_enable_bt_tethering() is failed : %d\n", ret);
+ __deinit_bt();
+ goto FAIL;
+ }
- ret = __activate_bt_nap(obj);
- if (ret != MOBILE_AP_ERROR_NONE) {
- bt_adapter_unset_state_changed_cb();
- bt_deinitialize();
- _deinit_tethering(obj);
- dbus_g_method_return(context,
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
+ dbus_g_method_return(g_context,
MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
- _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ __handle_bt_adapter_visibility();
+ g_context = NULL;
+ _unblock_device_sleep();
+
return;
}
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
- if (context)
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+FAIL:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+ g_context = NULL;
+ _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ _unblock_device_sleep();
+
return;
}
return;
}
-mobile_ap_error_code_e _enable_bt_tethering(TetheringObject *obj,
- DBusGMethodInvocation *context)
+static void __bt_adapter_visibility_changed_cb(int result,
+ bt_adapter_visibility_mode_e visibility_mode, void *user_data)
{
- mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- int bt_ret;
- int duration;
- bt_adapter_visibility_mode_e mode;
- bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
+ DBG("+\n");
- if (_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
- ERR("Bluetooth tethering is already enabled\n");
- ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
- return ret;
- }
+ int ret;
+ int duration;
+ bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
- if (obj->bt_context != NULL) {
- ERR("Bluetooth tethering request is progressing\n");
- ret = MOBILE_AP_ERROR_IN_PROGRESS;
- return ret;
+ ret = bt_adapter_get_visibility(&mode, &duration);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
}
- if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
+ if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
+ ERR("_launch_toast_popup() is failed\n");
}
- if (!_init_tethering(obj)) {
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
- }
+ DBG("-\n");
+}
- bt_ret = bt_initialize();
- if (bt_ret != BT_ERROR_NONE) {
- ERR("bt_initialize is failed : %d\n", bt_ret);
- _deinit_tethering(obj);
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
- }
+static void __handle_bt_adapter_visibility()
+{
+ DBG("+\n");
- bt_ret = bt_adapter_set_state_changed_cb(__bt_adapter_state_changed, (void *)obj);
- if (bt_ret != BT_ERROR_NONE) {
- ERR("bt_adapter_set_state_changed_cb is failed : %d\n", bt_ret);
- bt_deinitialize();
- _deinit_tethering(obj);
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
- }
+ int ret;
+ int duration;
+ bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
- bt_ret = bt_adapter_get_state(&adapter_state);
- if (bt_ret != BT_ERROR_NONE) {
- ERR("bt_adapter_get_state is failed : %d\n", bt_ret);
- bt_adapter_unset_state_changed_cb();
- bt_deinitialize();
- _deinit_tethering(obj);
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
+ ret = bt_adapter_get_visibility(&mode, &duration);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
}
- if (adapter_state == BT_ADAPTER_DISABLED) {
- bt_ret = bt_adapter_enable();
- if (bt_ret != BT_ERROR_NONE) {
- ERR("bt_adapter_enable is failed : %d\n", bt_ret);
- bt_adapter_unset_state_changed_cb();
- bt_deinitialize();
- _deinit_tethering(obj);
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
+ if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
+ ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE, 120);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_set_visibility is failed 0x[%X]\n", ret);
}
- obj->bt_context = context;
- return ret;
- } else {
- bt_ret = bt_adapter_get_visibility(&mode, &duration);
- if (bt_ret == BT_ERROR_NONE && mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE)
- _create_status_noti(MH_NOTI_BT_VISIBILITY_STR);
-
- }
-
- ret = __activate_bt_nap(obj);
- if (ret != MOBILE_AP_ERROR_NONE) {
- bt_adapter_unset_state_changed_cb();
- bt_deinitialize();
- _deinit_tethering(obj);
- ret = MOBILE_AP_ERROR_RESOURCE;
- goto FAIL;
}
-
- _delete_timeout_noti();
- _init_timeout_cb(MOBILE_AP_TYPE_BT, (void *)obj);
- _start_timeout_cb(MOBILE_AP_TYPE_BT);
-
- return ret;
-
-FAIL:
- _mobileap_clear_state(MOBILE_AP_STATE_BT);
-
- return ret;
-}
-
-mobile_ap_error_code_e _disable_bt_tethering(TetheringObject *obj)
-{
- int bt_ret;
-
- if (!_mobileap_is_enabled(MOBILE_AP_STATE_BT)) {
- ERR("BT tethering has not been enabled\n");
- return MOBILE_AP_ERROR_NOT_ENABLED;
- }
-
- __deactivate_bt_nap();
-
- bt_ret = bt_adapter_unset_state_changed_cb();
- if (bt_ret != BT_ERROR_NONE)
- ERR("bt_adapter_unset_state_changed_cb is failed : %d\n", bt_ret);
-
- bt_ret = bt_deinitialize();
- if (bt_ret != BT_ERROR_NONE)
- ERR("bt_deinitialize is failed : %d\n", bt_ret);
-
- _remove_station_info_all(MOBILE_AP_TYPE_BT);
- __del_bt_remote_all();
- _deinit_timeout_cb(MOBILE_AP_TYPE_BT);
-
- _deinit_tethering(obj);
- _mobileap_clear_state(MOBILE_AP_STATE_BT);
-
- return MOBILE_AP_ERROR_NONE;
+ bt_adapter_set_visibility_mode_changed_cb(__bt_adapter_visibility_changed_cb, NULL);
+ DBG("-\n");
}
-
gboolean tethering_enable_bt_tethering(TetheringObject *obj,
DBusGMethodInvocation *context)
{
mobile_ap_error_code_e ret;
+ gboolean ret_val = FALSE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
+ if (g_context) {
+ DBG("It is turnning on\n");
+ dbus_g_method_return(context,
+ MOBILE_AP_ENABLE_BT_TETHERING_CFM,
+ MOBILE_AP_ERROR_IN_PROGRESS);
+ return FALSE;
+ }
+
+ g_context = context;
+
+ _block_device_sleep();
- ret = _enable_bt_tethering(obj, context);
+ ret = __init_bt(obj);
+ if (ret != MOBILE_AP_ERROR_NONE)
+ goto DONE;
+
+ if (!_mobileap_set_state(MOBILE_AP_STATE_BT)) {
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ __deinit_bt();
+ goto DONE;
+ }
+
+ if (__is_bt_adapter_on() == FALSE) {
+ DBG("Bluetooth is deactivated\n");
+ if (__turn_on_bt_adapter(obj) != MOBILE_AP_ERROR_NONE) {
+ ERR("__turn_on_bt_adapter is failed\n");
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ __deinit_bt();
+ goto DONE;
+ }
+
+ return TRUE;
+ }
+
+ ret = _enable_bt_tethering(obj);
if (ret != MOBILE_AP_ERROR_NONE) {
ERR("_enable_bt_tethering() is failed : %d\n", ret);
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
- return FALSE;
- } else if (obj->bt_context == NULL) {
+ _mobileap_clear_state(MOBILE_AP_STATE_BT);
+ __deinit_bt();
+ } else {
_emit_mobileap_dbus_signal(obj, E_SIGNAL_BT_TETHER_ON, NULL);
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+ __handle_bt_adapter_visibility();
+ ret_val = TRUE;
}
- return TRUE;
-}
+DONE:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_BT_TETHERING_CFM, ret);
+ g_context = NULL;
+ _unblock_device_sleep();
+
+ return ret_val;
+}
gboolean tethering_disable_bt_tethering(TetheringObject *obj,
DBusGMethodInvocation *context)
dbus_g_method_return(context, MOBILE_AP_DISABLE_BT_TETHERING_CFM, ret);
return TRUE;
}
+
+gboolean _is_trying_bt_operation(void)
+{
+ return (g_context ? TRUE : FALSE);
+}
{
TetheringObjectClass *klass = TETHERING_OBJECT_GET_CLASS(obj);
- DBG("Emitting signal id [%d], with message [%s]\n", num, message);
+ SDBG("Emitting signal id [%d], with message [%s]\n", num, message);
+
+ if (num == E_SIGNAL_WIFI_TETHER_ON ||
+ num == E_SIGNAL_USB_TETHER_ON || num == E_SIGNAL_BT_TETHER_ON) {
+ _create_tethering_active_noti();
+ }
+
g_signal_emit(obj, klass->signals[num], 0, message);
}
return;
}
-
void _update_station_count(int count)
{
static int prev_cnt = 0;
- char str[MH_NOTI_STR_MAX] = {0, };
+ char icon_path[MH_NOTI_PATH_MAX] = {0, };
+ int wifi_count = 0;
+ int bt_count = 0;
+ int usb_count = 0;
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ return;
+ }
if (prev_cnt == count) {
- DBG("No need to update\n");
return;
}
- DBG("Update the number of station : %d\n", count);
if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_CONNECTED_DEVICE,
count) < 0) {
ERR("Error setting up vconf\n");
return;
}
- snprintf(str, MH_NOTI_STR_MAX, MH_NOTI_STR, count);
+ _get_station_count((gconstpointer)MOBILE_AP_TYPE_WIFI, _slist_find_station_by_interface, &wifi_count);
+ _get_station_count((gconstpointer)MOBILE_AP_TYPE_BT, _slist_find_station_by_interface, &bt_count);
+ _get_station_count((gconstpointer)MOBILE_AP_TYPE_USB, _slist_find_station_by_interface, &usb_count);
+
+ if (wifi_count > 0 && bt_count == 0 && usb_count == 0) {
+ g_strlcpy(icon_path, MH_NOTI_ICON_WIFI, sizeof(icon_path));
+ } else if (wifi_count == 0 && bt_count > 0 && usb_count == 0) {
+ g_strlcpy(icon_path, MH_NOTI_ICON_BT, sizeof(icon_path));
+ } else if (wifi_count == 0 && bt_count == 0 && usb_count > 0) {
+ g_strlcpy(icon_path, MH_NOTI_ICON_USB, sizeof(icon_path));
+ } else if (wifi_count == 0 && bt_count == 0 && usb_count == 0) {
+ return;
+ } else {
+ g_strlcpy(icon_path, MH_NOTI_ICON_GENERAL, sizeof(icon_path));
+ }
+
if (prev_cnt == 0) {
- DBG("Create notification\n");
- _create_connected_noti(str, MH_NOTI_TITLE, MH_NOTI_ICON_PATH);
+ _create_connected_noti(count, icon_path);
} else {
- DBG("Update notification\n");
- _update_connected_noti(str);
+ _update_connected_noti(count, icon_path);
}
prev_cnt = count;
if (_get_station_info(info->mac, _slist_find_station_by_mac, &si) ==
MOBILE_AP_ERROR_NONE) {
- DBG("Already exist station : %s\n", info->mac);
- return MOBILE_AP_ERROR_INTERNAL;
+ if (!si) {
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ if (g_strcmp0(si->hostname, info->hostname) == 0 &&
+ g_strcmp0(si->ip, info->ip) == 0) {
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ _remove_station_info(si->mac, _slist_find_station_by_mac);
}
station_list = g_slist_append(station_list, info);
for (l = station_list; l != NULL; l = g_slist_next(l)) {
si = (mobile_ap_station_info_t *)l->data;
- DBG("[%d] interface : %d\n", i, si->interface);
- DBG("[%d] station MAC : %s\n", i, si->mac);
- DBG("[%d] station Hostname : %s\n", i, si->hostname);
- DBG("[%d] station IP : %s\n", i, si->ip);
- DBG("[%d] station connected time : %d\n", i, si->tm);
+ SDBG("[%d] interface : %d\n", i, si->interface);
+ SDBG("[%d] station MAC : %s\n", i, si->mac);
+ SDBG("[%d] station Hostname : %s\n", i, si->hostname);
+ SDBG("[%d] station IP : %s\n", i, si->ip);
+ SDBG("[%d] station connected time : %d\n", i, si->tm);
i++;
}
}
si = (mobile_ap_station_info_t *)l->data;
- DBG("Remove station MAC : %s\n", si->mac);
+ SDBG("Remove station MAC : %s\n", si->mac);
station_list = g_slist_delete_link(station_list, l);
_send_dbus_station_info("DhcpLeaseDeleted", si);
+ g_free(si->hostname);
g_free(si);
count = g_slist_length(station_list);
mobile_ap_station_info_t *si = NULL;
int count;
+ _flush_dhcp_ack_timer();
+
while (l) {
si = (mobile_ap_station_info_t *)l->data;
- DBG("interface : %d\n", si->interface);
if (si->interface != type) {
l = g_slist_next(l);
continue;
}
- DBG("Remove station MAC : %s\n", si->mac);
+ SDBG("Remove station MAC : %s\n", si->mac);
_send_dbus_station_info("DhcpLeaseDeleted", si);
+ g_free(si->hostname);
g_free(si);
temp_l = l;
}
node = l->data;
- DBG("Found station : %s\n", node->mac);
+ SDBG("Found station : %s\n", node->mac);
*si = node;
return MOBILE_AP_ERROR_NONE;
}
*count = _count;
- DBG("Station count : %d\n", *count);
return MOBILE_AP_ERROR_NONE;
}
return MOBILE_AP_ERROR_NONE;
}
-int _add_data_usage_rule(const char *src, const char *dest)
+int _add_interface_routing(const char *interface, const in_addr_t gateway)
{
- if (src == NULL || src[0] == '\0' ||
- dest == NULL || dest[0] == '\0' ||
- g_strcmp0(src, dest) == 0) {
+ if (interface == NULL || interface[0] == '\0') {
ERR("Invalid parameter\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
char cmd[MAX_BUF_SIZE] = {0, };
+ struct in_addr addr;
+ char *interface_gw;
+ in_addr_t subnet;
- snprintf(cmd, sizeof(cmd), "%s -A FORWARD "FORWARD_RULE,
- IPTABLES, src, dest);
- DBG("ADD IPTABLES RULE : %s\n", cmd);
- if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
- return MOBILE_AP_ERROR_INTERNAL;
- }
+ addr.s_addr = htonl(gateway);
+
+ subnet = inet_netof(addr);
+ addr = inet_makeaddr(subnet, 0);
+ interface_gw = inet_ntoa(addr);
- snprintf(cmd, sizeof(cmd), "%s -A FORWARD "FORWARD_RULE,
- IPTABLES, dest, src);
- DBG("ADD IPTABLES RULE : %s\n", cmd);
+ snprintf(cmd, sizeof(cmd), "%s route add "INTERFACE_ROUTING,
+ IP_CMD, interface_gw, TETHERING_ROUTING_TABLE, interface);
if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
+ ERR("cmd failed : %s\n", cmd);
return MOBILE_AP_ERROR_INTERNAL;
}
return MOBILE_AP_ERROR_NONE;
}
-int _del_data_usage_rule(const char *src, const char *dest)
+int _del_interface_routing(const char *interface, const in_addr_t gateway)
{
- if (src == NULL || src[0] == '\0' ||
- dest == NULL || dest[0] == '\0' ||
- g_strcmp0(src, dest) == 0) {
+ if (interface == NULL || interface[0] == '\0') {
ERR("Invalid parameter\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
char cmd[MAX_BUF_SIZE] = {0, };
+ struct in_addr addr;
+ char *interface_gw;
+ in_addr_t subnet;
- snprintf(cmd, sizeof(cmd), "%s -D FORWARD "FORWARD_RULE,
- IPTABLES, src, dest);
- DBG("REMOVE IPTABLES RULE : %s\n", cmd);
- if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
- return MOBILE_AP_ERROR_INTERNAL;
- }
+ addr.s_addr = htonl(gateway);
+
+ subnet = inet_netof(addr);
+ addr = inet_makeaddr(subnet, 0);
+ interface_gw = inet_ntoa(addr);
- snprintf(cmd, sizeof(cmd), "%s -D FORWARD "FORWARD_RULE,
- IPTABLES, dest, src);
- DBG("REMOVE IPTABLES RULE : %s\n", cmd);
+ snprintf(cmd, sizeof(cmd), "%s route del "INTERFACE_ROUTING,
+ IP_CMD, interface_gw, TETHERING_ROUTING_TABLE, interface);
if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
+ ERR("cmd failed : %s\n", cmd);
return MOBILE_AP_ERROR_INTERNAL;
}
return MOBILE_AP_ERROR_NONE;
}
-int _get_data_usage(const char *src, const char *dest,
- unsigned long long *tx, unsigned long long *rx)
+int _add_routing_rule(const char *interface)
{
- if (src == NULL || src[0] == '\0' ||
- dest == NULL || dest[0] == '\0' ||
- tx == NULL || rx == NULL) {
+ if (interface == NULL || interface[0] == '\0') {
ERR("Invalid parameter\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
char cmd[MAX_BUF_SIZE] = {0, };
- char buf[MAX_BUF_SIZE] = {0, };
- FILE *fp = NULL;
- /* Tx : Src. -> Dest. */
- snprintf(cmd, sizeof(cmd),
- "%s -L FORWARD -vx | %s \"%s[ ]*%s\" | %s '{ print $2 }' > %s",
- IPTABLES, GREP, src, dest, AWK, DATA_USAGE_FILE);
- if (system(cmd) < 0) {
- ERR("\"cmd\" is failed\n");
+ snprintf(cmd, sizeof(cmd), "%s rule add "SRC_ROUTING_RULE,
+ IP_CMD, interface, TETHERING_ROUTING_TABLE);
+ if (_execute_command(cmd)) {
+ ERR("cmd failed : %s\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
}
- /* Rx : Dest. -> Src. */
- snprintf(cmd, sizeof(cmd),
- "%s -L FORWARD -vx | %s \"%s[ ]*%s\" | %s '{ print $2 }' >> %s",
- IPTABLES, GREP, dest, src, AWK, DATA_USAGE_FILE);
- if (system(cmd) < 0) {
- ERR("\"cmd\" is failed\n");
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _del_routing_rule(const char *interface)
+{
+ if (interface == NULL || interface[0] == '\0') {
+ ERR("Invalid parameter\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
}
- fp = fopen(DATA_USAGE_FILE, "r");
- if (fp == NULL) {
- ERR("%s open failed\n", DATA_USAGE_FILE);
- ERR("%s\n", strerror(errno));
+ char cmd[MAX_BUF_SIZE] = {0, };
+
+ snprintf(cmd, sizeof(cmd), "%s rule del "SRC_ROUTING_RULE,
+ IP_CMD, interface, TETHERING_ROUTING_TABLE);
+ if (_execute_command(cmd)) {
+ ERR("cmd failed : %s\n", cmd);
return MOBILE_AP_ERROR_INTERNAL;
}
- if (fgets(buf, sizeof(buf), fp) == NULL)
- *tx = 0LL;
- else
- *tx = atoll(buf);
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _flush_ip_address(const char *interface)
+{
+ if (interface == NULL || interface[0] == '\0') {
+ ERR("Invalid parameter\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
- if (fgets(buf, sizeof(buf), fp) == NULL)
- *rx = 0LL;
- else
- *rx = atoll(buf);
+ char cmd[MAX_BUF_SIZE] = {0, };
- fclose(fp);
- unlink(DATA_USAGE_FILE);
+ snprintf(cmd, sizeof(cmd), "%s addr flush dev %s",
+ IP_CMD, interface);
+ if (_execute_command(cmd)) {
+ ERR("cmd failed : %s\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
return MOBILE_AP_ERROR_NONE;
}
pid_t pid = 0;
gchar **args = NULL;
- DBG("cmd : %s\n", cmd);
+ SDBG("CMD : %s\n", cmd);
args = g_strsplit_set(cmd, " ", -1);
if (!args) {
ERR("Should never get here!\n");
return EXIT_FAILURE;
} else {
- DBG("child pid : %d\n", pid);
-
/* Need to add timeout */
waitpid(pid, &status, 0);
g_strfreev(args);
ERR("child return : %d\n", exit_status);
return EXIT_FAILURE;
}
- DBG("child terminated normally\n");
return EXIT_SUCCESS;
} else {
ERR("child is terminated without exit\n");
in_addr_t subnet;
if (inet_aton(ip, &addr) == 0) {
- ERR("Address : %s is invalid\n", ip);
+ SERR("Address : %s is invalid\n", ip);
return MOBILE_AP_ERROR_INVALID_PARAM;
}
subnet = inet_netof(addr);
}
if (subnet == subnet_wifi) {
- *type = MOBILE_AP_TYPE_WIFI;
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ *type = MOBILE_AP_TYPE_WIFI;
+ else
+ *type = MOBILE_AP_TYPE_WIFI_AP;
return MOBILE_AP_ERROR_NONE;
} else if (subnet >= subnet_bt_min && subnet <= subnet_bt_max) {
*type = MOBILE_AP_TYPE_BT;
return MOBILE_AP_ERROR_NONE;
}
- ERR("Tethering type cannot be decided from %s\n", ip);
+ SERR("Tethering type cannot be decided from %s\n", ip);
+
return MOBILE_AP_ERROR_INVALID_PARAM;
}
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include <stdlib.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_common.h"
#include "mobileap_bluetooth.h"
#include "mobileap_wifi.h"
#include "mobileap_usb.h"
#include "mobileap_notification.h"
+#include "mobileap_handler.h"
+#define VCONF_IS_DEVICE_RENAMED_IN_UG "file/private/libug-setting-mobileap-efl/is_device_rename_local"
typedef struct {
- guint src_id;
+ alarm_id_t alarm_id;
+ time_t end_time;
GSourceFunc func;
void *user_data;
} sp_timeout_handler_t;
static gboolean __bt_timeout_cb(gpointer user_data);
static sp_timeout_handler_t sp_timeout_handler[MOBILE_AP_TYPE_MAX] = {
- {0, __wifi_timeout_cb, NULL},
- {0, NULL, NULL},
- {0, __bt_timeout_cb, NULL}};
+ {0, 0, __wifi_timeout_cb, NULL},
+ {0, 0, NULL, NULL},
+ {0, 0, __bt_timeout_cb, NULL},
+ {0, 0, NULL, NULL}};
-
-
-static void __handle_flight_mode_changed_cb(keynode_t *key, void *data)
+static void __handle_network_cellular_state_changed_cb(keynode_t *key, void *data)
{
if (key == NULL) {
ERR("Parameter is NULL\n");
TetheringObject *obj = (TetheringObject *)data;
int vconf_key = 0;
- if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
- DBG("Wi-Fi tethering is not enabled\n");
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_WIFI_AP)) {
return;
}
- if (vconf_keynode_get_type(key) != VCONF_TYPE_BOOL) {
+ if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
ERR("Invalid vconf key type\n");
return;
}
- vconf_key = vconf_keynode_get_bool(key);
- DBG("key = %s, value = %d(bool)\n",
+ vconf_key = vconf_keynode_get_int(key);
+ SDBG("key = %s, value = %d(int)\n",
vconf_keynode_get_name(key), vconf_key);
- if (vconf_key == FALSE)
+ if (vconf_key != VCONFKEY_NETWORK_CELLULAR_FLIGHT_MODE)
return;
- DBG("Flight mode\n");
- _disable_wifi_tethering(obj);
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ _disable_wifi_tethering(obj);
+ else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
+ _disable_wifi_ap(obj);
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_USB))
+ _disable_usb_tethering(obj);
+
_emit_mobileap_dbus_signal(obj, E_SIGNAL_FLIGHT_MODE, NULL);
return;
TetheringObject *obj = (TetheringObject *)data;
char *vconf_key = NULL;
+ softap_settings_t new_settings;
+ softap_security_type_e sec_type;
- if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
- DBG("Wi-Fi hotspot is not enabled\n");
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_WIFI_AP)) {
return;
}
ERR("Invalid vconf key type\n");
return;
}
-
vconf_key = vconf_keynode_get_str(key);
- DBG("key = %s, value = %s(str)\n",
- vconf_keynode_get_name(key), vconf_key);
- if (g_strcmp0(vconf_key, obj->ssid) == 0) {
- DBG("ssid is not changed\n");
- } else {
- DBG("ssid is changed\n");
- _disable_wifi_tethering(obj);
+ if (g_strcmp0(vconf_key, obj->softap_settings.ssid) != 0) {
+ DBG("Device name is changed\n");
+ new_settings = obj->softap_settings;
+ if (!g_strcmp0(new_settings.security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR)) {
+ sec_type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
+ } else {
+ sec_type = SOFTAP_SECURITY_TYPE_OPEN;
+ }
+ g_strlcpy(new_settings.ssid, vconf_key, sizeof(new_settings.ssid));
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
+ _reload_softap_settings(obj, new_settings.ssid, new_settings.key,
+ new_settings.hide_mode, sec_type);
+ } else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ _reload_softap_settings_for_ap(obj, new_settings.ssid, new_settings.key,
+ new_settings.hide_mode, sec_type);
+ }
+ }
+ return;
+}
+
+static void __handle_language_changed_cb(keynode_t *key, void *data)
+{
+ if (key == NULL || data == NULL) {
+ ERR("Parameter is NULL\n");
+ return;
+ }
+
+ char *language = NULL;
+
+ if (vconf_keynode_get_type(key) != VCONF_TYPE_STRING) {
+ ERR("Invalid vconf key type\n");
+ return;
+ }
+
+ language = vconf_get_str(VCONFKEY_LANGSET);
+ if (language) {
+ setenv("LANG", language, 1);
+ setenv("LC_MESSAGES", language, 1);
+ setlocale(LC_ALL, language);
+ free(language);
}
return;
}
+gboolean _is_power_save_survival_mode(void)
+{
+ int ret;
+ int status;
+
+ ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &status);
+ if (ret != 0) {
+ ERR("vconf_get_int is failed : %d\n", ret);
+ return FALSE;
+ }
+
+ DBG(" PS mode status : %d", status);
+ if (status == SETTING_PSMODE_SURVIVAL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
void _register_vconf_cb(void *user_data)
{
if (user_data == NULL) {
}
vconf_reg_t vconf_reg[] = {
- {VCONFKEY_TELEPHONY_FLIGHT_MODE,
- __handle_flight_mode_changed_cb, NULL},
+ {VCONFKEY_NETWORK_CELLULAR_STATE,
+ __handle_network_cellular_state_changed_cb, NULL},
{VCONFKEY_SETAPPL_DEVICE_NAME_STR,
__handle_device_name_changed_cb, NULL},
+ {VCONFKEY_LANGSET,
+ __handle_language_changed_cb, NULL},
{NULL, NULL, NULL}
};
int ret = 0;
while (vconf_reg[i].key != NULL && vconf_reg[i].cb != NULL) {
- DBG("Register [%d] : %s\n", i, vconf_reg[i].key);
ret = vconf_notify_key_changed(vconf_reg[i].key,
vconf_reg[i].cb, user_data);
if (ret != 0) {
}
vconf_reg_t vconf_reg[] = {
- {VCONFKEY_TELEPHONY_FLIGHT_MODE,
- __handle_flight_mode_changed_cb, NULL},
+ {VCONFKEY_NETWORK_CELLULAR_STATE,
+ __handle_network_cellular_state_changed_cb, NULL},
{VCONFKEY_SETAPPL_DEVICE_NAME_STR,
__handle_device_name_changed_cb, NULL},
+ {VCONFKEY_LANGSET,
+ __handle_language_changed_cb, NULL},
{NULL, NULL, NULL}
};
int ret = 0;
while (vconf_reg[i].key != NULL && vconf_reg[i].cb != NULL) {
- DBG("Register [%d] : %s\n", i, vconf_reg[i].key);
ret = vconf_ignore_key_changed(vconf_reg[i].key,
vconf_reg[i].cb);
if (ret != 0) {
_emit_mobileap_dbus_signal(obj,
E_SIGNAL_WIFI_TETHER_OFF, SIGNAL_MSG_TIMEOUT);
- _create_timeout_noti(MH_NOTI_TIMEOUT_STR, MH_NOTI_TIMEOUT_TITLE,
- MH_NOTI_ICON_PATH);
-
DBG("-\n");
return FALSE;
}
_emit_mobileap_dbus_signal(obj,
E_SIGNAL_BT_TETHER_OFF, SIGNAL_MSG_TIMEOUT);
- _create_timeout_noti(MH_NOTI_TIMEOUT_STR, MH_NOTI_TIMEOUT_TITLE,
- MH_NOTI_ICON_PATH);
DBG("-\n");
return FALSE;
}
+static sp_timeout_handler_t *__find_next_timeout(void)
+{
+ sp_timeout_handler_t *next_timeout = &sp_timeout_handler[MOBILE_AP_TYPE_WIFI];
+ mobile_ap_type_e i;
+
+ for (i = MOBILE_AP_TYPE_USB; i < MOBILE_AP_TYPE_MAX; i++) {
+ if (sp_timeout_handler[i].end_time == 0)
+ continue;
+
+ if (sp_timeout_handler[i].end_time < next_timeout->end_time ||
+ next_timeout->end_time == 0)
+ next_timeout = &sp_timeout_handler[i];
+ }
+
+ return next_timeout;
+}
+
+static void __expire_timeout(sp_timeout_handler_t *sp)
+{
+ if (sp->alarm_id > 0) {
+ alarmmgr_remove_alarm(sp->alarm_id);
+ sp->alarm_id = 0;
+ }
+
+ sp->end_time = 0;
+
+ if (sp->func)
+ sp->func(sp->user_data);
+}
+
+static void __reset_timeout(sp_timeout_handler_t *sp)
+{
+ if (sp->alarm_id > 0) {
+ alarmmgr_remove_alarm(sp->alarm_id);
+ sp->alarm_id = 0;
+ }
+
+ sp->end_time = 0;
+}
+
+int _sp_timeout_handler(alarm_id_t alarm_id, void *user_param)
+{
+ DBG("+\n");
+
+ int ret;
+ time_t now;
+ time_t interval;
+ mobile_ap_type_e i;
+ sp_timeout_handler_t *next_timeout;
+
+ now = time(NULL);
+ for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
+ if (sp_timeout_handler[i].end_time == 0)
+ continue;
+
+ if (sp_timeout_handler[i].alarm_id == alarm_id) {
+ sp_timeout_handler[i].alarm_id = 0;
+ __expire_timeout(&sp_timeout_handler[i]);
+ continue;
+ }
+
+ interval = (time_t)difftime(sp_timeout_handler[i].end_time, now);
+ if (interval > 0)
+ continue;
+
+ __expire_timeout(&sp_timeout_handler[i]);
+ }
+
+ next_timeout = __find_next_timeout();
+ if (next_timeout->end_time == 0)
+ return 0;
+
+ interval = (time_t)difftime(next_timeout->end_time, now);
+ ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
+ &next_timeout->alarm_id);
+ if (ret != ALARMMGR_RESULT_SUCCESS) {
+ ERR("alarmmgr_add_alarm is failed. end_time : %d\n",
+ next_timeout->end_time);
+ return 0;
+ }
+
+ DBG("-\n");
+ return 0;
+}
+
void _init_timeout_cb(mobile_ap_type_e type, void *user_data)
{
DBG("+\n");
+
if (sp_timeout_handler[type].func == NULL) {
- DBG("Not supported timeout : type[%d]\n", type);
return;
}
return;
}
- if (sp_timeout_handler[type].src_id > 0) {
- DBG("There is already registered timeout source\n");
- g_source_remove(sp_timeout_handler[type].src_id);
- sp_timeout_handler[type].src_id = 0;
- }
-
+ sp_timeout_handler[type].alarm_id = 0;
+ sp_timeout_handler[type].end_time = 0;
sp_timeout_handler[type].user_data = user_data;
DBG("-\n");
return;
}
-void _start_timeout_cb(mobile_ap_type_e type)
+void _start_timeout_cb(mobile_ap_type_e type, time_t end_time)
{
- DBG("+\n");
+ int ret;
+ time_t interval;
+ mobile_ap_type_e i;
+ sp_timeout_handler_t *next_timeout;
+
if (sp_timeout_handler[type].func == NULL) {
- DBG("Not supported timeout : type[%d]\n", type);
return;
}
- if (sp_timeout_handler[type].src_id > 0) {
- ERR("It is not registered or stopped\n");
+ __reset_timeout(&sp_timeout_handler[type]);
+ sp_timeout_handler[type].end_time = end_time;
+
+ next_timeout = __find_next_timeout();
+ if (next_timeout->alarm_id > 0) {
return;
}
- sp_timeout_handler[type].src_id = g_timeout_add(TETHERING_CONN_TIMEOUT,
- sp_timeout_handler[type].func,
- sp_timeout_handler[type].user_data);
+ for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
+ if (sp_timeout_handler[i].alarm_id == 0)
+ continue;
+
+ __reset_timeout(&sp_timeout_handler[i]);
+ }
+
+ interval = (time_t)difftime(next_timeout->end_time, time(NULL));
+ if (interval <= 0) {
+ __expire_timeout(next_timeout);
+ return;
+ }
+
+ ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
+ &next_timeout->alarm_id);
+ if (ret != ALARMMGR_RESULT_SUCCESS) {
+ ERR("alarmmgr_add_alarm is failed. type : %d, end_time : %d\n",
+ type, end_time);
+ return;
+ }
- DBG("-\n");
return;
}
void _stop_timeout_cb(mobile_ap_type_e type)
{
DBG("+\n");
+
+ int ret;
+ time_t interval;
+ mobile_ap_type_e i;
+ sp_timeout_handler_t *next_timeout;
+
if (sp_timeout_handler[type].func == NULL) {
- DBG("Not supported timeout : type[%d]\n", type);
return;
}
- if (sp_timeout_handler[type].src_id == 0) {
- ERR("It is not started yet\n");
+ if (sp_timeout_handler[type].alarm_id == 0) {
+ sp_timeout_handler[type].end_time = 0;
return;
}
- g_source_remove(sp_timeout_handler[type].src_id);
- sp_timeout_handler[type].src_id = 0;
+ for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
+ if (sp_timeout_handler[i].end_time != sp_timeout_handler[type].end_time ||
+ type == i)
+ continue;
+
+ sp_timeout_handler[i].alarm_id = sp_timeout_handler[type].alarm_id;
+ sp_timeout_handler[type].alarm_id = 0;
+ sp_timeout_handler[type].end_time = 0;
+ return;
+ }
+ __reset_timeout(&sp_timeout_handler[type]);
+
+ next_timeout = __find_next_timeout();
+ if (next_timeout->end_time == 0)
+ return;
+
+ interval = (time_t)difftime(next_timeout->end_time, time(NULL));
+ if (interval <= 0) {
+ __expire_timeout(next_timeout);
+ return;
+ }
+
+ ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
+ &next_timeout->alarm_id);
+ if (ret != ALARMMGR_RESULT_SUCCESS) {
+ ERR("alarmmgr_add_alarm is failed. type : %d, end_time : %d\n",
+ type, next_timeout->end_time);
+ }
DBG("-\n");
return;
void _deinit_timeout_cb(mobile_ap_type_e type) {
DBG("+\n");
+
if (sp_timeout_handler[type].func == NULL) {
- DBG("Not supported timeout : type[%d]\n", type);
return;
}
- if (sp_timeout_handler[type].src_id > 0) {
- g_source_remove(sp_timeout_handler[type].src_id);
- sp_timeout_handler[type].src_id = 0;
+ if (sp_timeout_handler[type].alarm_id > 0) {
+ _stop_timeout_cb(type);
}
sp_timeout_handler[type].user_data = NULL;
+ sp_timeout_handler[type].end_time = 0;
DBG("-\n");
return;
}
-
--- /dev/null
+/*
+ * mobileap-agent
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "mobileap_iptables.h"
+#include "mobileap_softap.h"
+#include "mobileap.h"
+#include "mobileap_common.h"
+
+#define CREATE_CHAIN_STR "-t %s -N %s" /* table_name, chain_name */
+#define REDIRECTION_ADD_RULE_STR "-t %s -A %s -j %s"
+#define REDIRECTION_DEL_RULE_STR "-t %s -D %s -j %s"
+#define FLUSH_CMD_STR "-t %s -F %s"
+#define DELETE_CHAIN_STR "-t %s -X %s"
+#define FORWARD_RULE_WITH_ACTION_STR "-t %s -A %s -i %s -o %s -j %s"
+#define FORWARD_RULE_WITH_ACTION_AND_STATE_STR "-t %s -A %s -i %s -o %s -m state --state %s -j %s"
+#define MASQUERADE_RULE_STR "-t %s -A %s -o %s -j MASQUERADE"
+#define PORT_FORWARD_RULE_STR "-t %s -A %s -i %s -p %s -d %s --dport %d -j DNAT --to %s:%d"
+#define CLAMP_MSS_RULE_STR "-t %s -A %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"
+#define DEFAULT_RULE_STR "-t %s -A %s -j %s"
+
+
+int _iptables_create_chain(const char *table_name, const char *chain_name)
+{
+ char cmd[MAX_BUF_SIZE] = { 0, };
+
+ snprintf(cmd, sizeof(cmd), "%s "CREATE_CHAIN_STR, IPTABLES, table_name,
+ chain_name);
+ SDBG("command [%s]\n", cmd);
+ if (_execute_command(cmd)) {
+ SERR("command [%s] failed\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _iptables_flush_rules(const char *table_name, const char *chain_name)
+{
+ char cmd[MAX_BUF_SIZE] = { 0, };
+
+ snprintf(cmd, sizeof(cmd), "%s "FLUSH_CMD_STR, IPTABLES, table_name,
+ chain_name);
+ SDBG("command [%s]\n", cmd);
+ if (_execute_command(cmd)) {
+ SERR("command [%s] failed\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _iptables_delete_chain(const char *table_name, const char *chain_name)
+{
+ char cmd[MAX_BUF_SIZE] = { 0, };
+
+ snprintf(cmd, sizeof(cmd), "%s "DELETE_CHAIN_STR, IPTABLES, table_name,
+ chain_name);
+ SDBG("command [%s]\n", cmd);
+ if (_execute_command(cmd)) {
+ SERR("command [%s] failed\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _iptables_add_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
+{
+ if (table == NULL || chain == NULL) {
+ ERR("invalid parameters\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ va_list ap;
+ char cmd[MAX_BUF_SIZE] = { 0, };
+
+ va_start(ap, chain);
+ switch (rule_type) {
+ case PKT_REDIRECTION_RULE: {
+ char *dst_chain;
+
+ dst_chain = va_arg(ap, char *);
+ if (dst_chain == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_ADD_RULE_STR, IPTABLES,
+ table, chain, dst_chain);
+ break;
+ }
+
+ case FORWARD_RULE_WITH_ACTION: {
+ char *in_iface = NULL;
+ char *out_iface = NULL;
+ char *action = NULL;
+
+ in_iface = va_arg(ap, char *);
+ out_iface = va_arg(ap, char *);
+ action = va_arg(ap, char *);
+
+ if (in_iface == NULL || out_iface == NULL || action == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_STR, IPTABLES,
+ table, chain, in_iface, out_iface, action);
+ break;
+ }
+
+ case FORWARD_RULE_WITH_ACTION_AND_STATE: {
+ char *in_iface = NULL;
+ char *out_iface = NULL;
+ char *action = NULL;
+ char *state = NULL;
+
+ in_iface = va_arg(ap, char *);
+ out_iface = va_arg(ap, char *);
+ action = va_arg(ap, char *);
+ state = va_arg(ap, char *);
+
+ if (in_iface == NULL || out_iface == NULL || action == NULL ||
+ state == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "FORWARD_RULE_WITH_ACTION_AND_STATE_STR,
+ IPTABLES, table, chain, in_iface, out_iface, state, action);
+
+ break;
+ }
+
+ case PORT_FW_RULE: {
+ char *ip_iface = NULL;
+ char *proto = NULL;
+ char *org_ip = NULL;
+ char *final_ip = NULL;
+ unsigned short org_port = 0;
+ unsigned short final_port = 0;
+
+ ip_iface = va_arg(ap, char *);
+ proto = va_arg(ap, char *);
+ org_ip = va_arg(ap, char *);
+ final_ip = va_arg(ap, char *);
+ org_port = va_arg(ap, int);
+ final_port = va_arg(ap, int);
+
+ if (ip_iface == NULL || proto == NULL || org_ip == NULL ||
+ final_ip == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "PORT_FORWARD_RULE_STR,
+ IPTABLES, table, chain, ip_iface, proto,
+ org_ip, org_port, final_ip, final_port);
+ break;
+ }
+
+ case MASQ_RULE: {
+ char *ext_iface = NULL;
+
+ ext_iface = va_arg(ap, char *);
+
+ if (ext_iface == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "MASQUERADE_RULE_STR, IPTABLES,
+ table, chain, ext_iface);
+ break;
+ }
+
+ case CLAMP_MSS_RULE: {
+ snprintf(cmd, sizeof(cmd), "%s "CLAMP_MSS_RULE_STR, IPTABLES,
+ table, chain);
+ break;
+ }
+
+ case DEFAULT_RULE: {
+ char *action;
+
+ action = va_arg(ap, char *);
+
+ if (action == NULL) {
+ ERR("invalid parameters\n");
+ goto ERROR_EXIT;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s "DEFAULT_RULE_STR, IPTABLES,
+ table, chain, action);
+ break;
+ }
+
+ default:
+ ERR("case not supported\n");
+ goto ERROR_EXIT;
+ }
+
+ if (_execute_command(cmd)) {
+ SERR("command [%s] failed\n", cmd);
+ goto ERROR_EXIT;
+ }
+
+ va_end(ap);
+ return MOBILE_AP_ERROR_NONE;
+
+ERROR_EXIT:
+ va_end(ap);
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+}
+
+int _iptables_delete_rule(iptables_rule_e rule_type, const char *table, const char *chain, ...)
+{
+ va_list ap;
+ char cmd[MAX_BUF_SIZE] = { 0, };
+
+ va_start(ap, chain);
+ switch (rule_type) {
+ case PKT_REDIRECTION_RULE: {
+ char *dst_chain = NULL;
+
+ dst_chain = va_arg(ap, char *);
+ snprintf(cmd, sizeof(cmd), "%s "REDIRECTION_DEL_RULE_STR, IPTABLES,
+ table, chain, dst_chain);
+ break;
+ }
+ default:
+ ERR("case not supported\n");
+ goto ERROR_EXIT;
+ }
+
+ if (_execute_command(cmd)) {
+ SERR("command [%s] failed\n", cmd);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+ va_end(ap);
+ return MOBILE_AP_ERROR_NONE;
+
+ERROR_EXIT:
+ va_end(ap);
+ return MOBILE_AP_ERROR_INTERNAL;
+}
+
+int _get_data_usage(const char *src, const char *dest, unsigned long long *tx,
+ unsigned long long *rx)
+{
+ if (src == NULL || src[0] == '\0' || dest == NULL || dest[0] == '\0' ||
+ tx == NULL || rx == NULL) {
+ ERR("Invalid parameter\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ char cmd[MAX_BUF_SIZE] = {0, };
+ char buf[MAX_BUF_SIZE] = {0, };
+ FILE *fp = NULL;
+
+ /* Tx : Src. -> Dest. */
+ snprintf(cmd, sizeof(cmd),
+ "%s -t %s -L %s -vx | %s -v DROP | %s \"%s[ ]*%s\" | %s '{ print $2 }' > %s",
+ IPTABLES, TABLE_FILTER, TETH_FILTER_FW, GREP, GREP, src, dest, AWK, DATA_USAGE_FILE);
+ if (system(cmd) < 0) {
+ ERR("cmd %s is failed\n", cmd);
+ }
+
+ *tx = 0;
+
+ fp = fopen(DATA_USAGE_FILE, "r");
+ if (fp == NULL) {
+ ERR("%s open failed\n", DATA_USAGE_FILE);
+ ERR("%s\n", strerror(errno));
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ *tx += atoll(buf);
+ }
+
+ fclose(fp);
+ unlink(DATA_USAGE_FILE);
+
+ /* Rx : Dest. -> Src. */
+ snprintf(cmd, sizeof(cmd),
+ "%s -t %s -L %s -vx | %s -v DROP | %s \"%s[ ]*%s\" | %s '{ print $2 }' > %s",
+ IPTABLES, TABLE_FILTER, TETH_FILTER_FW, GREP, GREP, dest, src, AWK, DATA_USAGE_FILE);
+ if (system(cmd) < 0) {
+ ERR("cmd %s is failed\n", cmd);
+ }
+
+ *rx = 0;
+
+ fp = fopen(DATA_USAGE_FILE, "r");
+ if (fp == NULL) {
+ ERR("%s open failed\n", DATA_USAGE_FILE);
+ ERR("%s\n", strerror(errno));
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ *rx += atoll(buf);
+ }
+
+ fclose(fp);
+ unlink(DATA_USAGE_FILE);
+
+ return MOBILE_AP_ERROR_NONE;
+}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <pmapi.h>
+#include <time.h>
+#include <dd-display.h>
#include <vconf.h>
#include <net_connection.h>
#include <appcore-common.h>
+#include <wifi.h>
+#include <alarm.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_handler.h"
#include "mobileap_common.h"
#include "mobileap_bluetooth.h"
#include "mobileap_usb.h"
#include "mobileap_network.h"
#include "mobileap_notification.h"
+#include "mobileap_iptables.h"
GType tethering_object_get_type(void);
#define TETHERING_TYPE_OBJECT (tethering_object_get_type())
int mobileap_state = MOBILE_AP_STATE_NONE;
DBusConnection *tethering_conn = NULL;
-gboolean tethering_init(TetheringObject *obj, GError **error);
-gboolean tethering_deinit(TetheringObject *obj, GError **error);
gboolean tethering_disable(TetheringObject *obj, DBusGMethodInvocation *context);
gboolean tethering_get_station_info(TetheringObject *obj,
DBusGMethodInvocation *context);
gboolean tethering_get_data_packet_usage(TetheringObject *obj,
DBusGMethodInvocation *context);
-gboolean tethering_set_ip_forward_status(TetheringObject *obj,
- gint forward_mode, DBusGMethodInvocation *context);
-gboolean tethering_get_ip_forward_status(TetheringObject *obj, gint *forward_mode);
#include "tethering-server-stub.h"
-int ref_agent = 0;
-
static void tethering_object_init(TetheringObject *obj)
{
DBG("+\n");
g_assert(obj != NULL);
- obj->bt_context = NULL;
- obj->usb_context = NULL;
- obj->bt_device = NULL;
- obj->rx_bytes = 0;
- obj->tx_bytes = 0;
- obj->transfer_check_count = 0;
+ obj->init_count = 0;
+ memset(&obj->softap_settings, 0x00, sizeof(obj->softap_settings));
}
static void tethering_object_finalize(GObject *obj)
SIGNAL_NAME_USB_TETHER_OFF,
SIGNAL_NAME_BT_TETHER_ON,
SIGNAL_NAME_BT_TETHER_OFF,
+ SIGNAL_NAME_WIFI_AP_ON,
+ SIGNAL_NAME_WIFI_AP_OFF,
SIGNAL_NAME_NO_DATA_TIMEOUT,
SIGNAL_NAME_LOW_BATTERY_MODE,
SIGNAL_NAME_FLIGHT_MODE,
+ SIGNAL_NAME_POWER_SAVE_MODE,
SIGNAL_NAME_SECURITY_TYPE_CHANGED,
SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
SIGNAL_NAME_PASSPHRASE_CHANGED
{
int vconf_ret = 0;
- DBG("Before mobileap_state : %d\n", mobileap_state);
mobileap_state |= state;
- DBG("After mobileap_state : %d\n", mobileap_state);
vconf_ret = vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_MODE, mobileap_state);
if (vconf_ret != 0) {
return TRUE;
break;
+ case MOBILE_AP_TYPE_WIFI_AP:
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
+ return TRUE;
+ break;
+
default:
ERR("Unknow type : %d\n", type);
break;
{
int vconf_ret = 0;
- DBG("Before mobileap_state : %d\n", mobileap_state);
mobileap_state &= (~state);
- DBG("After mobileap_state : %d\n", mobileap_state);
vconf_ret = vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_MODE, mobileap_state);
if (vconf_ret != 0) {
return TRUE;
}
-static void __block_device_sleep(void)
+gboolean _terminate_mobileap_agent(gpointer user_data)
+{
+ if (mainloop == NULL) {
+ return FALSE;
+ }
+
+ if (!_mobileap_is_disabled()) {
+ DBG("Tethering is enabled\n");
+ return FALSE;
+ }
+
+ if (_is_trying_network_operation()) {
+ DBG("Network operation is going on\n");
+ return FALSE;
+ }
+
+ if (_is_trying_wifi_operation()) {
+ DBG("Wi-Fi operation is going on\n");
+ return FALSE;
+ }
+
+ if (_is_trying_bt_operation()) {
+ DBG("BT operation is going on\n");
+ return FALSE;
+ }
+
+ if (_is_trying_usb_operation()) {
+ DBG("USB operation is going on\n");
+ return FALSE;
+ }
+
+ DBG("All tethering / AP's are turned off\n");
+ g_main_loop_quit(mainloop);
+ mainloop = NULL;
+
+ return FALSE;
+}
+
+void _block_device_sleep(void)
{
int ret = 0;
- ret = pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+ ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
if (ret < 0)
ERR("PM control [ERROR] result = %d\n", ret);
else
DBG("PM control [SUCCESS]\n");
}
-static void __unblock_device_sleep(void)
+void _unblock_device_sleep(void)
{
int ret = 0;
- ret = pm_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
+ ret = display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
if (ret < 0)
ERR("PM control [ERROR] result = %d\n", ret);
else
DBG("PM control [SUCCESS]\n");
}
-gboolean _init_tethering(TetheringObject *obj)
+int _init_tethering(TetheringObject *obj)
{
+ int ret = MOBILE_AP_ERROR_NONE;
+
DBG("obj->init_count: %d\n", obj->init_count);
if (obj->init_count > 0) {
- DBG("Already env. is initialized for tethering: %d\n",
- obj->init_count);
obj->init_count++;
- return TRUE;
+ return MOBILE_AP_ERROR_NONE;
}
- obj->init_count++;
-
- __block_device_sleep();
-
- DBG("Open network\n");
- _open_network();
-
- DBG("Run DHCP server\n");
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ ret = _open_network();
+ }
_mh_core_execute_dhcp_server();
- return TRUE;
+ obj->init_count++;
+
+ return ret;
}
gboolean _deinit_tethering(TetheringObject *obj)
{
DBG("obj->init_count: %d\n", obj->init_count);
+ guint idle_id;
+
if (obj->init_count > 1) {
- DBG("Already deinitialized\n");
obj->init_count--;
return TRUE;
} else if (obj->init_count <= 0) {
obj->init_count = 0;
- DBG("Terminate DHCP / IPTABLES\n");
_mh_core_terminate_dhcp_server();
- _close_network();
- __unblock_device_sleep();
-
- return TRUE;
-}
-gboolean tethering_init(TetheringObject *obj, GError **error)
-{
- DBG("There are [%d] references\n", ++ref_agent);
-
- return TRUE;
-}
-
-gboolean tethering_deinit(TetheringObject *obj, GError **error)
-{
- if (--ref_agent <= 0 && _mobileap_is_disabled() &&
- !_is_trying_network_operation()) {
- DBG("Terminate mobileap-agent\n");
- g_main_loop_quit(mainloop);
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ _close_network();
}
- DBG("There are [%d] references\n", ref_agent);
+ idle_id = g_idle_add(_terminate_mobileap_agent, NULL);
+ if (idle_id == 0) {
+ ERR("g_idle_add is failed\n");
+ }
return TRUE;
}
unsigned long long rx_bytes = 0;
if (_get_network_interface_name(&if_name) == FALSE) {
- ERR("No network interface\n");
dbus_g_method_return(context, MOBILE_AP_GET_DATA_PACKET_USAGE_CFM,
0ULL, 0ULL);
return FALSE;
return TRUE;
}
-gboolean tethering_set_ip_forward_status(TetheringObject *obj,
- gint forward_mode, DBusGMethodInvocation *context)
-{
- g_assert(obj != NULL);
-
- gboolean ret;
-
- if (forward_mode == 0) {
- ret = _unset_masquerade();
- } else {
- ret = _set_masquerade();
- }
-
- dbus_g_method_return(context, ret);
-
- return TRUE;
-}
-
-gboolean tethering_get_ip_forward_status(TetheringObject *obj, gint *forward_mode)
-{
- g_assert(obj != NULL);
-
- int fd;
- int ret;
- char value[2] = {0, };
-
- fd = open(IP_FORWARD, O_RDONLY);
- if (fd < 0) {
- ERR("open failed\n");
- return FALSE;
- }
-
- ret = read(fd, value, sizeof(value));
- if (ret < 0) {
- ERR("read is failed\n");
- close(fd);
- return FALSE;
- }
- close(fd);
-
- *forward_mode = atoi(value);
-
- return TRUE;
-}
-
-
static DBusHandlerResult __dnsmasq_signal_filter(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
- DBG("DhcpConnected signal : %s %s %s\n", ip_addr, mac, name);
+ SDBG("DhcpConnected signal : %s %s %s\n", ip_addr, mac, name);
+ /*
+ * DHCP ACK received, destroy timeout if exists
+ */
+ _destroy_dhcp_ack_timer(mac);
if (_get_tethering_type_from_ip(ip_addr, &type) != MOBILE_AP_ERROR_NONE)
return DBUS_HANDLER_RESULT_HANDLED;
if (_mobileap_is_enabled_by_type(type) == FALSE) {
- DBG("Tethering[%d] is disabled. Ignore ACK\n", type);
return DBUS_HANDLER_RESULT_HANDLED;
}
info->interface = type;
g_strlcpy(info->ip, ip_addr, sizeof(info->ip));
g_strlcpy(info->mac, mac, sizeof(info->mac));
- if (type == MOBILE_AP_TYPE_WIFI || type == MOBILE_AP_TYPE_USB) {
+ if (type == MOBILE_AP_TYPE_WIFI || type == MOBILE_AP_TYPE_USB ||
+ type == MOBILE_AP_TYPE_WIFI_AP) {
if (name[0] == '\0')
- g_strlcpy(info->hostname,
- MOBILE_AP_NAME_UNKNOWN,
- sizeof(info->hostname));
+ info->hostname = g_strdup(MOBILE_AP_NAME_UNKNOWN);
else
- g_strlcpy(info->hostname, name,
- sizeof(info->hostname));
+ info->hostname = g_strdup(name);
} else if (type == MOBILE_AP_TYPE_BT) {
_bt_get_remote_device_name(obj, mac, &bt_remote_device_name);
if (bt_remote_device_name == NULL)
- g_strlcpy(info->hostname,
- MOBILE_AP_NAME_UNKNOWN,
- sizeof(info->hostname));
- else {
- g_strlcpy(info->hostname, bt_remote_device_name,
- sizeof(info->hostname));
- free(bt_remote_device_name);
- }
+ info->hostname = g_strdup(MOBILE_AP_NAME_UNKNOWN);
+ else
+ info->hostname = bt_remote_device_name;
}
time(&tm);
info->tm = tm;
if (_add_station_info(info) != MOBILE_AP_ERROR_NONE) {
+ g_free(info->hostname);
free(info);
return DBUS_HANDLER_RESULT_HANDLED;
}
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-
- DBG("DhcpLeaseDeleted signal : %s %s %s\n", ip_addr, mac, name);
+ SDBG("DhcpLeaseDeleted signal : %s %s %s\n", ip_addr, mac, name);
_remove_station_info(ip_addr, _slist_find_station_by_ip_addr);
int main(int argc, char **argv)
{
+ const char *rule = "type='signal',interface='"DNSMASQ_DBUS_INTERFACE"'";
+
TetheringObject *tethering_obj = NULL;
- DBusError dbus_error;
- char *rule = "type='signal',interface='"DNSMASQ_DBUS_INTERFACE"'";
DBusGConnection *tethering_bus = NULL;
DBusGProxy *tethering_bus_proxy = NULL;
- guint result = 0;
+ DBusError dbus_error;
GError *error = NULL;
- int mobileap_vconf_key = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
+ guint result = 0;
+ int ret;
+
+ DBG("+\n");
-#if !GLIB_CHECK_VERSION(2,35,0)
+#if !GLIB_CHECK_VERSION(2,36,0)
g_type_init();
#endif
- if (appcore_set_i18n(MOBILEAP_LOCALE_COMMON_PKG, MOBILEAP_LOCALE_COMMON_RES) < 0)
- goto failure;
-
- if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobileap_vconf_key)) {
- ERR("vconf_get_int FAIL\n");
- mobileap_state = MOBILE_AP_STATE_NONE;
- } else {
- ERR("vconf_get_int OK(mobileap_vconf_key value is %d)\n",
- mobileap_vconf_key);
- mobileap_state = mobileap_vconf_key;
- }
-
mainloop = g_main_loop_new(NULL, FALSE);
if (mainloop == NULL) {
ERR("Couldn't create GMainLoop\n");
- goto failure;
+ return 0;
}
+ /* D-Bus init */
tethering_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
if (error != NULL) {
ERR("Couldn't connect to system bus[%s]\n", error->message);
+ g_error_free(error);
goto failure;
}
- tethering_conn = dbus_g_connection_get_connection(tethering_bus);
-
- DBG("Registering the well-known name (%s)\n", TETHERING_SERVICE_NAME);
-
tethering_bus_proxy = dbus_g_proxy_new_for_name(tethering_bus,
- DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+ DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
if (tethering_bus_proxy == NULL) {
ERR("Failed to get a proxy for D-Bus\n");
goto failure;
}
-
- if (!dbus_g_proxy_call(tethering_bus_proxy,
- "RequestName",
- &error,
- G_TYPE_STRING,
- TETHERING_SERVICE_NAME,
- G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &result, G_TYPE_INVALID)) {
- ERR("D-Bus.RequestName RPC failed[%s]\n", error->message);
+ if (!dbus_g_proxy_call(tethering_bus_proxy, "RequestName", &error,
+ G_TYPE_STRING, TETHERING_SERVICE_NAME,
+ G_TYPE_UINT, 0, G_TYPE_INVALID,
+ G_TYPE_UINT, &result, G_TYPE_INVALID)) {
+ ERR("dbus_g_proxy_call is failed\n");
+ if (error) {
+ ERR("D-Bus.RequestName RPC failed[%s]\n",
+ error->message);
+ g_error_free(error);
+ }
goto failure;
}
-
if (result != 1) {
ERR("Failed to get the primary well-known name.\n");
goto failure;
}
-
g_object_unref(tethering_bus_proxy);
tethering_bus_proxy = NULL;
tethering_obj = g_object_new(TETHERING_TYPE_OBJECT, NULL);
if (tethering_obj == NULL) {
- ERR("Failed to create one MobileAP instance.\n");
+ ERR("Failed to create one Tethering instance.\n");
goto failure;
}
-
- /* Registering it on the D-Bus */
dbus_g_connection_register_g_object(tethering_bus,
TETHERING_SERVICE_OBJECT_PATH, G_OBJECT(tethering_obj));
- DBG("Ready to serve requests.\n");
-
- _init_network(NULL);
- _register_wifi_station_handler();
- _register_vconf_cb((void *)tethering_obj);
-
+ tethering_conn = dbus_g_connection_get_connection(tethering_bus);
dbus_error_init(&dbus_error);
dbus_bus_add_match(tethering_conn, rule, &dbus_error);
if (dbus_error_is_set(&dbus_error)) {
dbus_error_free(&dbus_error);
goto failure;
}
-
- DBG("Listening to D-BUS signals from dnsmasq");
dbus_connection_add_filter(tethering_conn, __dnsmasq_signal_filter, tethering_obj, NULL);
+ /* Platform modules */
+ if (appcore_set_i18n(MOBILEAP_LOCALE_COMMON_PKG, MOBILEAP_LOCALE_COMMON_RES) < 0) {
+ ERR("appcore_set_i18n is failed\n");
+ }
+
+ if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobileap_state) < 0) {
+ ERR("vconf_get_int is failed\n");
+ mobileap_state = MOBILE_AP_STATE_NONE;
+ }
+
+ _init_network((void *)tethering_obj);
+ _register_wifi_station_handler();
+ _register_vconf_cb((void *)tethering_obj);
+
+ ret = wifi_initialize();
+ if (ret != WIFI_ERROR_NONE) {
+ ERR("wifi_initialize() is failed : %d\n", ret);
+ }
+
+ ret = alarmmgr_init(APPNAME);
+ if (ret != ALARMMGR_RESULT_SUCCESS) {
+ ERR("alarmmgr_init(%s) is failed : %d\n", APPNAME, ret);
+ } else {
+ ret = alarmmgr_set_cb(_sp_timeout_handler, NULL);
+ if (ret != ALARMMGR_RESULT_SUCCESS) {
+ ERR("alarmmgr_set_cb is failed : %d\n", ret);
+ }
+ }
+
g_main_loop_run(mainloop);
+ alarmmgr_fini();
+
+ ret = wifi_deinitialize();
+ if (ret != WIFI_ERROR_NONE) {
+ ERR("wifi_deinitialize() is failed : %d\n", ret);
+ }
+
_unregister_vconf_cb((void *)tethering_obj);
+ _unregister_wifi_station_handler();
_deinit_network();
- failure:
- ERR("Terminate the mobileap-agent\n");
+ dbus_connection_remove_filter(tethering_conn, __dnsmasq_signal_filter, tethering_obj);
+ dbus_bus_remove_match(tethering_conn, rule, NULL);
- if (tethering_bus)
- dbus_g_connection_unref(tethering_bus);
- if (tethering_bus_proxy)
- g_object_unref(tethering_bus_proxy);
+ g_object_unref(tethering_obj);
+ dbus_g_connection_unref(tethering_bus);
+
+ DBG("-\n");
+ return 0;
+
+ failure:
if (tethering_obj)
g_object_unref(tethering_obj);
+ if (tethering_bus_proxy)
+ g_object_unref(tethering_bus_proxy);
+ if (tethering_bus)
+ dbus_g_connection_unref(tethering_bus);
+ DBG("-\n");
return 0;
}
*/
#include <stdio.h>
+#include <unistd.h>
#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
#include <net_connection.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_common.h"
#include "mobileap_network.h"
+#include "mobileap_wifi.h"
+#include "mobileap_bluetooth.h"
+#include "mobileap_usb.h"
+#include "mobileap_iptables.h"
+
+typedef enum {
+ __NO_SERVICE,
+ __INTERNET,
+ __TETHERING_ONLY
+} tethering_cellular_service_type_e;
+
+typedef struct {
+ connection_profile_h handle;
+ tethering_cellular_service_type_e svc_type;
+} tethering_cellular_profile_s;
+
+#define MH_PORT_FORWARD_CONF_FILEPATH "/tmp/mobileap_agent_port_forward_info"
+#define MH_MAX_PORT_FORWARD_RULE_LEN 64 /* interface(10) protocol(10) ip(15):port(5) ip(15):port(5) */
+#define MH_MAX_NO_OF_PORT_FORWARD_RULE 64
+
+typedef struct {
+ char *input_interface;
+ char *proto;
+ char *org_dest_ip;
+ unsigned short org_dest_port;
+ char *new_dest_ip;
+ unsigned short new_dest_port;
+} port_forward_info_s;
+
+static TetheringObject *obj = NULL;
+static connection_h connection = NULL;
+static tethering_cellular_profile_s c_prof = {NULL, __NO_SERVICE};
+static guint net_timeout_id;
+static connection_profile_h tethered_prof = NULL;
+static GSList *port_forward_info = NULL;
-extern int ref_agent;
-static connection_h connection = NULL;
-static connection_profile_h cprof = NULL;
+static gboolean __try_to_open_tethering_profile(gpointer user_data);
-static void __print_profile(connection_profile_h profile)
+static mobile_ap_error_code_e __get_conn_error(int conn_error)
{
- if (profile == NULL)
- return;
+ mobile_ap_error_code_e err = MOBILE_AP_ERROR_NONE;
+
+ switch (conn_error) {
+ case CONNECTION_ERROR_NONE:
+ err = MOBILE_AP_ERROR_NONE;
+ break;
+
+ case CONNECTION_ERROR_OUT_OF_MEMORY:
+ err = MOBILE_AP_ERROR_RESOURCE;
+ break;
+
+ case CONNECTION_ERROR_INVALID_OPERATION:
+ err = MOBILE_AP_ERROR_INTERNAL;
+ break;
+
+ case CONNECTION_ERROR_INVALID_PARAMETER:
+ err = MOBILE_AP_ERROR_INVALID_PARAM;
+ break;
+
+ case CONNECTION_ERROR_ALREADY_EXISTS:
+ err = MOBILE_AP_ERROR_ALREADY_ENABLED;
+ break;
+
+ case CONNECTION_ERROR_PERMISSION_DENIED:
+ err = MOBILE_AP_ERROR_PERMISSION_DENIED;
+ break;
+
+ case CONNECTION_ERROR_DHCP_FAILED:
+ err = MOBILE_AP_ERROR_DHCP;
+ break;
+
+ case CONNECTION_ERROR_NOW_IN_PROGRESS:
+ err = MOBILE_AP_ERROR_IN_PROGRESS;
+ break;
+
+ default:
+ ERR("Not defined error : %d\n", conn_error);
+ err = MOBILE_AP_ERROR_INTERNAL;
+ break;
+ }
+
+ return err;
+}
+
+static gboolean __is_valid_ipv4_addr(const char *ip)
+{
+ int i;
+ int len;
+ int dot_count = 0;
+ int addr;
+ char tmp_ip[16] = {0, };
+ char *p = tmp_ip;
+
+ if (ip == NULL)
+ return FALSE;
+
+ len = strlen(ip);
+ if (len > 15 /* 255.255.255.255 */ || len < 7 /* 0.0.0.0 */)
+ return FALSE;
+ g_strlcpy(tmp_ip, ip, sizeof(tmp_ip));
+
+ for (i = 0; i <= len; i++) {
+ if (tmp_ip[i] == '.') {
+ if (++dot_count > 3)
+ return FALSE;
+ if (&tmp_ip[i] == p)
+ return FALSE;
+ tmp_ip[i] = '\0';
+ addr = atoi(p);
+ if (addr < 0 || addr > 255)
+ return FALSE;
+ p = &tmp_ip[i + 1];
+ } else if (tmp_ip[i] == '\0') {
+ if (&tmp_ip[i] == p)
+ return FALSE;
+ addr = atoi(p);
+ if (addr < 0 || addr > 255)
+ return FALSE;
+ break;
+ } else if (tmp_ip[i] < '0' || tmp_ip[i] > '9')
+ return FALSE;
+ }
+
+ if (dot_count != 3)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void __clear_port_forward_info(void)
+{
+ GSList *l;
+ GSList *temp_l;
+ port_forward_info_s *pf;
+
+ for (l = port_forward_info; l; ) {
+ pf = (port_forward_info_s *)l->data;
+ if (pf) {
+ g_free(pf->new_dest_ip);
+ g_free(pf->org_dest_ip);
+ g_free(pf->proto);
+ g_free(pf->input_interface);
+ g_free(pf);
+ }
+
+ temp_l = l;
+ l = g_slist_next(l);
+ port_forward_info = g_slist_delete_link(port_forward_info, temp_l);
+ }
+
+ return;
+}
+
+static gboolean __read_port_forward_info(const char *conf_file)
+{
+ if (conf_file == NULL) {
+ ERR("Invalid parameter\n");
+ return FALSE;
+ }
+
+ DBG("+\n");
+
+ FILE *fp;
+ char buf[MH_MAX_PORT_FORWARD_RULE_LEN];
+ port_forward_info_s *pf;
+ int no_of_rule = 0;
- int conn_ret;
- bool roaming;
+ __clear_port_forward_info();
+
+ fp = fopen(conf_file, "r");
+ if (fp == NULL) {
+ ERR("fopen is failed : %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ int i;
+ char *token;
+ char *saveptr1 = NULL;
+ char *saveptr2 = NULL;
+
+ char *input_interface;
+ char *proto;
+ char *dest_ip[2];
+ char *dest_port[2];
+
+ if (no_of_rule++ >= MH_MAX_NO_OF_PORT_FORWARD_RULE) {
+ DBG("There are too many rules\n");
+ break;
+ }
+
+ /* "Input interface" "Protocol" "Original destination IP:Port" "New destination IP:Port" */
+ /* pdp0 udp 10.90.50.38:23 192.168.43.10:23 */
+
+ input_interface = strtok_r(buf, " ", &saveptr1);
+ if (input_interface == NULL) {
+ SERR("Invalid rule : %s\n", buf);
+ continue;
+ }
+
+ proto = strtok_r(NULL, " ", &saveptr1);
+ if (proto == NULL) {
+ SERR("Invalid rule : %s\n", buf);
+ continue;
+ }
+
+ for (i = 0; i < sizeof(dest_ip) / sizeof(char *); i++) {
+ token = strtok_r(NULL, " ", &saveptr1);
+ if (token == NULL) {
+ SERR("Invalid rule : %s\n", buf);
+ break;
+ }
+
+ dest_ip[i] = strtok_r(token, ":", &saveptr2);
+ if (dest_ip[i] == NULL ||
+ !__is_valid_ipv4_addr(dest_ip[i])) {
+ SERR("Invalid rule : %s\n", buf);
+ break;
+ }
+
+ dest_port[i] = strtok_r(NULL, ":", &saveptr2);
+ if (dest_port[i] == NULL) {
+ SERR("Invalid rule : %s\n", buf);
+ break;
+ }
+ }
+
+ if (i < sizeof(dest_ip) / sizeof(char *))
+ continue;
+
+ pf = (port_forward_info_s *)malloc(sizeof(port_forward_info_s));
+ if (pf == NULL)
+ break;
+
+ pf->input_interface = g_strdup(input_interface);
+ pf->proto = g_strdup(proto);
+ pf->org_dest_ip = g_strdup(dest_ip[0]);
+ pf->org_dest_port = (unsigned short)atoi(dest_port[0]);
+ pf->new_dest_ip = g_strdup(dest_ip[1]);
+ pf->new_dest_port = (unsigned short)atoi(dest_port[1]);
+ port_forward_info = g_slist_append(port_forward_info, pf);
+
+ SDBG("Port forward rule #%d : %s %s %s:%d %s:%d\n", no_of_rule,
+ pf->input_interface, pf->proto,
+ pf->org_dest_ip, pf->org_dest_port,
+ pf->new_dest_ip, pf->new_dest_port);
+ }
+
+ fclose(fp);
+
+ return TRUE;
+}
+
+static gboolean __is_valid_port_forward_info(port_forward_info_s *pf)
+{
+ if (pf == NULL)
+ return FALSE;
+
+ if (!pf->input_interface || !pf->proto ||
+ !pf->org_dest_ip || !pf->new_dest_ip)
+ return FALSE;
+
+ if (!strlen(pf->input_interface) || !strlen(pf->proto) ||
+ !strlen(pf->org_dest_ip) || !strlen(pf->new_dest_ip))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void __print_cellular_profile(void)
+{
+ int ret = 0;
char *apn = NULL;
char *home_url = NULL;
- connection_cellular_network_type_e network_type;
+ bool roaming = false;
connection_cellular_service_type_e service_type;
- conn_ret = connection_profile_get_cellular_network_type(profile, &network_type);
- if (conn_ret != CONNECTION_ERROR_NONE)
- ERR("connection API fail : 0x%X\n", conn_ret);
- else
- DBG("Network type : %d\n", network_type);
+ if (c_prof.handle == NULL)
+ return;
- conn_ret = connection_profile_get_cellular_service_type(profile, &service_type);
- if (conn_ret != CONNECTION_ERROR_NONE)
- ERR("connection API fail : 0x%X\n", conn_ret);
+ ret = connection_profile_get_cellular_service_type(c_prof.handle, &service_type);
+ if (ret != CONNECTION_ERROR_NONE)
+ ERR("connection API fail: 0x%X\n", ret);
else
- DBG("Service type : %d\n", service_type);
+ SDBG("Service type: %d\n", service_type);
- conn_ret = connection_profile_get_cellular_apn(profile, &apn);
- if (conn_ret != CONNECTION_ERROR_NONE)
- ERR("connection API fail : 0x%X\n", conn_ret);
+ ret = connection_profile_get_cellular_apn(c_prof.handle, &apn);
+ if (ret != CONNECTION_ERROR_NONE)
+ ERR("connection API fail: 0x%X\n", ret);
else {
- DBG("APN : %s\n", apn);
- free(apn);
+ SDBG("APN: %s\n", apn);
+ g_free(apn);
}
- conn_ret = connection_profile_get_cellular_home_url(profile, &home_url);
- if (conn_ret != CONNECTION_ERROR_NONE)
- ERR("connection API fail : 0x%X\n", conn_ret);
+ ret = connection_profile_get_cellular_home_url(c_prof.handle, &home_url);
+ if (ret != CONNECTION_ERROR_NONE)
+ ERR("connection API fail: 0x%X\n", ret);
else {
- DBG("Home url : %s\n", home_url);
- free(home_url);
+ SDBG("Home url: %s\n", home_url);
+ g_free(home_url);
}
- conn_ret = connection_profile_is_cellular_roaming(profile, &roaming);
- if (conn_ret != CONNECTION_ERROR_NONE)
- ERR("connection API fail : 0x%X\n", conn_ret);
+ ret = connection_profile_is_cellular_roaming(c_prof.handle, &roaming);
+ if (ret != CONNECTION_ERROR_NONE)
+ ERR("connection API fail: 0x%X\n", ret);
else
- DBG("Roaming : %d\n", roaming);
+ SDBG("Roaming: %d\n", roaming);
+}
+
+static void __handle_open_network_error(void)
+{
+ int ret = MOBILE_AP_ERROR_NONE;
+
+ if (_mobileap_is_disabled()) {
+ return;
+ }
+
+ ret = _disable_wifi_tethering(obj);
+ DBG("_disable_wifi_tethering returns %d\n", ret);
+
+ ret = _disable_bt_tethering(obj);
+ DBG("_disable_bt_tethering returns %d\n", ret);
+
+ ret = _disable_usb_tethering(obj);
+ DBG("_disable_usb_tethering returns %d\n", ret);
+
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_NET_CLOSED, NULL);
return;
}
+static gboolean __is_equal_profile(connection_profile_h a, connection_profile_h b)
+{
+ char *a_id = NULL;
+ char *b_id = NULL;
+ int ret;
+
+ ret = connection_profile_get_id(a, &a_id);
+ if (ret != CONNECTION_ERROR_NONE || a_id == NULL) {
+ ERR("connection_profile_get_id is failed [0x%X]\n", ret);
+ return FALSE;
+ }
+
+ ret = connection_profile_get_id(b, &b_id);
+ if (ret != CONNECTION_ERROR_NONE || b_id == NULL) {
+ ERR("connection_profile_get_id is failed [0x%X]\n", ret);
+ g_free(a_id);
+ return FALSE;
+ }
+
+ ret = g_strcmp0(a_id, b_id);
+ g_free(a_id);
+ g_free(b_id);
+
+ return (ret == 0) ? TRUE : FALSE;
+}
+
static gboolean __is_connected_profile(connection_profile_h profile)
{
if (profile == NULL) {
return FALSE;
}
- int conn_ret;
+ int ret;
connection_profile_state_e pstat = CONNECTION_PROFILE_STATE_DISCONNECTED;
- conn_ret = connection_profile_get_state(profile, &pstat);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_profile_get_state is failed: 0x%X\n", conn_ret);
+ ret = connection_profile_get_state(profile, &pstat);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_profile_get_state is failed: 0x%X\n", ret);
return FALSE;
}
if (pstat != CONNECTION_PROFILE_STATE_CONNECTED) {
- DBG("Profile is not connected\n");
return FALSE;
}
return TRUE;
}
+static void __connection_type_changed_cb(connection_type_e type, void *user_data)
+{
+ DBG("Changed connection type is [%s]\n",
+ type == CONNECTION_TYPE_DISCONNECTED ? "DISCONNECTED" :
+ type == CONNECTION_TYPE_WIFI ? "Wi-Fi" :
+ type == CONNECTION_TYPE_CELLULAR ? "Cellular" :
+ type == CONNECTION_TYPE_ETHERNET ? "Ethernet" :
+ "Unknown");
+
+ if (_mobileap_is_disabled()) {
+ DBG("Tethering is disabled\n");
+ return;
+ }
+
+ if (_open_network() != MOBILE_AP_ERROR_NONE) {
+ ERR("_open_network() is failed\n");
+ __handle_open_network_error();
+ }
+
+ return;
+}
+
+void __cellular_state_changed_cb(keynode_t *node, void *user_data)
+{
+ if (node == NULL) {
+ ERR("Invalid parameter\n");
+ return;
+ }
+
+ if (vconf_keynode_get_type(node) != VCONF_TYPE_INT) {
+ ERR("Invalid vconf key type\n");
+ return;
+ }
+
+ int ret;
+ int cellular_state;
+ connection_type_e net_type;
+
+ cellular_state = vconf_keynode_get_int(node);
+ SDBG("key = %s, value = %d(int)\n",
+ vconf_keynode_get_name(node), cellular_state);
-static gboolean __get_connected_profile(connection_profile_h *r_prof, connection_profile_type_e *r_net_type)
+ if (_mobileap_is_disabled())
+ return;
+
+ if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
+ return;
+
+ ret = connection_get_type(connection, &net_type);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_get_type is failed [0x%X]\n", ret);
+ return;
+ }
+
+ if (net_type != CONNECTION_TYPE_DISCONNECTED &&
+ net_type != CONNECTION_TYPE_CELLULAR)
+ return;
+
+ if (tethered_prof)
+ return;
+
+ DBG("VCONFKEY_NETWORK_CELLULAR_ON\n");
+ if (_open_network() != MOBILE_AP_ERROR_NONE) {
+ ERR("_open_network() is failed\n");
+ __handle_open_network_error();
+ }
+
+ return;
+}
+
+static void __profile_state_changed_cb(connection_profile_state_e state, void *user_data)
{
- if (r_prof == NULL || r_net_type == NULL) {
- ERR("Invalid param [%p] [%p]\n", r_prof, r_net_type);
- return FALSE;
+ if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
+ ERR("There is no proper profile\n");
+ return;
}
- int conn_ret;
- connection_profile_h profile = NULL;
- connection_profile_type_e net_type = CONNECTION_PROFILE_TYPE_CELLULAR;
+ DBG("Tethering cellular profile is %s\n",
+ state == CONNECTION_PROFILE_STATE_DISCONNECTED ? "Disconnected" :
+ state == CONNECTION_PROFILE_STATE_ASSOCIATION ? "Associated" :
+ state == CONNECTION_PROFILE_STATE_CONFIGURATION ? "Configured" :
+ state == CONNECTION_PROFILE_STATE_CONNECTED ? "Connected" :
+ "Unknown");
- conn_ret = connection_get_current_profile(connection, &profile);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_get_current_profile is failed : %d\n", conn_ret);
- return FALSE;
+ int ret;
+ int cellular_state;
+
+ connection_profile_refresh(c_prof.handle);
+
+ if (_mobileap_is_disabled())
+ return;
+
+ if (c_prof.svc_type != __TETHERING_ONLY)
+ return;
+
+ if (tethered_prof) {
+ if (!__is_equal_profile(tethered_prof, c_prof.handle))
+ return;
+ connection_profile_refresh(tethered_prof);
+ }
+
+ if (state != CONNECTION_PROFILE_STATE_DISCONNECTED)
+ return;
+
+ DBG("Cellular profile is disconnected\n");
+ _close_network();
+
+ ret = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
+ if (ret < 0) {
+ ERR("vconf_get_int is failed : %d\n", ret);
+ if (vconf_ignore_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
+ __cellular_state_changed_cb) < 0) {
+ ERR("vconf_ignore_key_changed is failed\n");
+ }
+ return;
+ }
+
+ if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
+ return;
+
+ if (_open_network() != MOBILE_AP_ERROR_NONE) {
+ ERR("_open_network() is failed\n");
+ __handle_open_network_error();
}
- conn_ret = connection_profile_get_type(profile, &net_type);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_profile_get_type is failed : 0x%X\n", conn_ret);
+ DBG("-\n");
+ return;
+}
+
+static void __update_tethering_cellular_profile(void)
+{
+ int ret;
+ connection_profile_h profile;
+ tethering_cellular_service_type_e svc_type;
+
+ ret = connection_get_default_cellular_service_profile(connection,
+ CONNECTION_CELLULAR_SERVICE_TYPE_TETHERING, &profile);
+ if (ret == CONNECTION_ERROR_NONE) {
+ svc_type = __TETHERING_ONLY;
+ goto DONE;
+ }
+ DBG("There is no tethering profile\n");
+
+ ret = connection_get_default_cellular_service_profile(connection,
+ CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET, &profile);
+ if (ret == CONNECTION_ERROR_NONE) {
+ svc_type = __INTERNET;
+ goto DONE;
+ }
+ ERR("Getting default connection for internet is failed\n");
+ /* To-Do : Need to consider prepaid internet profile */
+
+ if (c_prof.handle) {
+ connection_profile_unset_state_changed_cb(c_prof.handle);
+ connection_profile_destroy(c_prof.handle);
+ c_prof.handle = NULL;
+ c_prof.svc_type = __NO_SERVICE;
+ }
+ return;
+
+DONE:
+ if (c_prof.handle == NULL ||
+ !__is_equal_profile(c_prof.handle, profile)) {
+ if (c_prof.handle) {
+ DBG("Tethering cellular profile is updated\n");
+ connection_profile_unset_state_changed_cb(c_prof.handle);
+ connection_profile_destroy(c_prof.handle);
+ }
+
+ c_prof.handle = profile;
+ c_prof.svc_type = svc_type;
+ connection_profile_set_state_changed_cb(c_prof.handle,
+ __profile_state_changed_cb, NULL);
+ } else {
connection_profile_destroy(profile);
- return FALSE;
+ connection_profile_refresh(c_prof.handle);
}
- *r_prof = profile;
- *r_net_type = net_type;
- return TRUE;
+ return;
}
-static gboolean __get_network_profile(connection_profile_h *r_prof)
+static void __profile_closed_cb(connection_error_e result, void *user_data)
{
- if (r_prof == NULL) {
- ERR("r_prof is NULL\n");
+ connection_profile_refresh(c_prof.handle);
+
+ if (result != CONNECTION_ERROR_NONE) {
+ ERR("Unable to close profile [0x%X]", result);
+ } else {
+ DBG("Tethering profile is closed");
+ }
+
+ return;
+}
+
+static gboolean __close_tethering_profile(void)
+{
+ if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
+ ERR("There is no proper cellular profile\n");
return FALSE;
}
- connection_profile_h profile;
- connection_profile_type_e net_type = CONNECTION_PROFILE_TYPE_CELLULAR;
+ int ret;
+ connection_profile_state_e state;
+
+ DBG("+\n");
+
+ if (net_timeout_id) {
+ g_source_remove(net_timeout_id);
+ net_timeout_id = 0;
+ }
+
+ if (c_prof.svc_type == __INTERNET) {
+ __profile_closed_cb(CONNECTION_ERROR_NONE, NULL);
+ return TRUE;
+ }
- if (__get_connected_profile(&profile, &net_type) == FALSE) {
- ERR("There is no available network\n");
+ ret = connection_profile_get_state(c_prof.handle, &state);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_profile_get_state is failed [0x%X]\n", ret);
return FALSE;
}
- DBG("Current connected net_type : %d\n", net_type);
- if (net_type == CONNECTION_PROFILE_TYPE_WIFI) {
- *r_prof = profile;
+ if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
+ DBG("Already disconnected profile\n");
return TRUE;
}
- if (net_type != CONNECTION_PROFILE_TYPE_CELLULAR) {
- ERR("Network type [%d] is not supported\n", net_type);
+ ret = connection_close_profile(connection, c_prof.handle,
+ __profile_closed_cb, NULL);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("Connection close Failed!!\n");
return FALSE;
}
- __print_profile(profile);
- *r_prof = profile;
+ DBG("-\n");
return TRUE;
}
-static void __connection_type_changed_cb(connection_type_e type, void *user_data)
+static void __profile_opened_cb(connection_error_e result, void *user_data)
{
- DBG("Changed connection type is %s\n",
- type == CONNECTION_TYPE_DISCONNECTED ? "DISCONNECTED" :
- type == CONNECTION_TYPE_WIFI ? "Wi-Fi" :
- type == CONNECTION_TYPE_CELLULAR ? "Cellular" :
- type == CONNECTION_TYPE_ETHERNET ? "Ethernet" :
- "Unknown");
+ if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
+ ERR("There is no proper profile\n");
+ return;
+ }
+ int ret;
+ connection_type_e net_type;
+
+ DBG("+\n");
+
+ connection_profile_refresh(c_prof.handle);
if (_mobileap_is_disabled()) {
- DBG("Tethering is not enabled\n");
+ __close_tethering_profile();
return;
}
- if (_unset_masquerade() == FALSE) {
- ERR("_unset_masquerade is failed\n");
+ if (result == CONNECTION_ERROR_OPERATION_ABORTED) {
+ DBG("connection_open_profile is cancelled\n");
+ return;
}
- if (cprof) {
- connection_profile_destroy(cprof);
- cprof = NULL;
+ /* Check opened and retry context */
+ ret = connection_get_type(connection, &net_type);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_get_type is failed\n");
+ __close_tethering_profile();
+ return;
}
- if (type == CONNECTION_TYPE_DISCONNECTED) {
+ if (net_type != CONNECTION_TYPE_DISCONNECTED &&
+ net_type != CONNECTION_TYPE_CELLULAR) {
+ DBG("Connection type is changed\n");
+ __close_tethering_profile();
return;
}
- _open_network();
+ if (tethered_prof) {
+ connection_profile_refresh(tethered_prof);
+ return;
+ }
+ /* End of check */
+
+ if (result != CONNECTION_ERROR_ALREADY_EXISTS &&
+ result != CONNECTION_ERROR_NONE) {
+ DBG("Retry to open profile [0x%X]\n", result);
+ if (net_timeout_id) {
+ g_source_remove(net_timeout_id);
+ net_timeout_id = 0;
+ }
+ net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
+ __try_to_open_tethering_profile,
+ NULL);
+ return;
+ }
+
+ DBG("Tethering profile is opened");
+
+ __print_cellular_profile();
+
+ connection_profile_clone(&tethered_prof, c_prof.handle);
+ _set_masquerade();
+ _add_default_router();
+ _add_port_forward_rule();
+
+ DBG("-\n");
return;
}
+static gboolean __open_tethering_profile(void)
+{
+ if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
+ ERR("There is no proper cellular profile\n");
+ return FALSE;
+ }
+
+ int ret;
+
+ DBG("+\n");
+
+ if (c_prof.svc_type == __INTERNET) {
+ return TRUE;
+ }
+
+ if (__is_connected_profile(c_prof.handle)) {
+ DBG("Already connected profile\n");
+ return TRUE;
+ }
+
+ ret = connection_open_profile(connection, c_prof.handle,
+ __profile_opened_cb, NULL);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("Unable to open profile [0x%X]", ret);
+ return FALSE;
+ }
+
+ DBG("-\n");
+ return TRUE;
+}
+
+static gboolean __try_to_open_tethering_profile(gpointer user_data)
+{
+ DBG("+\n");
+
+ if (_mobileap_is_disabled()) {
+ DBG("Tethering is disabled\n");
+ net_timeout_id = 0;
+ return FALSE;
+ }
+
+ if (__open_tethering_profile() == FALSE)
+ return TRUE;
+
+ net_timeout_id = 0;
+ return FALSE;
+}
+
gboolean _is_trying_network_operation(void)
{
+ if (net_timeout_id)
+ return TRUE;
return FALSE;
}
return FALSE;
}
- if (cprof == NULL) {
- ERR("There is no connected profile\n");
+ if (tethered_prof == NULL) {
return FALSE;
}
- int conn_ret = 0;
+ int ret = 0;
- conn_ret = connection_profile_get_network_interface_name(cprof, if_name);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_profile_get_network_interface_name is failed : 0x%X\n", conn_ret);
+ connection_profile_refresh(tethered_prof);
+
+ ret = connection_profile_get_network_interface_name(tethered_prof, if_name);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_profile_get_network_interface_name is failed : 0x%X\n", ret);
+ return FALSE;
+ }
+
+ if (strlen(*if_name) == 0) {
+ ERR("if_name is zero length\n");
+ free(*if_name);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean _get_network_gateway_address(char **ip)
+{
+ if (ip == NULL) {
+ ERR("ip is NULL\n");
+ return FALSE;
+ }
+
+ if (tethered_prof == NULL) {
+ return FALSE;
+ }
+
+ int ret = 0;
+
+ connection_profile_refresh(tethered_prof);
+
+ ret = connection_profile_get_gateway_address(tethered_prof,
+ CONNECTION_ADDRESS_FAMILY_IPV4, ip);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_profile_get_ip_address is failed : 0x%X\n", ret);
return FALSE;
}
ERR("_get_network_interface_name is failed\n");
return FALSE;
}
- DBG("Network interface : %s\n", if_name);
+ SDBG("Network interface : %s\n", if_name);
_mh_core_enable_masquerade(if_name);
free(if_name);
gboolean _unset_masquerade(void)
{
- if (cprof == NULL) {
+ if (tethered_prof == NULL) {
DBG("There is nothing to unset masquerading\n");
return TRUE;
}
ERR("_get_network_interface_name is failed\n");
return FALSE;
}
- DBG("Network interface : %s\n", if_name);
+ SDBG("Network interface : %s\n", if_name);
_mh_core_disable_masquerade(if_name);
free(if_name);
return TRUE;
}
-gboolean _open_network(void)
+gboolean _add_default_router(void)
{
- connection_profile_h profile = NULL;
+ if (tethered_prof == NULL) {
+ DBG("There is no network\n");
+ return TRUE;
+ }
- DBG("+\n");
+ char cmd[MAX_BUF_SIZE] = {0, };
+ char *ip = NULL;
+ char *interface = NULL;
- if (__get_network_profile(&profile) == FALSE) {
- ERR("__get_network_profile is failed\n");
+ if (_get_network_gateway_address(&ip) == FALSE) {
return FALSE;
}
- if (!__is_connected_profile(profile)) {
- connection_profile_destroy(profile);
+ if (_get_network_interface_name(&interface) == FALSE) {
+ free(ip);
+ return FALSE;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s route replace "DEFAULT_ROUTER,
+ IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
+ free(interface);
+ free(ip);
+
+ if (_execute_command(cmd)) {
+ ERR("%s is failed\n", cmd);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean _del_default_router(void)
+{
+ if (tethered_prof == NULL) {
+ DBG("There is no network\n");
return TRUE;
}
- cprof = profile;
- if (_set_masquerade() == FALSE) {
- ERR("_set_masquerade is failed\n");
- _close_network();
+ char cmd[MAX_BUF_SIZE] = {0, };
+ char *ip = NULL;
+ char *interface = NULL;
+
+ if (_get_network_gateway_address(&ip) == FALSE) {
return FALSE;
}
- DBG("-\n");
+ if (_get_network_interface_name(&interface) == FALSE) {
+ free(ip);
+ return FALSE;
+ }
+
+ snprintf(cmd, sizeof(cmd), "%s route del "DEFAULT_ROUTER,
+ IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
+ free(interface);
+ free(ip);
+
+ if (_execute_command(cmd)) {
+ ERR("%s is failed\n", cmd);
+ return FALSE;
+ }
return TRUE;
}
-gboolean _close_network(void)
+void _add_port_forward_rule(void)
+{
+ DBG("+\n");
+
+ GSList *l;
+ port_forward_info_s *pf;
+
+ if (access(MH_PORT_FORWARD_CONF_FILEPATH, F_OK) < 0) {
+ return;
+ }
+
+ if (__read_port_forward_info(MH_PORT_FORWARD_CONF_FILEPATH) == FALSE) {
+ ERR("__read_port_forward_info() is failed\n");
+ return;
+ }
+
+ _iptables_create_chain(TABLE_NAT, TETH_NAT_PRE);
+ _iptables_add_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
+ TETH_NAT_PRE);
+
+ for (l = port_forward_info; l; l = g_slist_next(l)) {
+ pf = (port_forward_info_s *)l->data;
+
+ if (__is_valid_port_forward_info(pf) == FALSE)
+ continue;
+
+ _iptables_add_rule(PORT_FW_RULE, TABLE_NAT, TETH_NAT_PRE,
+ pf->input_interface, pf->proto, pf->org_dest_ip,
+ pf->new_dest_ip, (int)pf->org_dest_port, (int)pf->new_dest_port);
+ }
+
+ return;
+}
+
+void _del_port_forward_rule(void)
{
- gboolean ret;
+ GSList *l;
+ GSList *temp_l;
+ port_forward_info_s *pf;
DBG("+\n");
- ret = _unset_masquerade();
- if (ret == FALSE)
- ERR("_unset_masquerade is failed\n");
+ if (port_forward_info == NULL) {
+ DBG("port forwarding rules were not applied, no need to deleted\n");
+ return;
+ }
+
+ for(l = port_forward_info; l;) {
+ pf = (port_forward_info_s *)l->data;
+ if (pf) {
+ g_free(pf->new_dest_ip);
+ g_free(pf->org_dest_ip);
+ g_free(pf->proto);
+ g_free(pf->input_interface);
+ g_free(pf);
+ }
+
+ temp_l = l;
+ l = g_slist_next(l);
+ port_forward_info = g_slist_delete_link(port_forward_info,
+ temp_l);
+ }
+
+ _iptables_delete_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
+ TETH_NAT_PRE);
+ _iptables_flush_rules(TABLE_NAT, TETH_NAT_PRE);
+ _iptables_delete_chain(TABLE_NAT, TETH_NAT_PRE);
- connection_profile_destroy(cprof);
- cprof = NULL;
+ return;
+}
+
+int _open_network(void)
+{
+ DBG("+\n");
+
+ int ret;
+ int con_ret;
+ int cellular_state;
+ connection_type_e net_type;
+
+ ret = connection_get_type(connection, &net_type);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_get_type is failed\n");
+ con_ret = __get_conn_error(ret);
+ return con_ret;
+ }
+
+ if (vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state) < 0) {
+ ERR("vconf_get_int is failed\n");
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ DBG("Connection type : %d, Cellular State : %d\n",
+ net_type, cellular_state);
+
+ if (tethered_prof) {
+ if (net_type == CONNECTION_TYPE_CELLULAR) {
+ __update_tethering_cellular_profile();
+ if (__is_equal_profile(tethered_prof, c_prof.handle)) {
+ DBG("Cellular profile is already configured\n");
+ return MOBILE_AP_ERROR_NONE;
+ }
+ }
+
+ DBG("There is already tethered profile\n");
+ _close_network();
+ }
+
+ if (net_type == CONNECTION_TYPE_DISCONNECTED &&
+ cellular_state != VCONFKEY_NETWORK_CELLULAR_ON) {
+ DBG("There is no network\n");
+ /* Callback will handle this once Network type is changed */
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ switch (net_type) {
+ case CONNECTION_TYPE_DISCONNECTED:
+ case CONNECTION_TYPE_CELLULAR:
+ __update_tethering_cellular_profile();
+ if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
+ DBG("There is no proper cellular profile for tethering\n");
+ return MOBILE_AP_ERROR_NONE;
+ }
+ __print_cellular_profile();
+
+ if (!__is_connected_profile(c_prof.handle)) {
+ if (c_prof.svc_type != __TETHERING_ONLY) {
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ if (net_timeout_id) {
+ g_source_remove(net_timeout_id);
+ net_timeout_id = 0;
+ }
+ net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
+ __try_to_open_tethering_profile, NULL);
+
+ return MOBILE_AP_ERROR_NONE;
+ }
+ connection_profile_clone(&tethered_prof, c_prof.handle);
+ break;
+
+ case CONNECTION_TYPE_WIFI:
+ case CONNECTION_TYPE_ETHERNET:
+ case CONNECTION_TYPE_BT:
+ ret = connection_get_current_profile(connection, &tethered_prof);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_get_current_profile is failed [0x%X]\n", ret);
+ con_ret = __get_conn_error(ret);
+ return con_ret;
+ }
+ break;
+
+ default:
+ ERR("Unknown connection type : %d\n", net_type);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ _set_masquerade();
+ _add_default_router();
+ _add_port_forward_rule();
DBG("-\n");
- return TRUE;
+ return MOBILE_AP_ERROR_NONE;
}
-gboolean _init_network(void *user_data)
+void _close_network(void)
{
- int conn_ret;
+ if (tethered_prof == NULL) {
+ DBG("There is no tethered profile\n");
+ return;
+ }
- conn_ret = connection_create(&connection);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_create is failed : 0x%X\n", conn_ret);
+ DBG("+\n");
+
+ _del_port_forward_rule();
+ _del_default_router();
+ _unset_masquerade();
+
+ connection_profile_destroy(tethered_prof);
+ tethered_prof = NULL;
+ __close_tethering_profile();
+
+ DBG("-\n");
+ return;
+}
+
+gboolean _init_network(void *user_data)
+{
+ if (user_data == NULL) {
+ ERR("Invalid parameter\n");
return FALSE;
}
- conn_ret = connection_set_type_changed_cb(connection,
+ int ret;
+
+ obj = (TetheringObject *)user_data;
+
+ ret = connection_create(&connection);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_create is failed : 0x%X\n", ret);
+ goto FAIL;
+ }
+
+ ret = connection_set_type_changed_cb(connection,
__connection_type_changed_cb, user_data);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_set_type_changed cb is failed : 0x%X\n", conn_ret);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_set_type_changed cb is failed : 0x%X\n", ret);
+ goto FAIL;
+ }
+
+ ret = vconf_notify_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
+ __cellular_state_changed_cb, NULL);
+ if (ret < 0) {
+ ERR("vconf_notify_key_changed is failed : %d\n", ret);
+ connection_unset_type_changed_cb(connection);
+ goto FAIL;
+ }
+
+ __update_tethering_cellular_profile();
+
+ return TRUE;
+
+FAIL:
+ if (connection) {
connection_destroy(connection);
connection = NULL;
- return FALSE;
}
- return TRUE;
+ return FALSE;
}
gboolean _deinit_network(void)
{
- int conn_ret;
+ int ret;
if (connection == NULL) {
ERR("Connection handle is not initialized\n");
return TRUE;
}
- conn_ret = connection_unset_type_changed_cb(connection);
- if (conn_ret != CONNECTION_ERROR_NONE) {
- ERR("connection_unset_type_changed_cb is failed : %d\n", conn_ret);
+ if (c_prof.handle) {
+ vconf_ignore_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
+ __cellular_state_changed_cb);
+ connection_profile_unset_state_changed_cb(c_prof.handle);
+ connection_profile_destroy(c_prof.handle);
+ c_prof.handle = NULL;
+ c_prof.svc_type = __NO_SERVICE;
+ }
+
+ ret = connection_unset_type_changed_cb(connection);
+ if (ret != CONNECTION_ERROR_NONE) {
+ ERR("connection_unset_type_changed_cb is failed : %d\n", ret);
}
connection_destroy(connection);
connection = NULL;
+ obj = NULL;
return TRUE;
}
#include <stdio.h>
#include <string.h>
#include <notification.h>
+#include <bluetooth.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
+#include "mobileap_notification.h"
+
+#define MH_NOTI_LAUNCH_PKGNAME "setting-mobileap-efl"
+#define MH_NOTI_CALLER_PKGNAME "mobileap-agent"
+#define MH_LOCALE_DOMAIN "ug-setting-mobileap-efl"
+#define MH_LOCALE_DIR "/usr/ug/res/locale"
-//#define __ENABLE_UG_LAUNCH
-#define MH_NOTI_APP_NAME "setting-mobileap-efl"
-#define MH_AGENT_PKG_NAME "mobileap-agent"
static int connected_noti_id = 0;
static int timeout_noti_id = 0;
-int _create_timeout_noti(const char *content, const char *title,
- const char *icon_path)
+static int __create_status_noti(const char *content)
+{
+ if (content == NULL)
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+
+ notification_error_e ret;
+
+ ret = notification_status_message_post(content);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("notification_status_message_post() is failed : %d\n", ret);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ return MOBILE_AP_ERROR_NONE;
+}
+
+int _create_timeout_noti(const char *icon_path)
{
DBG("+\n");
+
notification_h noti = NULL;
notification_error_e ret = NOTIFICATION_ERROR_NONE;
+ char *old_icon_path = NULL;
+ char *general_icon_path = NULL;
if (timeout_noti_id) {
- noti = notification_load(APPNAME, timeout_noti_id);
+ noti = notification_load(MH_NOTI_CALLER_PKGNAME, timeout_noti_id);
if (noti == NULL) {
DBG("Notification can be deleted already\n");
} else {
+ ret = notification_get_image(noti,
+ NOTIFICATION_IMAGE_TYPE_ICON, &old_icon_path);
+ if (ret == NOTIFICATION_ERROR_NONE) {
+ if (g_strcmp0(icon_path, old_icon_path))
+ general_icon_path = MH_NOTI_ICON_GENERAL;
+ }
+
ret = notification_delete(noti);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_delete [%d]\n", ret);
ret = notification_free(noti);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_free [%d]\n", ret);
- return MOBILE_AP_ERROR_INTERNAL;
}
}
+
timeout_noti_id = 0;
}
return MOBILE_AP_ERROR_INTERNAL;
}
+ ret = notification_set_pkgname(noti, MH_NOTI_CALLER_PKGNAME);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Fail to notification_set_pkgname [%d]\n", ret);
+ goto FAIL;
+ }
+
ret = notification_set_property(noti,
-#ifdef __ENABLE_UG_LAUNCH
NOTIFICATION_PROP_VOLATILE_DISPLAY);
-#else
- NOTIFICATION_PROP_VOLATILE_DISPLAY |
- NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
-#endif
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_property [%d]\n", ret);
goto FAIL;
ret = notification_set_layout(noti, NOTIFICATION_LY_NOTI_EVENT_SINGLE);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Fail to notification_set_image [%d]\n", ret);
+ ERR("Fail to notification_set_layout [%d]\n", ret);
goto FAIL;
}
ret = notification_set_image(noti,
- NOTIFICATION_IMAGE_TYPE_ICON, icon_path);
+ NOTIFICATION_IMAGE_TYPE_ICON, general_icon_path ?
+ general_icon_path : icon_path);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_image [%d]\n", ret);
goto FAIL;
}
ret = notification_set_text(noti,
- NOTIFICATION_TEXT_TYPE_TITLE,
- title,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ NOTIFICATION_TEXT_TYPE_TITLE, NULL,
+ MH_STR_CONNECTION_TIMEOUT,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_text [%d]\n", ret);
goto FAIL;
}
ret = notification_set_text(noti,
- NOTIFICATION_TEXT_TYPE_CONTENT,
- content,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ NOTIFICATION_TEXT_TYPE_CONTENT, NULL,
+ MH_STR_CONFIGURE_TETHERING,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_text [%d]\n", ret);
goto FAIL;
}
- ret = notification_set_pkgname(noti, APPNAME);
+ ret = notification_set_text_domain(noti, MH_LOCALE_DOMAIN, MH_LOCALE_DIR);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Fail to notification_set_pkgname [%d]\n", ret);
+ ERR("Fail to notification_set_text_domain [%d]\n", ret);
goto FAIL;
}
-#ifdef __ENABLE_UG_LAUNCH
- ret = notification_set_application(noti, MH_NOTI_APP_NAME);
+
+ ret = notification_set_application(noti, MH_NOTI_LAUNCH_PKGNAME);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_application [%d]\n", ret);
goto FAIL;
}
-#endif
+
ret = notification_insert(noti, &timeout_noti_id);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_insert [%d]\n", ret);
{
notification_error_e ret = NOTIFICATION_ERROR_NONE;
notification_list_h noti_list = NULL;
+ notification_list_h l = NULL;
notification_h noti = NULL;
+ notification_ly_type_e layout;
+
+ DBG("+\n");
- ret = notification_get_detail_list(MH_AGENT_PKG_NAME,
- NOTIFICATION_GROUP_ID_NONE,
- NOTIFICATION_PRIV_ID_NONE,
- -1,
- ¬i_list);
+ ret = notification_get_detail_list(MH_NOTI_CALLER_PKGNAME,
+ NOTIFICATION_GROUP_ID_NONE,
+ NOTIFICATION_PRIV_ID_NONE,
+ -1,
+ ¬i_list);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_get_detail_list\n");
return MOBILE_AP_ERROR_INTERNAL;
}
- if (noti_list) {
- noti = notification_list_get_data(noti_list);
- if (noti)
- notification_delete(noti);
+ if (noti_list == NULL) {
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ for (l = noti_list; l; l = notification_list_get_next(l)) {
+ noti = notification_list_get_data(l);
+ if (noti == NULL)
+ break;
- notification_free_list(noti_list);
+ ret = notification_get_layout(noti, &layout);
+ if (ret == NOTIFICATION_ERROR_NONE &&
+ layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE) {
+ DBG("Found timeout noti\n");
+ notification_delete(noti);
+ }
}
+ notification_free_list(noti_list);
+
+ DBG("-\n");
+
return MOBILE_AP_ERROR_NONE;
}
-int _create_connected_noti(const char *content, const char *title,
- const char *icon_path)
+int _create_connected_noti(int count, const char *icon_path)
{
DBG("+\n");
notification_h noti = NULL;
return MOBILE_AP_ERROR_INTERNAL;
}
+ ret = notification_set_pkgname(noti, MH_NOTI_CALLER_PKGNAME);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Fail to notification_set_pkgname [%d]\n", ret);
+ goto FAIL;
+ }
+
ret = notification_set_property(noti,
NOTIFICATION_PROP_DISABLE_AUTO_DELETE |
-#ifdef __ENABLE_UG_LAUNCH
NOTIFICATION_PROP_VOLATILE_DISPLAY);
-#else
- NOTIFICATION_PROP_VOLATILE_DISPLAY |
- NOTIFICATION_PROP_DISABLE_APP_LAUNCH);
-#endif
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_property [%d]\n", ret);
goto FAIL;
}
ret = notification_set_text(noti,
- NOTIFICATION_TEXT_TYPE_TITLE,
- title,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ NOTIFICATION_TEXT_TYPE_TITLE, NULL,
+ MH_STR_TETHERING,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_text [%d]\n", ret);
goto FAIL;
}
ret = notification_set_text(noti,
- NOTIFICATION_TEXT_TYPE_CONTENT,
- content,
- NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ NOTIFICATION_TEXT_TYPE_CONTENT, NULL,
+ MH_STR_CONNECTED_DEV,
+ NOTIFICATION_VARIABLE_TYPE_INT, count,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_text [%d]\n", ret);
goto FAIL;
}
- ret = notification_set_pkgname(noti, APPNAME);
+ ret = notification_set_text_domain(noti, MH_LOCALE_DOMAIN, MH_LOCALE_DIR);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Fail to notification_set_pkgname [%d]\n", ret);
+ ERR("Fail to notification_set_text_domain [%d]\n", ret);
goto FAIL;
}
-#ifdef __ENABLE_UG_LAUNCH
- ret = notification_set_application(noti, MH_NOTI_APP_NAME);
+
+ ret = notification_set_application(noti, MH_NOTI_LAUNCH_PKGNAME);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_set_application [%d]\n", ret);
goto FAIL;
}
-#endif
+
+ ret = notification_set_display_applist(noti,
+ NOTIFICATION_DISPLAY_APP_ALL ^ NOTIFICATION_DISPLAY_APP_INDICATOR);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Fail to notification_set_display_applist [%d]\n", ret);
+ goto FAIL;
+ }
+
ret = notification_insert(noti, &connected_noti_id);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_insert [%d]\n", ret);
return MOBILE_AP_ERROR_INTERNAL;
}
-int _update_connected_noti(const char *content)
+int _update_connected_noti(int count, const char *icon_path)
{
DBG("+\n");
- if (content == NULL) {
- ERR("Invalid param\n");
- return MOBILE_AP_ERROR_INVALID_PARAM;
- }
-
notification_h noti = NULL;
notification_error_e ret = NOTIFICATION_ERROR_NONE;
- noti = notification_load(APPNAME, connected_noti_id);
+ noti = notification_load(MH_NOTI_CALLER_PKGNAME, connected_noti_id);
if (noti == NULL) {
ERR("notification_load is failed\n");
return MOBILE_AP_ERROR_INTERNAL;
}
- ret = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT,
- content, NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ ret = notification_set_image(noti,
+ NOTIFICATION_IMAGE_TYPE_ICON, icon_path);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Fail to notification_set_text [%d]\n", ret);
+ ERR("Fail to notification_set_image [%d]\n", ret);
+ goto FAIL;
+ }
- ret = notification_free(noti);
- if (ret != NOTIFICATION_ERROR_NONE)
- ERR("Fail to notification_free [%d]\n", ret);
- return MOBILE_AP_ERROR_INTERNAL;
+ ret = notification_set_text(noti,
+ NOTIFICATION_TEXT_TYPE_CONTENT, NULL,
+ MH_STR_CONNECTED_DEV,
+ NOTIFICATION_VARIABLE_TYPE_INT, count,
+ NOTIFICATION_VARIABLE_TYPE_NONE);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Fail to notification_set_text [%d]\n", ret);
+ goto FAIL;
}
ret = notification_update(noti);
if (ret != NOTIFICATION_ERROR_NONE) {
ERR("Fail to notification_update [%d]\n", ret);
-
- ret = notification_free(noti);
- if (ret != NOTIFICATION_ERROR_NONE)
- ERR("Fail to notification_free [%d]\n", ret);
- return MOBILE_AP_ERROR_INTERNAL;
+ goto FAIL;
}
ret = notification_free(noti);
DBG("-\n");
return MOBILE_AP_ERROR_NONE;
+
+FAIL:
+ ret = notification_free(noti);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Fail to notification_free [%d]\n", ret);
+ }
+
+ return MOBILE_AP_ERROR_INTERNAL;
}
int _delete_connected_noti(void)
notification_h noti = NULL;
notification_error_e ret;
- noti = notification_load(APPNAME, connected_noti_id);
+ noti = notification_load(MH_NOTI_CALLER_PKGNAME, connected_noti_id);
if (noti == NULL) {
ERR("notification_load is failed\n");
connected_noti_id = 0;
return MOBILE_AP_ERROR_NONE;
}
-int _create_status_noti(const char *content)
+void _create_tethering_active_noti(void)
{
- if (content == NULL)
- return MOBILE_AP_ERROR_INVALID_PARAM;
+ int active_count = 0;
- notification_error_e ret;
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ active_count++;
- ret = notification_status_message_post(content);
- if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("notification_status_message_post() is failed : %d\n", ret);
- return MOBILE_AP_ERROR_INTERNAL;
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_BT))
+ active_count++;
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_USB))
+ active_count++;
+
+ if (active_count == 1)
+ __create_status_noti(_("IDS_MOBILEAP_BODY_TETHERING_ACTIVE_ABB"));
+
+ return;
+}
+
+void _create_bt_tethering_active_noti(void)
+{
+ int ret;
+ bt_adapter_visibility_mode_e mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
+ int duration;
+ int str_len;
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *str = NULL;
+
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI) &&
+ !_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
+ str1 = MH_STR_TETHERING_ACTIVE;
+ __create_status_noti(str1);
}
- return MOBILE_AP_ERROR_NONE;
+ ret = bt_adapter_get_visibility(&mode, &duration);
+ if (ret != BT_ERROR_NONE) {
+ ERR("bt_adapter_get_visibility is failed 0x[%X]\n", ret);
+ }
+
+ if (mode == BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE) {
+ str2 = MH_STR_BT_VISIBILITY;
+ __create_status_noti(str2);
+ }
+
+ return;
}
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
+#include <ctype.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/wireless.h>
-
#include <openssl/evp.h>
#include <openssl/sha.h>
#include "mobileap_common.h"
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_handler.h"
+#include "mobileap_wifi.h"
+#include "mobileap_iptables.h"
+
+#define NETCONFIG_SERVICE "net.netconfig"
+#define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi"
+#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi"
+
+#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
static pid_t dnsmasq_pid = 0;
static pid_t hostapd_pid = 0;
static int hostapd_monitor_fd = 0;
static GIOChannel *hostapd_io_channel = NULL;
static guint hostapd_io_source = 0;
+GSList *sta_timer_list = NULL;
+
+static gboolean __hostapd_connect_timer_cb(gpointer user_data);
+
+static char *__find_first_caps_char(char *str)
+{
+ if (str == NULL) {
+ ERR("NULL string passes\n");
+ return NULL;
+ }
+
+ while(*str) {
+ if (isupper(*str)) {
+ return str;
+ }
+ str++;
+ }
+ return NULL;
+}
static int __issue_ioctl(int sock_fd, char *if_name, char *cmd, char *buf)
{
return ret_val;
}
-static int __get_psk_hexascii(const char *pass, const unsigned char *salt, char *psk, unsigned int psk_len)
+static int __get_psk_hexascii(const char *pass, const unsigned char *salt,
+ char *psk, unsigned int psk_len)
{
- if (pass == NULL || salt == NULL || psk == NULL || psk_len == 0) {
+ if (pass == NULL || salt == NULL || psk == NULL || psk_len <
+ (SHA256_DIGEST_LENGTH * 2 + 1)) {
ERR("Invalid parameter\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
- if (psk_len < SHA256_DIGEST_LENGTH * 2 + 1) {
- ERR("Invalid parameter\n");
- return MOBILE_AP_ERROR_INVALID_PARAM;
- }
-
- int i;
- int d_16;
- int r_16;
+ int i = 0;
+ int d_16 = 0;
+ int r_16 = 0;
unsigned char buf[SHA256_DIGEST_LENGTH] = {0, };
if (!PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass),
salt, strlen((const char *)salt),
PSK_ITERATION_COUNT, sizeof(buf), buf)) {
ERR("Getting psk is failed\n");
- return MOBILE_AP_ERROR_INTERNAL;
+ return MOBILE_AP_ERROR_RESOURCE;
}
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
return MOBILE_AP_ERROR_NONE;
}
-static int __execute_hostapd(const char *ssid, const char *security,
- const char *key, int hide_mode)
+static int __execute_hostapd(const mobile_ap_type_e type, const char *ssid,
+ const char *security, const char *passphrase, int hide_mode)
{
DBG("+\n");
- char psk[2 * SHA256_DIGEST_LENGTH + 1] = {0, };
+ char *conf = NULL;
+ char *old_conf;
char buf[HOSTAPD_CONF_LEN] = "";
- char sec_buf[HOSTAPD_CONF_LEN] = "";
FILE *fp = NULL;
pid_t pid;
-
- if (security != NULL && !strcmp(security, "wpa2-psk")) {
- if (__get_psk_hexascii(key, (const unsigned char *)ssid, psk,
- sizeof(psk)) != MOBILE_AP_ERROR_NONE) {
- ERR("Getting PSK(Hex ascii type) is failed\n");
- return MOBILE_AP_ERROR_INTERNAL;
- }
-
- snprintf(sec_buf, HOSTAPD_CONF_LEN,
- "wpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\nwps_state=2\neap_server=1",
- psk);
- }
-
- snprintf(buf, HOSTAPD_CONF_LEN, HOSTAPD_CONF,
+ int ret;
+ char key[MOBILE_AP_WIFI_KEY_MAX_LEN + 1];
+ /* Default conf. */
+ snprintf(buf, sizeof(buf), HOSTAPD_CONF,
WIFI_IF,
HOSTAPD_CTRL_INTF_DIR,
ssid,
MOBILE_AP_WIFI_CHANNEL,
hide_mode ? 2 : 0,
- MOBILE_AP_MAX_WIFI_STA,
- sec_buf);
+ MOBILE_AP_MAX_WIFI_STA);
+ conf = g_strdup(buf);
+
+ /* Vendor elements conf. */
+ if (type == MOBILE_AP_TYPE_WIFI) {
+ snprintf(buf, sizeof(buf),
+ "vendor_elements=%s\n", HOSTAPD_VENDOR_ELEMENTS_TETH);
+ } else if (type == MOBILE_AP_TYPE_WIFI_AP) {
+ snprintf(buf, sizeof(buf),
+ "vendor_elements=%s\n", HOSTAPD_VENDOR_ELEMENTS_WIFI_AP);
+ } else {
+ ERR("Unknown type: %d\n", type);
+ g_free(conf);
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+ old_conf = conf;
+ conf = g_strconcat(old_conf, buf, NULL);
+ g_free(old_conf);
+
+ /* Security conf. */
+ if (security != NULL && !strcmp(security, "wpa2-psk")) {
+ ret = __get_psk_hexascii(passphrase, (const unsigned char *)ssid, key, sizeof(key));
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ g_free(conf);
+ ERR("hex conversion failed\n");
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+ snprintf(buf, sizeof(buf),
+ "wpa=2\nrsn_pairwise=CCMP\nwpa_psk=%s\n", key);
+
+ old_conf = conf;
+ conf = g_strconcat(old_conf, buf, NULL);
+ g_free(old_conf);
+ }
fp = fopen(HOSTAPD_CONF_FILE, "w");
if (NULL == fp) {
ERR("Could not create the file.\n");
+ g_free(conf);
return MOBILE_AP_ERROR_RESOURCE;
}
- fputs(buf, fp);
+ fputs(conf, fp);
+ g_free(conf);
fclose(fp);
pid = fork();
return MOBILE_AP_ERROR_RESOURCE;
}
- if (pid == 0) {
+ if (pid == 0) {
if (execl(HOSTAPD_BIN, HOSTAPD_BIN, "-e", HOSTAPD_ENTROPY_FILE,
HOSTAPD_CONF_FILE,
- "-f", HOSTAPD_DEBUG_FILE, "-dd",
+ "-f", HOSTAPD_DEBUG_FILE, "-ddd",
(char *)NULL)) {
ERR("execl failed\n");
}
{
DBG("+\n");
+ int ret;
+
if (hostapd_pid == 0) {
- DBG("There is no hostapd\n");
+ ERR("There is no hostapd\n");
return MOBILE_AP_ERROR_NONE;
}
waitpid(hostapd_pid, NULL, 0);
hostapd_pid = 0;
+ ret = unlink(HOSTAPD_CONF_FILE);
+ if (ret < 0) {
+ ERR("unlink is failed : %s\n", strerror(errno));
+ }
+
return MOBILE_AP_ERROR_NONE;
}
}
if (buf[0] == '<') {
- DBG("Unsolicited message\n");
+ ERR("Unsolicited message\n");
continue;
}
g_strlcpy(src.sun_path, intf, sizeof(src.sun_path));
if (stat(src.sun_path, &stat_buf) == 0) {
- DBG("There is already mh interface. It will be removed\n");
unlink(src.sun_path);
}
g_strlcpy(dest.sun_path, ctrl_intf, sizeof(dest.sun_path));
while (connect(*fd, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
- DBG("connect is failed : %s\n", strerror(errno));
if (++retry >= HOSTAPD_RETRY_MAX)
goto FAIL;
usleep(HOSTAPD_RETRY_DELAY);
{
DBG("+\n");
- char buf[HOSTAPD_REQ_MAX_LEN] = {0, };
+ GSList *l;
+ char buf[HOSTAPD_REQ_MAX_LEN + 1] = {0, };
char *pbuf = NULL;
gsize read = 0;
int n_station = 0;
+ int type;
+ sta_timer_t *ptr = NULL;
+ char *mac = NULL;
+ char *end = NULL;
+ gboolean discon_event = FALSE;
+
#if !GLIB_CHECK_VERSION(2, 31, 0)
int ret = 0;
if (pbuf != NULL)
*pbuf = '\0';
- if (buf[0] == '<' && (pbuf = strchr(buf, '>')) != NULL) {
- pbuf++;
- } else {
- pbuf = buf;
- }
-
- DBG("Event : %s\n", pbuf);
+ SDBG("Read string from hostapd = [%s]\n", buf);
+ pbuf = buf;
+ /* concatenated string, containing multiple events can arrive */
+ while (pbuf && *pbuf) {
+ pbuf = __find_first_caps_char(pbuf);
+ if (!pbuf || !*pbuf) {
+ break;
+ }
- if (!strncmp(pbuf, HOSTAPD_STA_DISCONN, strlen(HOSTAPD_STA_DISCONN))) {
- pbuf = strchr(pbuf, ' ');
- if (pbuf == NULL) {
- ERR("There is no info. for disconnected station\n");
- return TRUE;
+ if (!strncmp(pbuf, HOSTAPD_STA_CONN, HOSTAPD_STA_CONN_LEN)) {
+ pbuf = pbuf + HOSTAPD_STA_CONN_LEN;
+ if (!pbuf || !*pbuf) {
+ ERR("No mac address\n");
+ return TRUE;
+ }
+
+ end = strchr(pbuf, '<');
+ if (end && *end) {
+ mac = g_strndup(pbuf, (long)(end - pbuf));
+ pbuf = end + 1;
+ } else {
+ mac = g_strdup(pbuf);
+ pbuf += strlen(mac);
+ }
+
+ if (mac == NULL) {
+ ERR("strdup failed\n");
+ return TRUE;
+ }
+
+ for (l = sta_timer_list; l != NULL; l = g_slist_next(l)) {
+ ptr = (sta_timer_t *)l->data;
+ if (ptr == NULL) {
+ continue;
+ }
+
+ if (g_strcmp0(ptr->mac_addr, mac) == 0) {
+ g_free(mac);
+ mac = NULL;
+ break;
+ }
+ }
+
+ /* Matched station found, so skip */
+ if (l != NULL) {
+ continue;
+ }
+
+ SDBG("%s%s\n", HOSTAPD_STA_CONN, mac);
+ ptr = (sta_timer_t *)g_malloc(sizeof(sta_timer_t));
+ ptr->mac_addr = mac;
+ ptr->tid = g_timeout_add(HOSTAPD_DHCP_MAX_INTERVAL,
+ __hostapd_connect_timer_cb, mac);
+ sta_timer_list = g_slist_append(sta_timer_list, ptr);
+
+ } else if (!strncmp(pbuf, HOSTAPD_STA_DISCONN, HOSTAPD_STA_DISCONN_LEN)) {
+ pbuf = pbuf + HOSTAPD_STA_DISCONN_LEN;
+ if (!pbuf || !*pbuf) {
+ break;
+ }
+
+ end = strchr(pbuf, '<');
+ if (end && *end) {
+ mac = g_strndup(pbuf, (long)(end - pbuf));
+ pbuf = end + 1;
+ } else {
+ mac = g_strdup(pbuf);
+ pbuf += strlen(mac);
+ }
+
+ if (mac == NULL) {
+ ERR("strdup failed\n");
+ return TRUE;
+ }
+
+ SDBG("%s%s\n", HOSTAPD_STA_DISCONN, mac);
+ _remove_station_info(mac, _slist_find_station_by_mac);
+
+ /*
+ * Destroy the timer if its not expired before disconnection
+ */
+ _destroy_dhcp_ack_timer(mac);
+ g_free(mac);
+ mac = NULL;
+ discon_event = TRUE;
+
+ } else {
+ pbuf = strchr(pbuf, '>');
+ if (pbuf == NULL)
+ break;
+ pbuf++;
}
- pbuf++;
+ }
- DBG("Disconnected station MAC : %s\n", pbuf);
- _remove_station_info(pbuf, _slist_find_station_by_mac);
+ if (discon_event == FALSE)
+ goto DONE;
- _get_station_count((gconstpointer)MOBILE_AP_TYPE_WIFI,
- _slist_find_station_by_interface, &n_station);
- if (n_station == 0)
- _start_timeout_cb(MOBILE_AP_TYPE_WIFI);
-
- return TRUE;
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
+ type = MOBILE_AP_TYPE_WIFI;
+ } else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ type = MOBILE_AP_TYPE_WIFI_AP;
} else {
- DBG("Event is not handled\n");
+ goto DONE;
}
+ _get_station_count((gconstpointer)type,
+ _slist_find_station_by_interface, &n_station);
+
+ if (n_station == 0) {
+ if (type == MOBILE_AP_TYPE_WIFI)
+ _start_timeout_cb(type, time(NULL) + TETHERING_CONN_TIMEOUT);
+ else if (type == MOBILE_AP_TYPE_WIFI_AP)
+ _start_timeout_cb(type, time(NULL) + WIFI_AP_CONN_TIMEOUT);
+ }
+DONE:
return TRUE;
}
buf_len = sizeof(buf);
__send_hostapd_req(*fd, HOSTAPD_MONITOR_ATTACH,
strlen(HOSTAPD_MONITOR_ATTACH), buf, &buf_len);
- DBG("return : %s\n", buf);
return MOBILE_AP_ERROR_NONE;
}
buf_len = sizeof(buf);
__send_hostapd_req(*fd, HOSTAPD_MONITOR_DETACH,
strlen(HOSTAPD_MONITOR_DETACH), buf, &buf_len);
- DBG("return : %s\n", buf);
if (hostapd_io_source != 0) {
g_source_remove(hostapd_io_source);
return drv_interface;
}
-int _mh_core_enable_softap(const char *ssid, const char *security,
- const char *key, int hide_mode)
+static int __mh_core_softap_firmware_start(void)
+{
+ int err = 0;
+ DBusError error;
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ DBusMessage *message = NULL;
+ DBusConnection *connection = NULL;
+ const char *device = "softap";
+
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (connection == NULL) {
+ ERR("Failed to get system bus");
+ return -EIO;
+ }
+
+ message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+ NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE ".Firmware", "Start");
+ if (message == NULL) {
+ ERR("Failed DBus method call");
+ dbus_connection_unref(connection);
+ return -EIO;
+ }
+
+ dbus_message_iter_init_append(message, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &device);
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(connection, message,
+ NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+ if (dbus_error_is_set(&error) == TRUE) {
+ if (NULL != strstr(error.message, ".AlreadyExists")) {
+ // softap already enabled
+ } else {
+ ERR("dbus_connection_send_with_reply_and_block() failed. "
+ "DBus error [%s: %s]", error.name, error.message);
+
+ err = -EIO;
+
+ dbus_error_free(&error);
+ }
+
+ dbus_error_free(&error);
+ }
+
+ if (reply != NULL)
+ dbus_message_unref(reply);
+
+ dbus_message_unref(message);
+ dbus_connection_unref(connection);
+
+ return err;
+}
+
+static int __mh_core_softap_firmware_stop(void)
+{
+ int err = 0;
+ DBusError error;
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ DBusMessage *message = NULL;
+ DBusConnection *connection = NULL;
+ const char *device = "softap";
+
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ if (connection == NULL) {
+ ERR("Failed to get system bus");
+ return -EIO;
+ }
+
+ message = dbus_message_new_method_call(NETCONFIG_SERVICE,
+ NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE ".Firmware", "Stop");
+ if (message == NULL) {
+ ERR("Failed DBus method call");
+ dbus_connection_unref(connection);
+ return -EIO;
+ }
+
+ dbus_message_iter_init_append(message, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &device);
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(connection, message,
+ NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
+ if (dbus_error_is_set(&error) == TRUE) {
+ if (NULL != strstr(error.message, ".AlreadyExists")) {
+ // softap already disabled
+ } else {
+ ERR("dbus_connection_send_with_reply_and_block() failed. "
+ "DBus error [%s: %s]", error.name, error.message);
+
+ err = -EIO;
+
+ dbus_error_free(&error);
+ }
+
+ dbus_error_free(&error);
+ }
+
+ if (reply != NULL)
+ dbus_message_unref(reply);
+
+ dbus_message_unref(message);
+ dbus_connection_unref(connection);
+
+ return err;
+}
+
+int _mh_core_enable_softap(const mobile_ap_type_e type, const char *ssid,
+ const char *security, const char *key, int hide_mode)
{
if (ssid == NULL || security == NULL || key == NULL) {
ERR("Invalid param\n");
char *if_name = WIFI_IF;
char buf[MAX_BUF_SIZE] = { 0 };
- snprintf(cmd, sizeof(cmd), "%s softap", WLAN_SCRIPT);
- if (_execute_command(cmd)) {
- ERR("execute script failed : %s\n", cmd);
+ char wext_ssid[MOBILE_AP_WIFI_SSID_MAX_LEN] = { 0 };
+ char *ptr = NULL;
+
+ if (__mh_core_softap_firmware_start() < 0)
return MOBILE_AP_ERROR_INTERNAL;
- }
drv_interface = __get_drv_interface();
break;
}
+ /*
+ * In case of Wireless extension interface,
+ * 32 byte SSID including null character can be accepted.
+ */
+ g_strlcpy(wext_ssid, ssid, sizeof(wext_ssid));
+ if (!g_utf8_validate(wext_ssid, -1, (const char **)&ptr))
+ *ptr = '\0';
+
snprintf(cmd, MAX_BUF_SIZE, "ASCII_CMD=AP_CFG,"
"SSID_LEN=%d,SSID=%s,"
"SEC=%s,KEY_LEN=%d,KEY=%s,CHANNEL=%d,"
"PREAMBLE=0,MAX_SCB=%d,HIDE=%d,END",
- strlen(ssid), ssid,
+ strlen(wext_ssid), wext_ssid,
security, strlen(key), key,
MOBILE_AP_WIFI_CHANNEL,
MOBILE_AP_MAX_WIFI_STA, hide_mode);
break;
}
- DBG("Setting softap is OK\n");
ret_status = _mh_core_set_ip_address(WIFI_IF,
IP_ADDRESS_WIFI);
if (ret_status != MOBILE_AP_ERROR_NONE) {
break;
case MOBILE_AP_NL80211:
+
ret_status = _mh_core_set_ip_address(WIFI_IF,
IP_ADDRESS_SOFTAP);
if (ret_status != MOBILE_AP_ERROR_NONE) {
break;
}
- ret_status = __execute_hostapd(ssid, security, key, hide_mode);
+ ret_status = __execute_hostapd(type, ssid, security, key, hide_mode);
if (ret_status != MOBILE_AP_ERROR_NONE) {
ERR("__execute_hostapd is failed\n");
break;
break;
default:
- DBG("Unknown driver interface : %d\n", drv_interface);
+ ERR("Unknown driver interface : %d\n", drv_interface);
break;
}
- if (ret_status != MOBILE_AP_ERROR_NONE) {
- snprintf(cmd, sizeof(cmd), "%s stop", WLAN_SCRIPT);
- if (_execute_command(cmd)) {
- ERR("execute script failed : %s\n", cmd);
- }
- }
+ if (ret_status != MOBILE_AP_ERROR_NONE)
+ __mh_core_softap_firmware_stop();
return ret_status;
}
break;
default:
- DBG("Unknown driver interface : %d\n", drv_interface);
+ ERR("Unknown driver interface : %d\n", drv_interface);
break;
}
- snprintf(cmd, sizeof(cmd), "%s stop", WLAN_SCRIPT);
- if (_execute_command(cmd)) {
- ERR("execute script failed : %s\n", cmd);
+ if (__mh_core_softap_firmware_stop() < 0)
ret_status = MOBILE_AP_ERROR_INTERNAL;
- }
return ret_status;
}
buf_ptr = buf;
sscanf(buf_ptr, "%02x", &di->number);
- DBG("connected station : %d\n", di->number);
buf_ptr += 2;
for (i = 0; i < di->number; i++) {
l_bssid[0], l_bssid[1], l_bssid[2],
l_bssid[3], l_bssid[4], l_bssid[5]);
- DBG("STA[%d] address[%s]\n", i, di->bssid[i]);
+ SDBG("STA[%d] address[%s]\n", i, di->bssid[i]);
buf_ptr += 12;
}
break;
}
- DBG("Station : %s\n", buf);
+ SDBG("Station : %s\n", buf);
g_strlcpy(di->bssid[no_of_sta++], buf, MOBILE_AP_STR_INFO_LEN);
buf_len = sizeof(buf);
int _mh_core_terminate_dhcp_server(void)
{
+ int ret;
+
if (dnsmasq_pid == 0) {
- DBG("There is no dnsmasq\n");
+ ERR("There is no dnsmasq\n");
return MOBILE_AP_ERROR_NONE;
}
waitpid(dnsmasq_pid, NULL, 0);
dnsmasq_pid = 0;
+ ret = unlink(DNSMASQ_CONF_FILE);
+ if (ret < 0) {
+ ERR("unlink is failed : %s\n", strerror(errno));
+ }
+
return MOBILE_AP_ERROR_NONE;
}
}
int fd = -1;
- char cmd[MAX_BUF_SIZE] = {0, };
fd = open(IP_FORWARD, O_WRONLY);
if (fd < 0) {
}
close(fd);
- snprintf(cmd, sizeof(cmd), "%s -t nat -A POSTROUTING "MASQUERADE_RULE,
- IPTABLES, ext_if);
- if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
- return MOBILE_AP_ERROR_INTERNAL;
- }
-
- _add_data_usage_rule(WIFI_IF, ext_if);
- _add_data_usage_rule(BT_IF_ALL, ext_if);
- _add_data_usage_rule(USB_IF, ext_if);
+ _iptables_create_chain(TABLE_NAT, TETH_NAT_POST);
+ _iptables_add_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_POST,
+ TETH_NAT_POST);
+ _iptables_add_rule(MASQ_RULE, TABLE_NAT, TETH_NAT_POST, ext_if);
+
+ _iptables_create_chain(TABLE_FILTER, TETH_FILTER_FW);
+
+ _iptables_add_rule(PKT_REDIRECTION_RULE, TABLE_FILTER, CHAIN_FW,
+ TETH_FILTER_FW);
+
+ _iptables_add_rule(CLAMP_MSS_RULE, TABLE_FILTER, TETH_FILTER_FW);
+
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ BT_IF_ALL, ext_if, ACTION_RETURN, STATE_RELATED_ESTAB);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ WIFI_IF, ext_if, ACTION_RETURN, STATE_RELATED_ESTAB);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ USB_IF, ext_if, ACTION_RETURN, STATE_RELATED_ESTAB);
+
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, BT_IF_ALL, ACTION_DROP, STATE_INVALID);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, WIFI_IF, ACTION_DROP, STATE_INVALID);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION_AND_STATE, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, USB_IF, ACTION_DROP, STATE_INVALID);
+
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, BT_IF_ALL, ACTION_RETURN);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, WIFI_IF, ACTION_RETURN);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ ext_if, USB_IF, ACTION_RETURN);
+
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ BT_IF_ALL, ext_if, ACTION_RETURN);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ WIFI_IF, ext_if, ACTION_RETURN);
+ _iptables_add_rule(FORWARD_RULE_WITH_ACTION, TABLE_FILTER, TETH_FILTER_FW,
+ USB_IF, ext_if, ACTION_RETURN);
+
+ _iptables_add_rule(DEFAULT_RULE, TABLE_FILTER, TETH_FILTER_FW,
+ ACTION_DROP);
return MOBILE_AP_ERROR_NONE;
}
}
int fd = -1;
- char cmd[MAX_BUF_SIZE] = {0, };
fd = open(IP_FORWARD, O_WRONLY);
if (fd < 0) {
}
close(fd);
- snprintf(cmd, sizeof(cmd), "%s -t nat -D POSTROUTING "MASQUERADE_RULE,
- IPTABLES, ext_if);
- if (_execute_command(cmd)) {
- ERR("iptables failed : %s\n", cmd);
- return MOBILE_AP_ERROR_INTERNAL;
- }
+ _iptables_delete_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_POST,
+ TETH_NAT_POST);
+ _iptables_flush_rules(TABLE_NAT, TETH_NAT_POST);
+ _iptables_delete_chain(TABLE_NAT, TETH_NAT_POST);
- _del_data_usage_rule(WIFI_IF, ext_if);
- _del_data_usage_rule(BT_IF_ALL, ext_if);
- _del_data_usage_rule(USB_IF, ext_if);
+ _iptables_delete_rule(PKT_REDIRECTION_RULE, TABLE_FILTER, CHAIN_FW,
+ TETH_FILTER_FW);
+ _iptables_flush_rules(TABLE_FILTER, TETH_FILTER_FW);
+ _iptables_delete_chain(TABLE_FILTER, TETH_FILTER_FW);
return MOBILE_AP_ERROR_NONE;
}
struct sockaddr_in addr;
int sock_fd;
- DBG("if_name : %s ip address : 0x%X\n", if_name, ip);
+ SDBG("if_name : %s ip address : 0x%X\n", if_name, ip);
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
ERR("socket open failed!!!\n");
- perror("ioctl fail");
return MOBILE_AP_ERROR_RESOURCE;
}
memcpy(&ifr.ifr_addr, &addr, sizeof(struct sockaddr));
if (ioctl(sock_fd, SIOCSIFADDR, &ifr) < 0) {
ERR("ioctl failed...!!!\n");
- perror("ioctl fail");
close(sock_fd);
return MOBILE_AP_ERROR_INTERNAL;
}
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) < 0) {
ERR("ioctl failed...!!!\n");
- perror("ioctl fail");
close(sock_fd);
return MOBILE_AP_ERROR_INTERNAL;
}
ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) < 0) {
ERR("ioctl failed...!!!\n");
- perror("ioctl fail");
close(sock_fd);
return MOBILE_AP_ERROR_INTERNAL;
}
return MOBILE_AP_ERROR_NONE;
}
+
+static gboolean __send_station_event_cb(gpointer data)
+{
+ int sig = GPOINTER_TO_INT(data);
+ int n_station = 0;
+ int type;
+ mobile_ap_station_info_t *si = NULL;
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ type = MOBILE_AP_TYPE_WIFI;
+ else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
+ type = MOBILE_AP_TYPE_WIFI_AP;
+ else
+ return FALSE;
+
+ if (sig == SIGUSR1) {
+ DBG("STA connected(%d)\n", sig);
+ /* STA connection is handled in the dnsmasq signal handler */
+ } else if (sig == SIGUSR2) {
+ DBG("STA disconnected(%d)\n", sig);
+
+ /* Temporarily care only one station.
+ * Driver team should be support detail information */
+ if (_get_station_info((gconstpointer)type,
+ _slist_find_station_by_interface,
+ &si) != MOBILE_AP_ERROR_NONE) {
+ return FALSE;
+ }
+ _remove_station_info(si->mac, _slist_find_station_by_mac);
+
+ _get_station_count((gconstpointer)type,
+ _slist_find_station_by_interface, &n_station);
+ if (n_station == 0) {
+ if (type == MOBILE_AP_TYPE_WIFI)
+ _start_timeout_cb(type, time(NULL) + TETHERING_CONN_TIMEOUT);
+ else if (type == MOBILE_AP_TYPE_WIFI_AP)
+ _start_timeout_cb(type, time(NULL) + WIFI_AP_CONN_TIMEOUT);
+ }
+ }
+
+ return FALSE;
+}
+
+static void __handle_station_signal(int sig)
+{
+ g_idle_add(__send_station_event_cb, GINT_TO_POINTER(sig));
+ return;
+}
+
+void _register_wifi_station_handler(void)
+{
+ struct sigaction sa;
+
+ if (__get_drv_interface() != MOBILE_AP_WEXT)
+ return;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = __handle_station_signal;
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGUSR2, &sa, NULL);
+
+ return;
+}
+
+void _unregister_wifi_station_handler(void)
+{
+ struct sigaction sa;
+
+ if (__get_drv_interface() != MOBILE_AP_WEXT)
+ return;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGUSR2, &sa, NULL);
+
+ return;
+}
+
+static gboolean __hostapd_connect_timer_cb(gpointer user_data)
+{
+ char *mac = (char *)user_data;
+ GSList *l = NULL;
+ GSList *temp = NULL;
+ sta_timer_t *ptr = NULL;
+ mobile_ap_station_info_t *info = NULL;
+ time_t tm;
+ int n_station = 0;
+ int type;
+ int ret;
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ type = MOBILE_AP_TYPE_WIFI;
+ else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
+ type = MOBILE_AP_TYPE_WIFI_AP;
+ else
+ return FALSE;
+
+ for (l = sta_timer_list; l != NULL; l = g_slist_next(l)) {
+ ptr = (sta_timer_t *)l->data;
+ if (ptr == NULL)
+ continue;
+
+ if (!g_strcmp0(ptr->mac_addr, mac)) {
+ DBG("client with Static IP, Add station\n");
+
+ info = (mobile_ap_station_info_t *)g_malloc(sizeof(mobile_ap_station_info_t));
+ if (info == NULL) {
+ ERR("g_malloc failed\n");
+ g_free(ptr->mac_addr);
+ g_free(ptr);
+ temp = l;
+ l = g_slist_next(l);
+ sta_timer_list = g_slist_delete_link(sta_timer_list, temp);
+ break;
+ }
+
+ time(&tm);
+ info->tm = tm;
+ info->interface = type;
+ g_strlcpy(info->ip, "", sizeof(info->ip));
+ g_strlcpy(info->mac, mac, sizeof(info->mac));
+
+ ret = _get_wifi_name_from_lease_info(mac, &info->hostname);
+ if (ret != MOBILE_AP_ERROR_NONE)
+ info->hostname = g_strdup(MOBILE_AP_NAME_UNKNOWN);
+
+ g_free(ptr->mac_addr);
+ g_free(ptr);
+ temp = l;
+ l = g_slist_next(l);
+ sta_timer_list = g_slist_delete_link(sta_timer_list, temp);
+
+ goto SUCCESS;
+ }
+ }
+
+ return FALSE;
+
+SUCCESS :
+ if (_add_station_info(info) != MOBILE_AP_ERROR_NONE) {
+ g_free(info->hostname);
+ g_free(info);
+ return FALSE;
+ }
+
+ _get_station_count((gconstpointer)type,
+ _slist_find_station_by_interface, &n_station);
+ if (n_station == 1)
+ _stop_timeout_cb(type);
+
+ _send_dbus_station_info("DhcpConnected", info);
+
+ return FALSE;
+}
+
+void _flush_dhcp_ack_timer(void)
+{
+ DBG("+\n");
+
+ GSList *l = NULL;
+ GSList *temp = NULL;
+ sta_timer_t *ptr = NULL;
+
+ for (l = sta_timer_list; l != NULL; l = g_slist_next(l)) {
+ ptr = (sta_timer_t *)l->data;
+ if (ptr) {
+ if (ptr->tid != 0) {
+ g_source_remove(ptr->tid);
+ ptr->tid = 0;
+ }
+ g_free(ptr->mac_addr);
+ g_free(ptr);
+ }
+
+ temp = l;
+ l = g_slist_next(l);
+ sta_timer_list = g_slist_delete_link(sta_timer_list, temp);
+ }
+
+ DBG("-\n");
+ return;
+}
+
+void _destroy_dhcp_ack_timer(char *mac_addr)
+{
+ DBG("+\n");
+ if (mac_addr == NULL) {
+ ERR("mac address passed NULL\n");
+ return;
+ }
+
+ GSList *l = NULL;
+ GSList *temp = NULL;
+ sta_timer_t *ptr = NULL;
+
+ for (l = sta_timer_list; l != NULL; l = g_slist_next(l)) {
+
+ ptr = (sta_timer_t *)l->data;
+ if (ptr == NULL)
+ continue;
+
+ if (!g_strcmp0(ptr->mac_addr, mac_addr)) {
+
+ if (ptr->tid != 0) {
+ g_source_remove(ptr->tid);
+ ptr->tid = 0;
+ }
+ g_free(ptr->mac_addr);
+ g_free(ptr);
+ temp = l;
+ l = g_slist_next(l);
+ sta_timer_list = g_slist_delete_link(sta_timer_list,
+ temp);
+ break;
+ }
+ }
+
+ DBG("-\n");
+ return;
+}
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <gio/gio.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_common.h"
#include "mobileap_usb.h"
+static DBusGMethodInvocation *g_context = NULL;
+static gboolean in_progress = FALSE;
+static GDBusConnection *conn = NULL;
+static guint subscription_id = 0;
+static int usb_client_state = 0;
+
+#define USB_SYSTEM_DEVICE_PATH "/Org/Tizen/System/DeviceD/Usb"
+#define USB_SYSTEM_DEVICE_IFACE "org.tizen.system.deviced.Usb"
+#define USB_STATE_CHANGE_SIGNAL "StateChanged"
+
+enum usbclient_state {
+ USBCLIENT_STATE_DISCONNECTED = 0x00, /* usb cable is detached */
+ USBCLIENT_STATE_CONNECTED = 0x01, /* usb cable is attached */
+ /* usb cable is attached and available (ready to use) */
+ USBCLIENT_STATE_AVAILABLE = 0x02,
+};
+
+/* GDbus Signal Handler for USB Device State Changes */
+static void __usb_device_state_change_cb(GDBusConnection *connection,
+ const gchar *sender_name, const gchar *object_path,
+ const gchar *interface_name, const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+ unsigned int value = 0;
+ TetheringObject *obj = (TetheringObject *)user_data;
+
+ if (NULL == parameters || NULL == obj) {
+ ERR("Paramters Invalid \n");
+ return;
+ }
+
+ if (strcmp(object_path, USB_SYSTEM_DEVICE_PATH) ||
+ strcmp(interface_name, USB_SYSTEM_DEVICE_IFACE) ||
+ strcmp(signal_name, USB_STATE_CHANGE_SIGNAL)) {
+ ERR("Unknown DBUS Signal\n");
+ return;
+ }
+ g_variant_get(parameters, "(u)", &value);
+ DBG("Received signal(%s), value: (%u)", signal_name, value);
+ DBG("USB connected ? (%s)", value & USBCLIENT_STATE_CONNECTED? "Yes":"No");
+ DBG("USB available ? (%s)", value & USBCLIENT_STATE_AVAILABLE? "Yes":"No");
+
+ if (USBCLIENT_STATE_DISCONNECTED == value) {
+ _disable_usb_tethering(obj);
+
+ if (g_context) {
+ dbus_g_method_return(g_context, MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_RESOURCE);
+ g_context = NULL;
+ } else {
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
+ SIGNAL_MSG_NOT_AVAIL_INTERFACE);
+ }
+ }
+
+ usb_client_state = value;
+}
+
+int _dbus_register_usb_state_change_signal(void *data)
+{
+ mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
+ GError *error = NULL;
+
+#if !GLIB_CHECK_VERSION(2,36,0)
+ g_type_init();
+#endif
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error) {
+ ERR("Error occurred (%s)", error->message);
+ g_error_free(error);
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ goto FAIL;
+ }
+ if (!conn) {
+ ERR("Failed to get gdbus connection");
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ goto FAIL;
+ }
+
+ subscription_id = g_dbus_connection_signal_subscribe(
+ conn, NULL, USB_SYSTEM_DEVICE_IFACE,
+ USB_STATE_CHANGE_SIGNAL, USB_SYSTEM_DEVICE_PATH, NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE, __usb_device_state_change_cb,
+ data, NULL);
+
+ if (subscription_id == 0) {
+ ERR("Failed to subscribe signal (%d)", USB_STATE_CHANGE_SIGNAL);
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ goto FAIL;
+ }
+
+ usb_client_state = -1;
+ DBG("Successfully Subscribed USB State Signal Handler");
+ return ret;
+
+FAIL:
+ if (conn)
+ g_object_unref(conn);
+ return ret;
+}
static void __handle_usb_disconnect_cb(keynode_t *key, void *data)
{
vconf_name = vconf_keynode_get_name(key);
vconf_key = vconf_keynode_get_int(key);
- DBG("key = %s, value = %d(int)\n", vconf_name, vconf_key);
+ SDBG("key = %s, value = %d(int)\n", vconf_name, vconf_key);
- if (!strcmp(vconf_name, VCONFKEY_SYSMAN_USB_STATUS) &&
- vconf_key == VCONFKEY_SYSMAN_USB_DISCONNECTED)
+ /*
+ * P140305-02551: Disconnected State is implemented from DBUS instead of
+ * VCONF key.
+ */
+ if (usb_client_state == USBCLIENT_STATE_DISCONNECTED)
DBG("USB is disconnected\n");
else if (!strcmp(vconf_name, VCONFKEY_SETAPPL_USB_MODE_INT) &&
vconf_key != SETTING_USB_TETHERING_MODE)
- DBG("USB Mode is changed [%d]\n", vconf_key);
+ SDBG("USB Mode is changed [%d]\n", vconf_key);
else
return;
_disable_usb_tethering(obj);
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
- SIGNAL_MSG_NOT_AVAIL_INTERFACE);
+
+ if (g_context) {
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_RESOURCE);
+ g_context = NULL;
+ } else {
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
+ SIGNAL_MSG_NOT_AVAIL_INTERFACE);
+ }
+
+ return;
}
static void __handle_usb_mode_change(keynode_t *key, void *data)
TetheringObject *obj = (TetheringObject *)data;
int ret;
int vconf_key;
+ guint idle_id;
if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
ERR("Invalid vconf key\n");
}
vconf_key = vconf_keynode_get_int(key);
- DBG("key = %s, value = %d(int)\n",
+ SDBG("key = %s, value = %d(int)\n",
vconf_keynode_get_name(key), vconf_key);
if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
DBG("USB tethering is enabled\n");
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change);
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
- dbus_g_method_return(obj->usb_context,
- MOBILE_AP_ENABLE_USB_TETHERING_CFM,
- MOBILE_AP_ERROR_NONE);
- obj->usb_context = NULL;
/* USB Mode change is handled while USB tethering is enabled */
vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &vconf_key);
if (ret != 0) {
ERR("vconf_get_int is failed. but ignored [%d]\n", ret);
- return;
}
+
if (vconf_key != SETTING_USB_TETHERING_MODE) {
ERR("USB Mode is changed suddenly\n");
_disable_usb_tethering(obj);
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
- SIGNAL_MSG_NOT_AVAIL_INTERFACE);
+ if (g_context) {
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_RESOURCE);
+ g_context = NULL;
+ }
+ return;
+ }
+ _add_interface_routing(USB_IF, IP_ADDRESS_USB);
+ _add_routing_rule(USB_IF);
+
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
+ if (g_context) {
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_NONE);
+ g_context = NULL;
}
} else {
if (vconf_key == SETTING_USB_TETHERING_MODE) {
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change);
_emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
- dbus_g_method_return(obj->usb_context,
- MOBILE_AP_DISABLE_USB_TETHERING_CFM,
- MOBILE_AP_ERROR_NONE);
- obj->usb_context = NULL;
+ if (g_context) {
+ dbus_g_method_return(g_context,
+ MOBILE_AP_DISABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_NONE);
+ g_context = NULL;
+ }
+
+ in_progress = FALSE;
+ idle_id = g_idle_add(_terminate_mobileap_agent, NULL);
+ if (idle_id == 0)
+ ERR("g_idle_add is failed\n");
}
}
-mobile_ap_error_code_e _enable_usb_tethering(TetheringObject *obj,
- DBusGMethodInvocation *context)
+mobile_ap_error_code_e _enable_usb_tethering(TetheringObject *obj)
{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
int vconf_ret;
return ret;
}
- if (obj->usb_context) {
- ERR("USB request is progressing\n");
- ret = MOBILE_AP_ERROR_IN_PROGRESS;
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ ERR("Wi-Fi AP is enabled\n");
+ ret = MOBILE_AP_ERROR_RESOURCE;
return ret;
}
- vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
- __handle_usb_disconnect_cb, obj);
- vconf_ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &usb_mode);
- if (vconf_ret != 0 || usb_mode == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
- ERR("Error getting vconf\n");
+ /* Register DBus Signal Handler for USB Client State */
+ if (_dbus_register_usb_state_change_signal(obj) != MOBILE_AP_ERROR_NONE) {
+ ERR("Failed to register dbus signal(%d)", ret);
ret = MOBILE_AP_ERROR_RESOURCE;
goto FAIL;
}
goto FAIL;
}
- if (!_init_tethering(obj)) {
- ret = MOBILE_AP_ERROR_RESOURCE;
+ ret = _init_tethering(obj);
+ if (ret != MOBILE_AP_ERROR_NONE) {
goto FAIL;
}
- obj->usb_context = context;
vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change, (void *)obj);
vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
if (vconf_ret != 0) {
ERR("Error getting vconf\n");
- obj->usb_context = NULL;
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change);
_deinit_tethering(obj);
}
if (usb_mode == SETTING_USB_TETHERING_MODE) {
- obj->usb_context = NULL;
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change);
+ _add_interface_routing(USB_IF, IP_ADDRESS_USB);
+ _add_routing_rule(USB_IF);
}
DBG("-\n");
return MOBILE_AP_ERROR_NONE;
FAIL:
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
- __handle_usb_disconnect_cb);
+ /* Clear DBus Signal Handler for USB Client State */
+ if (conn) {
+ if (subscription_id > 0) {
+ g_dbus_connection_signal_unsubscribe(conn, subscription_id);
+ subscription_id = 0;
+ }
+ g_object_unref(conn);
+ conn = NULL;
+ }
_mobileap_clear_state(MOBILE_AP_STATE_USB);
return ret;
ERR("_remove_station_info_all is failed. Ignore it\n");
}
+ /* Clear DBus Signal Handler for USB Client State */
+ if (conn) {
+ if (subscription_id > 0) {
+ g_dbus_connection_signal_unsubscribe(conn, subscription_id);
+ subscription_id = 0;
+ }
+ g_object_unref(conn);
+ conn = NULL;
+ }
+
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_disconnect_cb);
- vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
- __handle_usb_disconnect_cb);
_mobileap_clear_state(MOBILE_AP_STATE_USB);
+ _del_routing_rule(USB_IF);
+ _del_interface_routing(USB_IF, IP_ADDRESS_USB);
DBG("_disable_usb_tethering is done\n");
DBusGMethodInvocation *context)
{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
+ gboolean ret_val = FALSE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
+ if (g_context) {
+ DBG("It is turnning on\n");
+ dbus_g_method_return(context,
+ MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_IN_PROGRESS);
+ return FALSE;
+ }
+
+ g_context = context;
- ret = _enable_usb_tethering(obj, context);
+ ret = _enable_usb_tethering(obj);
if (ret != MOBILE_AP_ERROR_NONE) {
ERR("_enable_usb_tethering() is failed : %d\n", ret);
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
- return FALSE;
- } else if (obj->usb_context == NULL) {
+ goto DONE;
+ } else {
DBG("Don't need to wait for usb-setting\n");
_emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
- dbus_g_method_return(context,
- MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
- } else {
- DBG("dbus will be returned by vconf callback\n");
+ ret_val = TRUE;
}
- return TRUE;
-}
+DONE:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
+ g_context = NULL;
+ return ret_val;
+}
gboolean tethering_disable_usb_tethering(TetheringObject *obj,
DBusGMethodInvocation *context)
g_assert(obj != NULL);
g_assert(context != NULL);
- if (obj->usb_context) {
- ERR("USB request is progressing\n");
- ret = MOBILE_AP_ERROR_IN_PROGRESS;
+ if (g_context) {
+ DBG("It is turnning on\n");
dbus_g_method_return(context,
- MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
+ MOBILE_AP_DISABLE_USB_TETHERING_CFM,
+ MOBILE_AP_ERROR_IN_PROGRESS);
return FALSE;
}
+ g_context = context;
+
ret = _disable_usb_tethering(obj);
if (ret != MOBILE_AP_ERROR_NONE) {
- dbus_g_method_return(context,
+ dbus_g_method_return(g_context,
MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
+ g_context = NULL;
return FALSE;
}
- obj->usb_context = context;
vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change, (void *)obj);
vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
ERR("Error getting vconf : %d. This error is ignored\n", vconf_ret);
goto DONE;
}
+
if (usb_mode != SETTING_USB_TETHERING_MODE) {
DBG("Don't need to wait for usb-setting\n");
goto DONE;
}
+ in_progress = TRUE;
+
DBG("-\n");
return TRUE;
vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
__handle_usb_mode_change);
_emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
- dbus_g_method_return(context,
+ dbus_g_method_return(g_context,
MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
- return TRUE;
-}
-
-static void __add_usb_station_info_to_array(GPtrArray *array, mobile_ap_station_info_t *node)
-{
- GValue value = {0, {{0}}};
-
- g_value_init(&value, DBUS_STRUCT_STATION);
- g_value_take_boxed(&value,
- dbus_g_type_specialized_construct(DBUS_STRUCT_STATION));
- dbus_g_type_struct_set(&value, 0, node->ip, 1, node->mac,
- 2, node->hostname, G_MAXUINT);
- g_ptr_array_add(array, g_value_get_boxed(&value));
-}
-
-gboolean tethering_get_usb_station_info(TetheringObject *obj,
- DBusGMethodInvocation *context)
-{
- g_assert(obj != NULL);
- g_assert(context != NULL);
-
- GPtrArray *array = g_ptr_array_new();
- mobile_ap_station_info_t *node = NULL;
-
- if (_get_station_info((gconstpointer)MOBILE_AP_TYPE_USB,
- _slist_find_station_by_interface,
- &node) != MOBILE_AP_ERROR_NONE) {
- DBG("There is no USB station\n");
- dbus_g_method_return(context, array);
- g_ptr_array_free(array, TRUE);
- return TRUE;
- }
-
- __add_usb_station_info_to_array(array, node);
- dbus_g_method_return(context, array);
- g_ptr_array_free(array, TRUE);
+ g_context = NULL;
return TRUE;
}
-gboolean tethering_get_usb_interface_info(TetheringObject *obj,
- DBusGMethodInvocation *context)
+gboolean _is_trying_usb_operation(void)
{
- g_assert(obj != NULL);
- g_assert(context != NULL);
-
- GPtrArray *array = g_ptr_array_new();
- GValue value = {0, {{0}}};
- struct in_addr addr;
-
- addr.s_addr = htonl(IP_ADDRESS_USB);
-
- g_value_init(&value, DBUS_STRUCT_INTERFACE);
- g_value_take_boxed(&value,
- dbus_g_type_specialized_construct(DBUS_STRUCT_INTERFACE));
- dbus_g_type_struct_set(&value, 0, USB_IF, 1, inet_ntoa(addr),
- 2, inet_ntoa(addr), 3, IP_SUBNET_MASK, G_MAXUINT);
-
- g_ptr_array_add(array, g_value_get_boxed(&value));
- dbus_g_method_return(context, array);
- g_ptr_array_free(array, TRUE);
-
- return TRUE;
+ return (g_context ? TRUE : FALSE || in_progress);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <ss_manager.h>
+#include <wifi.h>
+#include <wifi-direct.h>
-#include "mobileap_agent.h"
+#include "mobileap_softap.h"
#include "mobileap_common.h"
#include "mobileap_wifi.h"
#include "mobileap_handler.h"
#include "mobileap_notification.h"
-static int __generate_initial_passphrase(char *passphrase_buf);
-static mobile_ap_error_code_e __get_hide_mode(int *hide_mode);
-static mobile_ap_error_code_e __set_hide_mode(const int hide_mode);
-static mobile_ap_error_code_e __get_common_ssid(char *ssid, unsigned int size);
-static mobile_ap_error_code_e __get_security_type(char *security_type, unsigned int len);
-static mobile_ap_error_code_e __set_security_type(const char *security_type);
-static mobile_ap_error_code_e __get_passphrase(char *passphrase, unsigned int size, unsigned int *passphrase_len);
-static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size);
-static gboolean __send_station_event_cb(gpointer data);
-static void __handle_station_signal(int sig);
-static mobile_ap_error_code_e __update_wifi_data(TetheringObject *obj);
-
-static int __generate_initial_passphrase(char *passphrase_buf)
+#define WIFI_RECOVERY_GUARD_TIME 1000 /* ms */
+
+static mobile_ap_error_code_e __update_softap_settings(softap_settings_t *st,
+ gchar *ssid, gchar *passphrase, int hide_mode, softap_security_type_e security_type);
+static int __turn_off_wifi(TetheringObject *obj);
+
+static DBusGMethodInvocation *g_context = NULL;
+static guint wifi_recovery_timeout_id = 0;
+static gboolean prev_wifi_on = FALSE;
+static wifi_saved_settings wifi_settings = {0, NULL, NULL, 0};
+
+static void _wifi_direct_state_cb(int error_code, wifi_direct_device_state_e state, void *user_data)
{
+ bool wifi_state = false;
+
DBG("+\n");
- guint32 rand_int;
- int index;
+ if (user_data == NULL) {
+ ERR("The param is NULL\n");
+ return;
+ }
- for (index = 0; index < MOBILE_AP_WIFI_KEY_MIN_LEN; index++) {
- rand_int = g_random_int_range('a', 'z');
- passphrase_buf[index] = rand_int;
+ TetheringObject *obj = (TetheringObject *)user_data;
+ int ret = 0;
+
+ if (state != WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) {
+ ERR("Unknown state : %d\n", state);
+ return;
}
- passphrase_buf[index] = '\0';
- return index;
+ wifi_direct_unset_device_state_changed_cb();
+ wifi_direct_deinitialize();
+
+ if (error_code != 0) {
+ ERR("wifi_direct_deactivate fail in cb : %d\n", error_code);
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ goto DONE;
+ }
+ DBG("Wi-Fi direct is turned off\n");
+
+ wifi_is_activated(&wifi_state);
+ if (wifi_state) {
+ DBG("Wi-Fi is turned on. Turn off Wi-Fi");
+ if (__turn_off_wifi(obj) != MOBILE_AP_ERROR_NONE) {
+ ERR("_turn_off_wifi is failed\n");
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ goto DONE;
+ }
+ return;
+ }
+
+ ret = _enable_wifi_tethering(obj, wifi_settings.ssid, wifi_settings.key,
+ wifi_settings.hide_mode, wifi_settings.security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_enable_wifi_tethering is failed\n");
+ } else {
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_TETHER_ON, NULL);
+ }
+
+DONE:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
+ g_context = NULL;
+
+ g_free(wifi_settings.ssid);
+ g_free(wifi_settings.key);
+ memset(&wifi_settings, 0, sizeof(wifi_settings));
+
+ DBG("-\n");
+ return;
}
-static mobile_ap_error_code_e __get_hide_mode(int *hide_mode)
+static void __wifi_activated_cb(wifi_error_e result, void *user_data)
{
- if (hide_mode == NULL) {
- ERR("Invalid param\n");
- return MOBILE_AP_ERROR_INVALID_PARAM;
+ DBG("Wi-Fi on is done\n");
+
+ return;
+}
+
+static void __wifi_deactivated_cb(wifi_error_e result, void *user_data)
+{
+ DBG("+\n");
+
+ if (user_data == NULL) {
+ ERR("The param is NULL\n");
+ return;
}
- if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, hide_mode) < 0) {
- ERR("vconf_get_int is failed\n");
- return MOBILE_AP_ERROR_RESOURCE;
+ TetheringObject *obj = (TetheringObject *)user_data;
+ int ret;
+
+ if (result != WIFI_ERROR_NONE) {
+ ERR("__wifi_deactivated_cb error : %d\n", result);
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ goto DONE;
}
- return MOBILE_AP_ERROR_NONE;
+ DBG("Wi-Fi is turned off\n");
+
+ ret = _enable_wifi_tethering(obj, wifi_settings.ssid, wifi_settings.key,
+ wifi_settings.hide_mode, wifi_settings.security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_enable_wifi_tethering is failed\n");
+ } else {
+ prev_wifi_on = TRUE;
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_TETHER_ON, NULL);
+ }
+
+DONE:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
+ g_context = NULL;
+
+ g_free(wifi_settings.ssid);
+ g_free(wifi_settings.key);
+ memset(&wifi_settings, 0, sizeof(wifi_settings));
+
+ DBG("-\n");
+ return;
}
-static mobile_ap_error_code_e __set_hide_mode(const int hide_mode)
+static int __turn_off_wifi(TetheringObject *obj)
{
- if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, hide_mode) < 0) {
- ERR("vconf_set_int is failed\n");
- return MOBILE_AP_ERROR_RESOURCE;
+ int ret;
+
+ ret = wifi_deactivate(__wifi_deactivated_cb, (void *)obj);
+ if (ret != WIFI_ERROR_NONE) {
+ ERR("wifi_deactivate() is failed : %d\n", ret);
+ return MOBILE_AP_ERROR_INTERNAL;
}
return MOBILE_AP_ERROR_NONE;
}
-static mobile_ap_error_code_e __get_common_ssid(char *ssid, unsigned int size)
+static gboolean __turn_on_wifi_timeout_cb(gpointer user_data)
{
- if (ssid == NULL)
- return MOBILE_AP_ERROR_INVALID_PARAM;
+ int ret;
+ guint idle_id;
- char *ptr = NULL;
- char *ptr_tmp = NULL;
+ wifi_recovery_timeout_id = 0;
- ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
- if (ptr == NULL)
- return MOBILE_AP_ERROR_RESOURCE;
+ ret = wifi_activate(__wifi_activated_cb, NULL);
+ if (ret != WIFI_ERROR_NONE) {
+ ERR("wifi_activate() is failed : %d\n", ret);
+ }
- if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp))
- *ptr_tmp = '\0';
+ idle_id = g_idle_add(_terminate_mobileap_agent, NULL);
+ if (idle_id == 0) {
+ ERR("g_idle_add is failed\n");
+ }
- g_strlcpy(ssid, ptr, size);
- free(ptr);
+ return FALSE;
+}
+
+static int __turn_on_wifi(void)
+{
+ if (wifi_recovery_timeout_id > 0) {
+ g_source_remove(wifi_recovery_timeout_id);
+ wifi_recovery_timeout_id = 0;
+ }
+
+ wifi_recovery_timeout_id = g_timeout_add(WIFI_RECOVERY_GUARD_TIME,
+ __turn_on_wifi_timeout_cb, NULL);
+ if (wifi_recovery_timeout_id == 0) {
+ ERR("g_timeout_add is failed\n");
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
return MOBILE_AP_ERROR_NONE;
}
-static mobile_ap_error_code_e __get_security_type(char *security_type, unsigned int len)
+static gboolean __is_wifi_direct_on(void)
{
- if (security_type == NULL)
- return MOBILE_AP_ERROR_INVALID_PARAM;
+ int wifi_direct_state = 0;
+ int ret;
- char *type_str = NULL;
- softap_security_type_e type;
-
- if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, (int *)&type) < 0) {
- ERR("vconf_get_int is failed\n");
- return MOBILE_AP_ERROR_RESOURCE;
+ ret = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
+ if (ret < 0) {
+ ERR("vconf_get_int() is failed : %d\n", ret);
+ return FALSE;
}
- switch (type) {
- case SOFTAP_SECURITY_TYPE_OPEN:
- type_str = SOFTAP_SECURITY_TYPE_OPEN_STR;
- break;
+ return wifi_direct_state != 0 ? TRUE : FALSE;
+}
- case SOFTAP_SECURITY_TYPE_WPA2_PSK:
- type_str = SOFTAP_SECURITY_TYPE_WPA2_PSK_STR;
- break;
+static int __turn_off_wifi_direct(TetheringObject *obj)
+{
+ int ret;
- default:
- ERR("Invalid data\n");
- return MOBILE_AP_ERROR_RESOURCE;
+ ret = wifi_direct_initialize();
+ if (ret < 0) {
+ ERR("wifi_direct_initialize() is failed : %d\n", ret);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
+
+ ret = wifi_direct_set_device_state_changed_cb(_wifi_direct_state_cb, (void *)obj);
+ if (ret < 0) {
+ ERR("wifi_direct_set_device_state_changed_cb() is failed : %d\n", ret);
+ ret = wifi_direct_deinitialize();
+ DBG("wifi_direct_deinitialize() ret : %d\n", ret);
+ return MOBILE_AP_ERROR_INTERNAL;
}
- g_strlcpy(security_type, type_str, len);
+ ret = wifi_direct_deactivate();
+ if (ret < 0) {
+ ERR("wifi_direct_deactivate() is failed : %d\n", ret);
+ ret = wifi_direct_unset_device_state_changed_cb();
+ DBG("wifi_direct_unset_device_state_changed_cb() ret : %d\n", ret);
+ ret = wifi_direct_deinitialize();
+ DBG("wifi_direct_deinitialize() ret : %d\n", ret);
+ return MOBILE_AP_ERROR_INTERNAL;
+ }
return MOBILE_AP_ERROR_NONE;
}
-static mobile_ap_error_code_e __set_security_type(const char *security_type)
+static mobile_ap_error_code_e __update_softap_settings(softap_settings_t *st,
+ gchar *ssid, gchar *passphrase, int hide_mode, softap_security_type_e security_type)
{
- if (security_type == NULL) {
+ if (st == NULL) {
ERR("Invalid param\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
- softap_security_type_e type;
+ g_strlcpy(st->ssid, ssid, sizeof(st->ssid));
- if (!strcmp(security_type, SOFTAP_SECURITY_TYPE_OPEN_STR)) {
- type = SOFTAP_SECURITY_TYPE_OPEN;
- } else if (!strcmp(security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR)) {
- type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
+ if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK) {
+ g_strlcpy(st->security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR,
+ sizeof(st->security_type));
+ g_strlcpy(st->key, passphrase, sizeof(st->key));
+ } else if (security_type == SOFTAP_SECURITY_TYPE_OPEN) {
+ g_strlcpy(st->security_type, SOFTAP_SECURITY_TYPE_OPEN_STR,
+ sizeof(st->security_type));
+ g_strlcpy(st->key, "00000000", sizeof(st->key));
} else {
- ERR("Invalid param\n");
- return MOBILE_AP_ERROR_INVALID_PARAM;
+ ERR("Unknown security type\n");
+ return MOBILE_AP_ERROR_INTERNAL;
}
- if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, type) < 0) {
- ERR("vconf_set_int is failed\n");
- return MOBILE_AP_ERROR_RESOURCE;
- }
+ st->hide_mode = hide_mode;
+
+ SDBG("ssid : %s security type : %s hide mode : %d\n",
+ st->ssid, st->security_type, st->hide_mode);
return MOBILE_AP_ERROR_NONE;
}
-static mobile_ap_error_code_e __get_passphrase(char *passphrase,
- unsigned int size, unsigned int *passphrase_len)
+static gboolean __is_equal_softap_settings(softap_settings_t *a, softap_settings_t *b)
{
- if (passphrase == NULL || passphrase_len == NULL) {
- ERR("Invalid parameter\n");
+ if (a->hide_mode != b->hide_mode)
+ return FALSE;
+
+ if (strcmp(a->ssid, b->ssid) != 0)
+ return FALSE;
+
+ if (strcmp(a->key, b->key) != 0)
+ return FALSE;
+
+ if (strcmp(a->security_type, b->security_type) != 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+mobile_ap_error_code_e _reload_softap_settings(TetheringObject *obj,
+ gchar *ssid, gchar *key, gint hide_mode, gint security_type)
+{
+ gboolean backup_prev_wifi_on = prev_wifi_on;
+ mobile_ap_error_code_e ret;
+ softap_settings_t *old_settings = &obj->softap_settings;
+ softap_settings_t new_settings;
+
+ if (obj == NULL || ssid == NULL || !strlen(ssid)) {
+ ERR("invalid parameters\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
- int ret = 0;
- ssm_file_info_t sfi;
-
- ret = ssm_getinfo(SOFTAP_PASSPHRASE_PATH, &sfi,
- SSM_FLAG_SECRET_OPERATION, NULL);
- if (ret == -SS_FILE_OPEN_ERROR) {
- *passphrase_len = __generate_initial_passphrase(passphrase);
-
- ret = __set_passphrase(passphrase, *passphrase_len);
- if (ret != MOBILE_AP_ERROR_NONE) {
- memset(passphrase, 0x00, size);
- *passphrase_len = 0;
- return ret;
- }
+ if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
+ return MOBILE_AP_ERROR_NONE;
- ret = ssm_getinfo(SOFTAP_PASSPHRASE_PATH, &sfi,
- SSM_FLAG_SECRET_OPERATION, NULL);
- if (ret < 0) {
- ERR("ssm_getinfo is failed : %d\n", ret);
- memset(passphrase, 0x00, size);
- *passphrase_len = 0;
- return MOBILE_AP_ERROR_RESOURCE;
- }
- } else if (ret < 0) {
- ERR("ssm_getinfo is failed : %d\n", ret);
- return MOBILE_AP_ERROR_RESOURCE;
+ ret = __update_softap_settings(&new_settings, ssid, key, hide_mode,
+ (softap_security_type_e)security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("__update_softap_settings is failed\n");
+ return ret;
}
- memset(passphrase, 0x00, size);
- ret = ssm_read(SOFTAP_PASSPHRASE_PATH, passphrase, sfi.originSize,
- passphrase_len, SSM_FLAG_SECRET_OPERATION, NULL);
- if (ret < 0) {
- ERR("ssm_read is failed : %d\n", ret);
- return MOBILE_AP_ERROR_RESOURCE;
+ if (__is_equal_softap_settings(&new_settings, old_settings) == TRUE) {
+ DBG("No need to reload settings\n");
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ prev_wifi_on = FALSE;
+ ret = _disable_wifi_tethering(obj);
+
+ prev_wifi_on = backup_prev_wifi_on;
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_disable_wifi_tethering is failed : %d\n", ret);
+ return ret;
+ }
+
+ ret = _enable_wifi_tethering(obj, ssid, key, hide_mode,
+ (softap_security_type_e)security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_enable_wifi_tethering is failed : %d\n", ret);
+ return ret;
}
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_TETHER_ON, NULL);
return MOBILE_AP_ERROR_NONE;
}
-static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size)
+mobile_ap_error_code_e _reload_softap_settings_for_ap(TetheringObject *obj,
+ gchar *ssid, gchar *key, gint hide_mode, gint security_type)
{
- if (size < MOBILE_AP_WIFI_KEY_MIN_LEN || size > MOBILE_AP_WIFI_KEY_MAX_LEN ||
- passphrase == NULL) {
- ERR("Invalid parameter\n");
+ gboolean backup_prev_wifi_on = prev_wifi_on;
+ mobile_ap_error_code_e ret;
+ softap_settings_t *old_settings = &obj->softap_settings;
+ softap_settings_t new_settings;
+
+ if (obj == NULL || ssid == NULL || !strlen(ssid)) {
+ ERR("invalid parameters\n");
return MOBILE_AP_ERROR_INVALID_PARAM;
}
- int ret = 0;
+ ret = __update_softap_settings(&new_settings, ssid, key, hide_mode,
+ (softap_security_type_e)security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("__update_softap_settings is failed\n");
+ return ret;
+ }
- ret = ssm_write_buffer((char *)passphrase, size, SOFTAP_PASSPHRASE_PATH,
- SSM_FLAG_SECRET_OPERATION, NULL);
- if (ret < 0) {
- ERR("ssm_write_buffer is failed : %d\n", ret);
- return MOBILE_AP_ERROR_RESOURCE;
+ if (__is_equal_softap_settings(&new_settings, old_settings) == TRUE) {
+ DBG("No need to reload settings\n");
+ return MOBILE_AP_ERROR_NONE;
+ }
+
+ prev_wifi_on = FALSE;
+
+ ret = _disable_wifi_ap(obj);
+ prev_wifi_on = backup_prev_wifi_on;
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_disable_wifi_ap is failed : %d\n", ret);
+ return ret;
+ }
+
+ ret = _enable_wifi_ap(obj, ssid, key, hide_mode,
+ (softap_security_type_e)security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_enable_wifi_ap is failed : %d\n", ret);
+ return ret;
}
return MOBILE_AP_ERROR_NONE;
}
-static gboolean __send_station_event_cb(gpointer data)
+int _get_wifi_name_from_lease_info(const char *mac, char **name_buf)
{
- int sig = GPOINTER_TO_INT(data);
- int n_station = 0;
- mobile_ap_station_info_t *si = NULL;
-
- if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
- return FALSE;
+ if (mac == NULL || name_buf == NULL) {
+ return MOBILE_AP_ERROR_INVALID_PARAM;
}
- if (sig == SIGUSR1) {
- DBG("STA connected(%d)\n", sig);
- /* STA connection is handled in the dnsmasq signal handler */
- } else if (sig == SIGUSR2) {
- DBG("STA disconnected(%d)\n", sig);
-
- /* Temporarily care only one station.
- * Driver team should be support detail information */
- if (_get_station_info(MOBILE_AP_TYPE_WIFI,
- _slist_find_station_by_interface,
- &si) != MOBILE_AP_ERROR_NONE) {
- return FALSE;
- }
- _remove_station_info(si->mac, _slist_find_station_by_mac);
+ GIOChannel *io = NULL;
+ char *line = NULL;
+ char *device_name = MOBILE_AP_NAME_UNKNOWN;
+ char ip_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
+ char mac_addr[MOBILE_AP_STR_INFO_LEN] = {0, };
+ char name[MOBILE_AP_STR_HOSTNAME_LEN] = {0, };
+ char expire[MOBILE_AP_STR_INFO_LEN] = {0, };
+ char extra[MOBILE_AP_STR_INFO_LEN] = {0, };
- _get_station_count((gconstpointer)MOBILE_AP_TYPE_WIFI,
- _slist_find_station_by_interface, &n_station);
- if (n_station == 0)
- _start_timeout_cb(MOBILE_AP_TYPE_WIFI);
+ io = g_io_channel_new_file(DNSMASQ_LEASES_FILE, "r", NULL);
+ if (io == NULL) {
+ return MOBILE_AP_ERROR_RESOURCE;
}
- return FALSE;
-}
+ while (g_io_channel_read_line(io, &line, NULL, NULL, NULL) ==
+ G_IO_STATUS_NORMAL) {
+ sscanf(line, "%19s %19s %19s %19s %19s",
+ expire, mac_addr, ip_addr, name, extra);
+ g_free(line);
-static void __handle_station_signal(int sig)
-{
- g_idle_add(__send_station_event_cb, GINT_TO_POINTER(sig));
- return;
-}
+ if (g_ascii_strcasecmp(mac_addr, mac) == 0) {
+ if (g_strcmp0(name, "*") != 0)
+ device_name = name;
+ break;
+ }
+ }
+ g_io_channel_unref(io);
-void _register_wifi_station_handler(void)
-{
- struct sigaction sa;
+ *name_buf = g_strdup(device_name);
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = __handle_station_signal;
- sigaction(SIGUSR1, &sa, NULL);
- sigaction(SIGUSR2, &sa, NULL);
+ return MOBILE_AP_ERROR_NONE;
}
void _add_wifi_device_to_array(softap_device_info_t *di, GPtrArray *array)
int found = 0;
for (i = 0; i < di->number; i++)
- DBG("bssid[%d]:%s\n", i, di->bssid[i]);
+ SDBG("bssid[%d]:%s\n", i, di->bssid[i]);
DBG("Number of connected device:%d\n", di->number);
G_IO_STATUS_NORMAL) {
sscanf(line, "%19s %19s %19s %19s %19s", expire, mac_addr,
ip_addr, name, extra);
- DBG("mac_addr:%s ip_addr:%s name:%s expire:%s\n", mac_addr,
+ SDBG("mac_addr:%s ip_addr:%s name:%s expire:%s\n", mac_addr,
ip_addr, name, expire);
for (i = 0; i < di->number; i++) {
}
}
-mobile_ap_error_code_e _enable_wifi_tethering(TetheringObject *obj, gchar *ssid)
+mobile_ap_error_code_e _enable_wifi_tethering(TetheringObject *obj, gchar *ssid,
+ gchar *passphrase, int hide_mode, softap_security_type_e security_type)
{
mobile_ap_error_code_e ret;
+ if (obj == NULL || ssid == NULL || !strlen(ssid)) {
+ ERR("invalid parameters\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK && passphrase == NULL) {
+ ERR("passphrase is null\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ ERR("Wi-Fi AP is already enabled\n");
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ return ret;
+ }
+
if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
ERR("Wi-Fi tethering is already enabled\n");
ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
}
/* Update Wi-Fi hotspot data to common object */
- ret = __update_wifi_data(obj);
+ ret = __update_softap_settings(&obj->softap_settings, ssid, passphrase,
+ hide_mode, security_type);
if (ret != MOBILE_AP_ERROR_NONE) {
_mobileap_clear_state(MOBILE_AP_STATE_WIFI);
return ret;
}
- if (ssid != NULL && strlen(ssid) > 0) {
- DBG("Private(Passed) SSID is used : %s\n", ssid);
- g_strlcpy(obj->ssid, ssid, sizeof(obj->ssid));
+ if (vconf_set_str(VCONFKEY_MOBILE_HOTSPOT_SSID,
+ obj->softap_settings.ssid) < 0) {
+ ERR("vconf_set_str is failed\n");
}
/* Initialize tethering */
- if (!_init_tethering(obj)) {
+ _block_device_sleep();
+ ret = _init_tethering(obj);
+ if (ret != MOBILE_AP_ERROR_NONE) {
_mobileap_clear_state(MOBILE_AP_STATE_WIFI);
- ret = MOBILE_AP_ERROR_RESOURCE;
- return ret;
+ goto DONE;
}
/* Upload driver */
- ret = _mh_core_enable_softap(obj->ssid, obj->security_type,
- obj->key, obj->hide_mode);
+ ret = _mh_core_enable_softap(MOBILE_AP_TYPE_WIFI,
+ obj->softap_settings.ssid,
+ obj->softap_settings.security_type,
+ obj->softap_settings.key,
+ obj->softap_settings.hide_mode);
if (ret != MOBILE_AP_ERROR_NONE) {
_deinit_tethering(obj);
_mobileap_clear_state(MOBILE_AP_STATE_WIFI);
+ goto DONE;
+ }
+ _delete_timeout_noti();
+
+ _init_timeout_cb(MOBILE_AP_TYPE_WIFI, (void *)obj);
+ _start_timeout_cb(MOBILE_AP_TYPE_WIFI, time(NULL) + TETHERING_CONN_TIMEOUT);
+
+ _add_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
+ _add_routing_rule(WIFI_IF);
+
+DONE:
+ _unblock_device_sleep();
+ return ret;
+}
+
+mobile_ap_error_code_e _enable_wifi_ap(TetheringObject *obj,
+ gchar *ssid, gchar *passphrase, int hide_mode,
+ softap_security_type_e security_type)
+{
+ mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
+
+ if (obj == NULL || ssid == NULL || !strlen(ssid)) {
+ ERR("invalid parameters\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK &&
+ (passphrase == NULL || strlen(passphrase) >= MOBILE_AP_WIFI_KEY_MAX_LEN)) {
+ ERR("hex key length is not correct\n");
+ return MOBILE_AP_ERROR_INVALID_PARAM;
+ }
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_BT
+ | MOBILE_AP_STATE_USB)) {
+ ERR("Tethering is already enabled\n");
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
+ ERR("Wi-Fi AP is already enabled\n");
+ return MOBILE_AP_ERROR_ALREADY_ENABLED;
+ }
+
+ if (!_mobileap_set_state(MOBILE_AP_STATE_WIFI_AP)) {
+ return MOBILE_AP_ERROR_RESOURCE;
+ }
+
+ ret = __update_softap_settings(&obj->softap_settings, ssid, passphrase,
+ hide_mode, security_type);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
return ret;
}
+ _block_device_sleep();
+
+ if (_init_tethering(obj) != MOBILE_AP_ERROR_NONE) {
+ _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
+ ret = MOBILE_AP_ERROR_RESOURCE;
+ goto DONE;
+ }
+
+ /* Upload driver */
+ ret = _mh_core_enable_softap(MOBILE_AP_TYPE_WIFI_AP,
+ obj->softap_settings.ssid,
+ obj->softap_settings.security_type,
+ obj->softap_settings.key,
+ obj->softap_settings.hide_mode);
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ _deinit_tethering(obj);
+ _mobileap_clear_state(MOBILE_AP_STATE_WIFI_AP);
+ goto DONE;
+ }
+
_delete_timeout_noti();
- _init_timeout_cb(MOBILE_AP_TYPE_WIFI, (void *)obj);
- _start_timeout_cb(MOBILE_AP_TYPE_WIFI);
+ _init_timeout_cb(MOBILE_AP_TYPE_WIFI_AP, (void *)obj);
+ _start_timeout_cb(MOBILE_AP_TYPE_WIFI_AP, time(NULL) + WIFI_AP_CONN_TIMEOUT);
+ _add_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
+ _add_routing_rule(WIFI_IF);
- return MOBILE_AP_ERROR_NONE;
+DONE:
+ _unblock_device_sleep();
+ return ret;
}
mobile_ap_error_code_e _disable_wifi_tethering(TetheringObject *obj)
{
- int ret = MOBILE_AP_ERROR_NONE;
+ int ret;
+ int state;
+ mobile_ap_type_e type;
+
+ type = MOBILE_AP_TYPE_WIFI;
+ state = MOBILE_AP_STATE_WIFI;
- if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
- ERR("Wi-Fi tethering has not been activated\n");
+ if (!_mobileap_is_enabled(state)) {
+ ERR("Wi-Fi tethering ap has not been activated\n");
ret = MOBILE_AP_ERROR_NOT_ENABLED;
return ret;
}
- _deinit_timeout_cb(MOBILE_AP_TYPE_WIFI);
+ _block_device_sleep();
+ _del_routing_rule(WIFI_IF);
+ _del_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
+ _flush_ip_address(WIFI_IF);
+ _deinit_timeout_cb(type);
- if (_remove_station_info_all(MOBILE_AP_TYPE_WIFI) !=
- MOBILE_AP_ERROR_NONE) {
+ if (_remove_station_info_all(type) != MOBILE_AP_ERROR_NONE) {
ERR("_remove_station_info_all is failed. Ignore it.\n");
}
ret = _mh_core_disable_softap();
if (ret != MOBILE_AP_ERROR_NONE) {
ERR("_mh_core_disable_softap is failed : %d\n", ret);
- return ret;
+ goto DONE;
}
_deinit_tethering(obj);
- _mobileap_clear_state(MOBILE_AP_STATE_WIFI);
+ _mobileap_clear_state(state);
+ if (prev_wifi_on == TRUE) {
+ DBG("Previous Wi-Fi was turned on. Recover it\n");
+ if (__turn_on_wifi() != MOBILE_AP_ERROR_NONE) {
+ ERR("__turn_on_wifi() is failed\n");
+ }
+ prev_wifi_on = FALSE;
+ }
DBG("_disable_wifi_tethering is done\n");
+DONE:
+ _unblock_device_sleep();
return ret;
}
-static mobile_ap_error_code_e __update_wifi_data(TetheringObject *obj)
+mobile_ap_error_code_e _disable_wifi_ap(TetheringObject *obj)
{
- if (obj == NULL) {
- ERR("Invalid param\n");
- return MOBILE_AP_ERROR_INVALID_PARAM;
- }
+ int ret;
+ int state;
+ mobile_ap_type_e type;
- mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- unsigned int read_len = 0;
+ type = MOBILE_AP_TYPE_WIFI_AP;
+ state = MOBILE_AP_STATE_WIFI_AP;
- ret = __get_common_ssid(obj->ssid, sizeof(obj->ssid));
- if (ret != MOBILE_AP_ERROR_NONE)
+ if (!_mobileap_is_enabled(state)) {
+ ERR("Wi-Fi ap tethering has not been activated\n");
+ ret = MOBILE_AP_ERROR_NOT_ENABLED;
return ret;
+ }
- ret = __get_security_type(obj->security_type, sizeof(obj->security_type));
- if (ret != MOBILE_AP_ERROR_NONE)
- return ret;
+ _block_device_sleep();
+ _del_routing_rule(WIFI_IF);
+ _del_interface_routing(WIFI_IF, IP_ADDRESS_SOFTAP);
+ _flush_ip_address(WIFI_IF);
+ _deinit_timeout_cb(type);
- ret = __get_hide_mode(&obj->hide_mode);
- if (ret != MOBILE_AP_ERROR_NONE)
- return ret;
+ if (_remove_station_info_all(type) != MOBILE_AP_ERROR_NONE) {
+ ERR("_remove_station_info_all is failed. Ignore it.\n");
+ }
- if (strcmp(obj->security_type, SOFTAP_SECURITY_TYPE_OPEN_STR) == 0) {
- g_strlcpy(obj->key, "00000000", sizeof(obj->key));
- } else if (strcmp(obj->security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR) == 0) {
- ret = __get_passphrase(obj->key, sizeof(obj->key), &read_len);
- if (ret != MOBILE_AP_ERROR_NONE)
- return ret;
- } else {
- ERR("Unknown security type\n");
- return MOBILE_AP_ERROR_INTERNAL;
+ ret = _mh_core_disable_softap();
+ if (ret != MOBILE_AP_ERROR_NONE) {
+ ERR("_mh_core_disable_softap is failed : %d\n", ret);
+ goto DONE;
}
- DBG("ssid : %s security type : %s hide mode : %d\n",
- obj->ssid, obj->security_type, obj->hide_mode);
+ _deinit_tethering(obj);
+ _mobileap_clear_state(state);
+
+ DBG("_disable_wifi_ap is done\n");
- return MOBILE_AP_ERROR_NONE;
+DONE:
+ _unblock_device_sleep();
+ return ret;
}
gboolean tethering_enable_wifi_tethering(TetheringObject *obj, gchar *ssid,
- gchar *key, gint hide_mode, DBusGMethodInvocation *context)
+ gchar *key, gint visibility, gint security_type,
+ DBusGMethodInvocation *context)
{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
gboolean ret_val = FALSE;
+ bool wifi_state = false;
+ DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
+ if (g_context) {
+ DBG("It is turnning on\n");
+ dbus_g_method_return(context,
+ MOBILE_AP_ENABLE_WIFI_TETHERING_CFM,
+ MOBILE_AP_ERROR_IN_PROGRESS);
+ return FALSE;
+ }
+
+ g_context = context;
+
+ wifi_settings.ssid = g_strdup(ssid);
+ if (security_type == SOFTAP_SECURITY_TYPE_WPA2_PSK) {
+ wifi_settings.key = g_strdup(key);
+ wifi_settings.security_type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
+ } else {
+ wifi_settings.security_type = SOFTAP_SECURITY_TYPE_OPEN;
+ }
+ wifi_settings.hide_mode = (!visibility);
+
+ if (wifi_recovery_timeout_id) {
+ DBG("Wi-Fi recovery is cancelled\n");
+ g_source_remove(wifi_recovery_timeout_id);
+ wifi_recovery_timeout_id = 0;
+ prev_wifi_on = TRUE;
+ }
+
+ if (__is_wifi_direct_on() == TRUE) {
+ DBG("Wi-Fi and Wi-Fi direct are turned on\n");
+ if (__turn_off_wifi_direct(obj) != MOBILE_AP_ERROR_NONE) {
+ ERR("_turn_off_wifi_direct is failed\n");
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ goto DONE;
+ }
+
+ return TRUE;
+ }
+
+ wifi_is_activated(&wifi_state);
+ if (wifi_state == true) {
+ DBG("Wi-Fi is turned on\n");
+ if (__turn_off_wifi(obj) != MOBILE_AP_ERROR_NONE) {
+ ERR("_turn_off_wifi is failed\n");
+ ret = MOBILE_AP_ERROR_INTERNAL;
+ goto DONE;
+ }
- ret = _enable_wifi_tethering(obj, ssid);
+ return TRUE;
+ }
+
+ ret = _enable_wifi_tethering(obj, ssid, key, !visibility,
+ (softap_security_type_e)security_type);
if (ret != MOBILE_AP_ERROR_NONE) {
ERR("_enable_wifi_tethering is failed\n");
} else {
ret_val = TRUE;
}
- dbus_g_method_return(context, MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
+DONE:
+ dbus_g_method_return(g_context,
+ MOBILE_AP_ENABLE_WIFI_TETHERING_CFM, ret);
+ g_context = NULL;
+
+ g_free(wifi_settings.ssid);
+ g_free(wifi_settings.key);
+ memset(&wifi_settings, 0, sizeof(wifi_settings));
return ret_val;
}
-
gboolean tethering_disable_wifi_tethering(TetheringObject *obj,
DBusGMethodInvocation *context)
{
return TRUE;
}
-gboolean tethering_get_wifi_tethering_hide_mode(TetheringObject *obj,
- DBusGMethodInvocation *context)
+gboolean tethering_enable_wifi_ap(TetheringObject *obj, gchar *ssid, gchar *key,
+ gint visibility, gint security_type, DBusGMethodInvocation *context)
{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- int hide_mode = 0;
+ gboolean ret_val = FALSE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
- ret = __get_hide_mode(&hide_mode);
- if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_hide_mode is failed : %d\n", ret);
+ if (wifi_recovery_timeout_id) {
+ DBG("Wi-Fi recovery is cancelled\n");
+ g_source_remove(wifi_recovery_timeout_id);
+ wifi_recovery_timeout_id = 0;
}
- dbus_g_method_return(context, hide_mode);
-
- return TRUE;
-}
-
-gboolean tethering_set_wifi_tethering_hide_mode(TetheringObject *obj,
- gint hide_mode, DBusGMethodInvocation *context)
-{
- int ret = 0;
-
- DBG("+\n");
- g_assert(obj != NULL);
- g_assert(context != NULL);
-
- int old_hide_mode;
-
- ret = __get_hide_mode(&old_hide_mode);
+ ret = _enable_wifi_ap(obj, ssid, key, !visibility,
+ (softap_security_type_e)security_type);
if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_hide_mode is failed : %d\n", ret);
- } else if (old_hide_mode == hide_mode) {
- DBG("old_hide_mode == hide_mode\n");
- dbus_g_method_return(context);
- return TRUE;
- }
-
- ret = __set_hide_mode(hide_mode);
- if (ret < 0) {
- ERR("__set_hide_mode is failed : %d\n", ret);
+ ERR("_enable_wifi_tethering is failed\n");
+ } else {
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_AP_ON, NULL);
+ ret_val = TRUE;
}
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_SSID_VISIBILITY_CHANGED,
- hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF ?
- SIGNAL_MSG_SSID_VISIBLE :
- SIGNAL_MSG_SSID_HIDE);
- dbus_g_method_return(context);
+ dbus_g_method_return(context, MOBILE_AP_ENABLE_WIFI_AP_CFM, ret);
- return TRUE;
+ return ret_val;
}
-gboolean tethering_get_wifi_tethering_ssid(TetheringObject *obj,
+gboolean tethering_disable_wifi_ap(TetheringObject *obj,
DBusGMethodInvocation *context)
{
- mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- char ssid[MOBILE_AP_WIFI_SSID_MAX_LEN + 1] = {0, };
+ int ret = MOBILE_AP_ERROR_NONE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
- if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
- g_strlcpy(ssid, obj->ssid, sizeof(ssid));
- } else {
- ret = __get_common_ssid(ssid, sizeof(ssid));
- if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_common_ssid is failed : %d\n", ret);
- }
- }
+ ret = _disable_wifi_ap(obj);
- dbus_g_method_return(context, ssid);
+ _emit_mobileap_dbus_signal(obj, E_SIGNAL_WIFI_AP_OFF, NULL);
+ dbus_g_method_return(context, MOBILE_AP_DISABLE_WIFI_AP_CFM, ret);
+
+ if (ret != MOBILE_AP_ERROR_NONE)
+ return FALSE;
return TRUE;
}
-gboolean tethering_get_wifi_tethering_security_type(TetheringObject *obj,
+gboolean tethering_reload_wifi_settings(TetheringObject *obj, gchar *ssid,
+ gchar *key, gint visibility, gint security_type,
DBusGMethodInvocation *context)
{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- char security_type[SECURITY_TYPE_LEN] = {0, };
+ gboolean ret_val = TRUE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
- ret = __get_security_type(security_type, sizeof(security_type));
+ ret = _reload_softap_settings(obj, ssid, key, !visibility, security_type);
if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_security_type is failed : %d\n", ret);
+ ERR("_reload_softap_settings is failed\n");
+ ret_val = FALSE;
}
- dbus_g_method_return(context, security_type);
+ dbus_g_method_return(context, ret);
- return TRUE;
+ return ret_val;
}
-gboolean tethering_set_wifi_tethering_security_type(TetheringObject *obj,
- gchar *security_type, DBusGMethodInvocation *context)
+gboolean tethering_reload_wifi_ap_settings(TetheringObject *obj, gchar *ssid,
+ gchar *key, gint visibility, gint security, DBusGMethodInvocation *context)
{
- mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- char old_security_type[SECURITY_TYPE_LEN] = {0, };
-
- DBG("+\n");
- g_assert(obj != NULL);
- g_assert(context != NULL);
-
- ret = __get_security_type(old_security_type, sizeof(old_security_type));
- if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_security_type is failed : %d\n", ret);
- } else if (g_strcmp0(old_security_type, security_type) == 0) {
- DBG("old_security_type == security_type\n");
- dbus_g_method_return(context);
- return TRUE;
- }
-
- ret = __set_security_type(security_type);
- if (ret < 0) {
- ERR("__set_security_type is failed: %d\n", ret);
- }
-
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_SECURITY_TYPE_CHANGED,
- security_type);
- dbus_g_method_return(context);
-
- return TRUE;
-}
-gboolean tethering_get_wifi_tethering_passphrase(TetheringObject *obj,
- DBusGMethodInvocation *context)
-{
mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- char passphrase[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, };
- unsigned int len = 0;
+ gboolean ret_val = TRUE;
DBG("+\n");
g_assert(obj != NULL);
g_assert(context != NULL);
- ret = __get_passphrase(passphrase, sizeof(passphrase), &len);
+ ret = _reload_softap_settings_for_ap(obj, ssid, key, !visibility, security);
if (ret != MOBILE_AP_ERROR_NONE) {
- len = 0;
- ERR("__get_password is failed : %d\n", ret);
+ ERR("_reload_softap_settings_for_ap is failed\n");
+ ret_val = FALSE;
}
- dbus_g_method_return(context, passphrase, len);
-
- return TRUE;
+ dbus_g_method_return(context, ret);
+ return ret_val;
}
-gboolean tethering_set_wifi_tethering_passphrase(TetheringObject *obj,
- gchar *passphrase, guint len, DBusGMethodInvocation *context)
+gboolean _is_trying_wifi_operation(void)
{
- mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
- char old_passphrase[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, };
- unsigned int old_len = 0;
-
- DBG("+\n");
- g_assert(obj != NULL);
- g_assert(context != NULL);
-
- ret = __get_passphrase(old_passphrase, sizeof(old_passphrase), &old_len);
- if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__get_passphrase is failed : %d\n", ret);
- } else if (old_len == len && !g_strcmp0(old_passphrase, passphrase)) {
- dbus_g_method_return(context);
- return TRUE;
- }
-
- ret = __set_passphrase(passphrase, len);
- if (ret != MOBILE_AP_ERROR_NONE) {
- ERR("__set_passphrase is failed : %d\n", ret);
- }
-
- _emit_mobileap_dbus_signal(obj, E_SIGNAL_PASSPHRASE_CHANGED, NULL);
- dbus_g_method_return(context);
-
- return TRUE;
+ return (g_context || wifi_recovery_timeout_id ? TRUE : FALSE);
}
--- /dev/null
+#!/bin/sh
+#
+# Tethering module log dump (tethering_dump.sh)
+#
+
+# Variables
+TETH_DEBUG=$1/tethering
+mkdir -p ${TETH_DEBUG}
+
+# copy files
+#/bin/cp -a /tmp/hostapd.log ${TETH_DEBUG}
+/bin/cp -rf /tmp/dnsmasq.conf /opt/var/lib/misc/* ${TETH_DEBUG}
+
+#vconftool get db/mobile_hotspot > ${TETH_DEBUG}/vconf_db.log
+#vconftool get memory/mobile_hotspot > ${TETH_DEBUG}/vconf_memory.log
+/usr/sbin/iptables -t nat -L -vv > ${TETH_DEBUG}/iptables_nat.log
+/usr/sbin/iptables -L -vv > ${TETH_DEBUG}/iptables_filter.log