X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftethering.c;h=17723089151940075f3ac307b657d54399905434;hb=681a9dc90d29faa512d7bb6365847c4b76d550f5;hp=f51ccd22c95adc997fb34df5f246bad6a376885e;hpb=db05696b4589b808e1c0819a07dc0aed937a83d1;p=platform%2Fcore%2Fapi%2Ftethering.git diff --git a/src/tethering.c b/src/tethering.c index f51ccd2..1772308 100755 --- a/src/tethering.c +++ b/src/tethering.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#define _GNU_SOURCE #include #include #include @@ -26,11 +27,49 @@ #include #include #include -#include -#include #include +#include #include "tethering_private.h" +#define ALLOWED_LIST tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/hostapd.accept") +#define BLOCKED_LIST tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/hostapd.deny") +#define TEMP_LIST tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/.hostapd_tmp") +#define MAC_ADDR_LEN 18 +#define MAX_BUF_SIZE 80 + +#ifdef TIZEN_TV_EXT +#define VCONFKEY_WIFI_TXPOWER "db/dnet/txpower" /**< VCONFKEY for TX Power */ +#define VCONFKEY_WIFI_CHANNEL "db/dnet/channel" /**< VCONFKEY for Channel */ +#define VCONFKEY_WIFI_SSID "db/dnet/ssid" /**< VCONFKEY for ssid */ + +#define DBUS_DEFAULT_REPLY_TIMEOUT 15000 +#endif /* TIZEN_TV_EXT */ + +#define IPTABLES "/usr/sbin/iptables" +#define TABLE_NAT "nat" +#define TETH_NAT_PRE "teth_nat_pre" +#define TABLE_FILTER "filter" +#define TETH_FILTER_FW "teth_filter_fw" +#define ACTION_DROP "DROP" +#define ACTION_ACCEPT "ACCEPT" +#define PORT_FORWARD_RULE_STR "-t %s -A %s -i %s -p %s -d %s --dport %d -j DNAT --to %s:%d" +#define FILTERING_MULTIPORT_RULE_STR "-t %s -A %s -p %s -m multiport --dport %d,%d -j %s" +#define FILTERING_RULE_STR "-t %s -A %s -p %s --dport %d -j %s" + +typedef enum { + DUAL_BAND_NONE = 0, //0 + DUAL_BAND_2G = 1 << 0, //1 + DUAL_BAND_5G = 1 << 1, //2 + DUAL_BAND_MIN_INTERFACE = 1 << 2, //4 + DUAL_BAND_ALL = 7, //7 +} supported_band_e; + +static GSList *allowed_list = NULL; +static GSList *blocked_list = NULL; +static GSList *port_forwarding = NULL; +static GSList *port_filtering = NULL; +static GSList *custom_port_filtering = NULL; + static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data); @@ -55,14 +94,6 @@ static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sen const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data); -static void __handle_wifi_ap_on(GDBusConnection *connection, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data); - -static void __handle_wifi_ap_off(GDBusConnection *connection, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data); - static void __handle_net_closed(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data); @@ -103,19 +134,32 @@ static __tethering_sig_t sigs[] = { {0, SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off}, {0, SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on}, {0, SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off}, - {0, SIGNAL_NAME_WIFI_AP_ON, __handle_wifi_ap_on}, - {0, SIGNAL_NAME_WIFI_AP_OFF, __handle_wifi_ap_off}, {0, SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout}, {0, SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode}, {0, SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode}, {0, SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed}, {0, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed}, {0, SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed}, - {0, SIGNAL_NAME_DHCP_STATUS, __handle_dhcp}, - {0, "", NULL} }; + {0, SIGNAL_NAME_DHCP_STATUS, __handle_dhcp} }; static int retry = 0; +static int is_dualband_support = DUAL_BAND_NONE; + +static void __reset_dualband_support(void) +{ + is_dualband_support = DUAL_BAND_NONE; +} + +static void __set_dualband_support(int band) +{ + is_dualband_support |= band; + return; +} +static gboolean __is_dualband_support(void) +{ + return (is_dualband_support == DUAL_BAND_ALL) ? TRUE : FALSE; +} static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, const char *arg) { if (conn == NULL || signal_name == NULL) @@ -133,7 +177,6 @@ static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, c ERR("g_dbus_connection_emit_signal is failed because %s\n", error->message); g_error_free(error); } - g_variant_unref(message); } static bool __any_tethering_is_enabled(tethering_h tethering) @@ -141,7 +184,7 @@ static bool __any_tethering_is_enabled(tethering_h tethering) if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) || tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) || tethering_is_enabled(tethering, TETHERING_TYPE_BT) || - tethering_is_enabled(tethering, TETHERING_TYPE_RESERVED)) + tethering_is_enabled(tethering, TETHERING_TYPE_P2P)) return true; return false; @@ -150,7 +193,9 @@ static bool __any_tethering_is_enabled(tethering_h tethering) static tethering_error_e __set_security_type(const tethering_wifi_security_type_e security_type) { if (security_type != TETHERING_WIFI_SECURITY_TYPE_NONE && - security_type != TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) { + security_type != TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK && + security_type != TETHERING_WIFI_SECURITY_TYPE_WPS && + security_type != TETHERING_WIFI_SECURITY_TYPE_SAE) { ERR("Invalid param\n"); return TETHERING_ERROR_INVALID_PARAMETER; } @@ -191,6 +236,11 @@ static bool __get_ssid_from_vconf(const char *path, char *ssid, unsigned int siz if (ptr == NULL) return false; + if (!g_strcmp0(ptr, "")) { + free(ptr); + return false; + } + if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp)) *ptr_tmp = '\0'; @@ -301,7 +351,6 @@ static tethering_error_e __get_error(int agent_error) case MOBILE_AP_ERROR_PERMISSION_DENIED: err = TETHERING_ERROR_PERMISSION_DENIED; break; - default: ERR("Not defined error : %d\n", agent_error); err = TETHERING_ERROR_OPERATION_FAILED; @@ -311,13 +360,118 @@ static tethering_error_e __get_error(int agent_error) return err; } +static tethering_type_e __convert_to_tethering_type(mobile_ap_type_e type) +{ + switch (type) { + case MOBILE_AP_TYPE_USB: + return TETHERING_TYPE_USB; + case MOBILE_AP_TYPE_WIFI: + return TETHERING_TYPE_WIFI; + case MOBILE_AP_TYPE_BT: + return TETHERING_TYPE_BT; + case MOBILE_AP_TYPE_P2P: + return TETHERING_TYPE_P2P; + default: + return TETHERING_TYPE_MAX; + } +} + +static void __invoke_enable_cb(__tethering_h *th, tethering_type_e type, bool is_requested) +{ + if (th == NULL || th->enabled_cb[type] == NULL) { + ERR("th or enabled_cb is NULL"); + return; + } + + tethering_enabled_cb ecb = NULL; + void *data = NULL; + + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + return; + } + + ecb = th->enabled_cb[type]; + data = th->enabled_user_data[type]; + ecb(TETHERING_ERROR_NONE, type, is_requested, data); +} + +static int __get_disabled_cause_by_interface_error(tethering_type_e type) +{ + switch (type) { + case TETHERING_TYPE_USB: + return TETHERING_DISABLED_BY_USB_DISCONNECTION; + case TETHERING_TYPE_WIFI: + return TETHERING_DISABLED_BY_WIFI_ON; + case TETHERING_TYPE_BT: + return TETHERING_DISABLED_BY_BT_OFF; + default: + return TETHERING_DISABLED_BY_OTHERS; + } +} + +static void __invoke_disabled_cb(__tethering_h *th, tethering_type_e type, GVariant *parameters) +{ + if (th == NULL || th->disabled_cb[type] == NULL) { + ERR("th or disabled_cb is NULL"); + return; + } + + tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS; + tethering_disabled_cb dcb = NULL; + void *data = NULL; + char *buf = NULL; + + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + return; + } + + data = th->disabled_user_data[type]; + + g_variant_get(parameters, "(s)", &buf); + if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) + code = __get_disabled_cause_by_interface_error(type); + else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) + code = TETHERING_DISABLED_BY_TIMEOUT; + + dcb(TETHERING_ERROR_NONE, type, code, data); + g_free(buf); +} + +static void __invoke_disabled_cbs(__tethering_h *th, tethering_disabled_cause_e code) +{ + if (th == NULL) { + ERR("th is NULL"); + return; + } + + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + return; + } + + for (tethering_type_e type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { + tethering_disabled_cb dcb = th->disabled_cb[type]; + if (dcb == NULL) + continue; + void *data = th->disabled_user_data[type]; + dcb(TETHERING_ERROR_NONE, type, code, data); + } +} + static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } __tethering_h *th = (__tethering_h *)user_data; bool opened = false; @@ -344,19 +498,15 @@ static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name, goto DONE; } - if (ap_type == MOBILE_AP_TYPE_USB) - type = TETHERING_TYPE_USB; - else if (ap_type == MOBILE_AP_TYPE_WIFI) - type = TETHERING_TYPE_WIFI; - else if (ap_type == MOBILE_AP_TYPE_BT) - type = TETHERING_TYPE_BT; - else if (ap_type == MOBILE_AP_TYPE_WIFI_AP) { - type = TETHERING_TYPE_RESERVED; - } else { + type = __convert_to_tethering_type(ap_type); + if (type == TETHERING_TYPE_MAX) { ERR("Not supported tethering type [%d]\n", ap_type); goto DONE; } + SINFO("[%s] type %d, ip %s, mac %s, name %s, timestamp %d", + buf, ap_type, ip, mac, name, timestamp); + ccb = th->changed_cb[type]; if (ccb == NULL) goto DONE; @@ -376,6 +526,8 @@ DONE: g_free(ip); g_free(mac); g_free(name); + + TETHERING_UNLOCK; DBG("-\n"); } @@ -384,24 +536,10 @@ static void __handle_net_closed(GDBusConnection *connection, const gchar *sender GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = 0; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE; - - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { - dcb = th->disabled_cb[type]; - if (dcb == NULL) - continue; - data = th->disabled_user_data[type]; - - dcb(TETHERING_ERROR_NONE, type, code, data); - } - + TETHERING_LOCK; + SINFO("Tethering Disabled by network close !"); + __invoke_disabled_cbs((__tethering_h *)user_data, TETHERING_DISABLED_BY_NETWORK_CLOSE); + TETHERING_UNLOCK; DBG("-\n"); } @@ -410,21 +548,9 @@ static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *se GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_WIFI; - bool is_requested = false; - tethering_enabled_cb ecb = NULL; - void *data = NULL; - - ecb = th->enabled_cb[type]; - if (ecb == NULL) - return; - data = th->enabled_user_data[type]; - - ecb(TETHERING_ERROR_NONE, type, is_requested, data); + TETHERING_LOCK; + __invoke_enable_cb((__tethering_h *)user_data, TETHERING_TYPE_WIFI, false); + TETHERING_UNLOCK; DBG("-\n"); } @@ -433,29 +559,9 @@ static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *s GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_WIFI; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - char *buf = NULL; - - dcb = th->disabled_cb[type]; - if (dcb == NULL) - return; - data = th->disabled_user_data[type]; - g_variant_get(parameters, "(s)", &buf); - if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) - code = TETHERING_DISABLED_BY_WIFI_ON; - else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) - code = TETHERING_DISABLED_BY_TIMEOUT; - - g_free(buf); - dcb(TETHERING_ERROR_NONE, type, code, data); - + TETHERING_LOCK; + __invoke_disabled_cb((__tethering_h *)user_data, TETHERING_TYPE_WIFI, parameters); + TETHERING_UNLOCK; DBG("-\n"); } @@ -464,21 +570,9 @@ static void __handle_usb_tether_on(GDBusConnection *connection, const gchar *sen GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_USB; - bool is_requested = false; - tethering_enabled_cb ecb = NULL; - void *data = NULL; - - ecb = th->enabled_cb[type]; - if (ecb == NULL) - return; - data = th->enabled_user_data[type]; - - ecb(TETHERING_ERROR_NONE, type, is_requested, data); + TETHERING_LOCK; + __invoke_enable_cb((__tethering_h *)user_data, TETHERING_TYPE_USB, false); + TETHERING_UNLOCK; DBG("-\n"); } @@ -487,27 +581,9 @@ static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *se GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_USB; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - char *buf = NULL; - - dcb = th->disabled_cb[type]; - if (dcb == NULL) - return; - data = th->disabled_user_data[type]; - - g_variant_get(parameters, "(s)", &buf); - if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) - code = TETHERING_DISABLED_BY_USB_DISCONNECTION; - - dcb(TETHERING_ERROR_NONE, type, code, data); - g_free(buf); + TETHERING_LOCK; + __invoke_disabled_cb((__tethering_h *)user_data, TETHERING_TYPE_USB, parameters); + TETHERING_UNLOCK; DBG("-\n"); } @@ -516,21 +592,9 @@ static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *send GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_BT; - bool is_requested = false; - tethering_enabled_cb ecb = NULL; - void *data = NULL; - - ecb = th->enabled_cb[type]; - if (ecb == NULL) - return; - data = th->enabled_user_data[type]; - - ecb(TETHERING_ERROR_NONE, type, is_requested, data); + TETHERING_LOCK; + __invoke_enable_cb((__tethering_h *)user_data, TETHERING_TYPE_BT, false); + TETHERING_UNLOCK; DBG("-\n"); } @@ -539,179 +603,77 @@ static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sen GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_BT; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - char *buf = NULL; - - dcb = th->disabled_cb[type]; - if (dcb == NULL) - return; - data = th->disabled_user_data[type]; - g_variant_get(parameters, "(s)", &buf); - if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) - code = TETHERING_DISABLED_BY_BT_OFF; - else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) - code = TETHERING_DISABLED_BY_TIMEOUT; - - dcb(TETHERING_ERROR_NONE, type, code, data); - - g_free(buf); + TETHERING_LOCK; + __invoke_disabled_cb((__tethering_h *)user_data, TETHERING_TYPE_BT, parameters); + TETHERING_UNLOCK; DBG("-\n"); } -static void __handle_wifi_ap_on(GDBusConnection *connection, const gchar *sender_name, +static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_RESERVED; - bool is_requested = false; - tethering_enabled_cb ecb = NULL; - void *data = NULL; - - ecb = th->enabled_cb[type]; - if (ecb == NULL) - return; - data = th->enabled_user_data[type]; - - ecb(TETHERING_ERROR_NONE, type, is_requested, data); + TETHERING_LOCK; + __invoke_disabled_cbs((__tethering_h *)user_data, TETHERING_DISABLED_BY_TIMEOUT); + TETHERING_UNLOCK; DBG("-\n"); } -static void __handle_wifi_ap_off(GDBusConnection *connection, const gchar *sender_name, +static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = TETHERING_TYPE_RESERVED; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - char *buf = NULL; - - dcb = th->disabled_cb[type]; - if (dcb == NULL) - return; - data = th->disabled_user_data[type]; - g_variant_get(parameters, "(s)", &buf); - if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) - code = TETHERING_DISABLED_BY_WIFI_ON; - else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) - code = TETHERING_DISABLED_BY_TIMEOUT; - g_free(buf); - - dcb(TETHERING_ERROR_NONE, type, code, data); - + TETHERING_LOCK; + __invoke_disabled_cbs((__tethering_h *)user_data, TETHERING_DISABLED_BY_LOW_BATTERY); + TETHERING_UNLOCK; DBG("-\n"); } -static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name, +static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = 0; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT; - - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { - dcb = th->disabled_cb[type]; - if (dcb == NULL) - continue; - data = th->disabled_user_data[type]; - - dcb(TETHERING_ERROR_NONE, type, code, data); - } + TETHERING_LOCK; + __invoke_disabled_cbs((__tethering_h *)user_data, TETHERING_DISABLED_BY_FLIGHT_MODE); + TETHERING_UNLOCK; DBG("-\n"); } -static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data) +static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) + { DBG("+\n"); + TETHERING_LOCK; - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = 0; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY; - - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_RESERVED; type++) { - dcb = th->disabled_cb[type]; - if (dcb == NULL) - continue; - data = th->disabled_user_data[type]; - - dcb(TETHERING_ERROR_NONE, type, code, data); - } - DBG("-\n"); -} - -static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data) -{ - DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - __tethering_h *th = (__tethering_h *)user_data; - tethering_type_e type = 0; - tethering_disabled_cb dcb = NULL; - void *data = NULL; - tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE; - - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_RESERVED; type++) { - dcb = th->disabled_cb[type]; - if (dcb == NULL) - continue; - data = th->disabled_user_data[type]; - - dcb(TETHERING_ERROR_NONE, type, code, data); - } - DBG("-\n"); -} - -static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name, - const gchar *object_path, const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data) - -{ - DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - __tethering_h *th = (__tethering_h *)user_data; tethering_wifi_security_type_changed_cb scb = NULL; void *data = NULL; tethering_wifi_security_type_e security_type; char *buf = NULL; + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + scb = th->security_type_changed_cb; - if (scb == NULL) + if (scb == NULL) { + TETHERING_UNLOCK; return; + } g_variant_get(parameters, "(s)", &buf); data = th->security_type_user_data; @@ -719,14 +681,20 @@ static void __handle_security_type_changed(GDBusConnection *connection, const gc security_type = TETHERING_WIFI_SECURITY_TYPE_NONE; else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0) security_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK; + else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_WPS_STR) == 0) + security_type = TETHERING_WIFI_SECURITY_TYPE_WPS; + else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_SAE_STR) == 0) + security_type = TETHERING_WIFI_SECURITY_TYPE_SAE; else { SERR("Unknown type : %s\n", buf); g_free(buf); + TETHERING_UNLOCK; return; } g_free(buf); scb(security_type, data); + TETHERING_UNLOCK; return; } @@ -735,8 +703,14 @@ static void __handle_ssid_visibility_changed(GDBusConnection *connection, const GVariant *parameters, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); __tethering_h *th = (__tethering_h *)user_data; tethering_wifi_ssid_visibility_changed_cb scb = NULL; @@ -744,8 +718,15 @@ static void __handle_ssid_visibility_changed(GDBusConnection *connection, const bool visible = false; char *buf = NULL; + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + scb = th->ssid_visibility_changed_cb; if (scb == NULL) { + TETHERING_UNLOCK; DBG("-\n"); return; } @@ -756,6 +737,8 @@ static void __handle_ssid_visibility_changed(GDBusConnection *connection, const scb(visible, data); g_free(buf); + + TETHERING_UNLOCK; DBG("-\n"); } @@ -764,36 +747,66 @@ static void __handle_passphrase_changed(GDBusConnection *connection, const gchar GVariant *parameters, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); __tethering_h *th = (__tethering_h *)user_data; tethering_wifi_passphrase_changed_cb pcb = NULL; void *data = NULL; + if (!_tethering_check_handle(th)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + pcb = th->passphrase_changed_cb; - if (pcb == NULL) + if (pcb == NULL) { + TETHERING_UNLOCK; return; + } data = th->passphrase_user_data; pcb(data); + + TETHERING_UNLOCK; DBG("-\n"); } static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - DBG("+\n"); + INFO("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); GError *g_error = NULL; GVariant *g_var; guint info; + tethering_type_e type = TETHERING_TYPE_WIFI; tethering_error_e error; __tethering_h *th = (__tethering_h *)user_data; - tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_WIFI]; - void *data = th->enabled_user_data[TETHERING_TYPE_WIFI]; + + tethering_enabled_cb ecb = th->enabled_cb[type]; + void *data = th->enabled_user_data[type]; + + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { @@ -801,7 +814,8 @@ static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, if (g_error->code == G_DBUS_ERROR_NO_REPLY && ++retry < TETHERING_ERROR_RECOVERY_MAX) { g_error_free(g_error); - tethering_enable((tethering_h)th, TETHERING_TYPE_WIFI); + tethering_enable((tethering_h)th, type); + TETHERING_UNLOCK; return; } else if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED) error = TETHERING_ERROR_PERMISSION_DENIED; @@ -810,29 +824,43 @@ static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, g_error_free(g_error); } else { g_variant_get(g_var, "(u)", &info); + g_variant_unref(g_var); error = __get_error(info); } retry = 0; + INFO("cfm event : wifi tethering enable info : %d\n", error); + sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_ON].name, TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, sigs[E_SIGNAL_WIFI_TETHER_ON].cb, (gpointer)th, NULL); + SINFO("Tethering enabled event ! error(%d)", error); + if (!ecb) { - DBG("-\n"); + TETHERING_UNLOCK; + INFO("-\n"); return; } - ecb(error, TETHERING_TYPE_WIFI, true, data); - g_variant_unref(g_var); - DBG("-\n"); + ecb(error, type, true, data); + + TETHERING_UNLOCK; + INFO("-\n"); } static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { DBG("+\n"); - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } + GError *g_error = NULL; GVariant *g_var; guint info; @@ -842,6 +870,12 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_BT]; void *data = th->enabled_user_data[TETHERING_TYPE_BT]; + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { ERR("DBus error [%s]\n", g_error->message); @@ -849,6 +883,7 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, ++retry < TETHERING_ERROR_RECOVERY_MAX) { g_error_free(g_error); tethering_enable((tethering_h)th, TETHERING_TYPE_BT); + TETHERING_UNLOCK; DBG("-\n"); return; } @@ -870,11 +905,14 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, sigs[E_SIGNAL_BT_TETHER_ON].cb, (gpointer)th, NULL); if (!ecb) { + TETHERING_UNLOCK; DBG("-\n"); return; } ecb(error, TETHERING_TYPE_BT, true, data); + + TETHERING_UNLOCK; DBG("-\n"); } @@ -882,8 +920,14 @@ static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); __tethering_h *th = (__tethering_h *)user_data; GError *g_error = NULL; GVariant *g_var; @@ -892,6 +936,12 @@ static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_USB]; void *data = th->enabled_user_data[TETHERING_TYPE_USB]; + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { ERR("DBus error [%s]\n", g_error->message); @@ -899,6 +949,7 @@ static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, ++retry < TETHERING_ERROR_RECOVERY_MAX) { g_error_free(g_error); tethering_enable((tethering_h)th, TETHERING_TYPE_USB); + TETHERING_UNLOCK; DBG("-\n"); return; } @@ -920,27 +971,42 @@ static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, sigs[E_SIGNAL_USB_TETHER_ON].cb, (gpointer)th, NULL); if (!ecb) { + TETHERING_UNLOCK; DBG("-\n"); return; } ecb(error, TETHERING_TYPE_USB, true, data); + + TETHERING_UNLOCK; DBG("-\n"); } -static void __wifi_ap_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, - gpointer user_data) +static void __p2p_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); __tethering_h *th = (__tethering_h *)user_data; GError *g_error = NULL; GVariant *g_var; guint info; tethering_error_e error; - tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_RESERVED]; - void *data = th->enabled_user_data[TETHERING_TYPE_RESERVED]; + tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_P2P]; + void *data = th->enabled_user_data[TETHERING_TYPE_P2P]; + + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { @@ -948,7 +1014,8 @@ static void __wifi_ap_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, if (g_error->code == G_DBUS_ERROR_NO_REPLY && ++retry < TETHERING_ERROR_RECOVERY_MAX) { g_error_free(g_error); - tethering_enable((tethering_h)th, TETHERING_TYPE_RESERVED); + tethering_enable((tethering_h)th, TETHERING_TYPE_P2P); + TETHERING_UNLOCK; DBG("-\n"); return; } @@ -964,26 +1031,30 @@ static void __wifi_ap_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, } retry = 0; - sigs[E_SIGNAL_WIFI_AP_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, - NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_AP_ON].name, - TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, - sigs[E_SIGNAL_WIFI_AP_ON].cb, (gpointer)th, NULL); - if (!ecb) { + TETHERING_UNLOCK; DBG("-\n"); return; } - ecb(error, TETHERING_TYPE_RESERVED, true, data); + ecb(error, TETHERING_TYPE_P2P, true, data); + + TETHERING_UNLOCK; DBG("-\n"); } static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - DBG("+\n"); + INFO("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); GError *g_error = NULL; GVariant *g_var; guint info, event_type; @@ -995,17 +1066,24 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, tethering_disabled_cb dcb = NULL; void *data = NULL; + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { ERR("DBus error [%s]\n", g_error->message); g_error_free(g_error); + TETHERING_UNLOCK; return; } g_variant_get(g_var, "(uu)", &event_type, &info); - DBG("cfm event : %d info : %d\n", event_type, info); + INFO("cfm event : %d info : %d\n", event_type, info); g_variant_unref(g_var); error = __get_error(info); - DBG("cfm event : %d info : %d\n", event_type, error); + INFO("cfm event : %d info : %d\n", event_type, error); switch (event_type) { case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM: sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, @@ -1046,13 +1124,8 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, dcb(error, type, code, data); break; - case MOBILE_AP_DISABLE_WIFI_AP_CFM: - sigs[E_SIGNAL_WIFI_AP_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, - NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_AP_OFF].name, - TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, - sigs[E_SIGNAL_WIFI_AP_OFF].cb, (gpointer)th, NULL); - - type = TETHERING_TYPE_RESERVED; + case MOBILE_AP_DISABLE_P2P_TETHERING_CFM: + type = TETHERING_TYPE_P2P; dcb = th->disabled_cb[type]; data = th->disabled_user_data[type]; if (dcb) @@ -1088,15 +1161,22 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, ERR("Invalid event\n"); break; } - DBG("-\n"); + + TETHERING_UNLOCK; + INFO("-\n"); } static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } GError *g_error = NULL; GVariant *g_var; @@ -1106,6 +1186,12 @@ static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, tethering_error_e tethering_error = TETHERING_ERROR_NONE; bool flag = false; + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } + g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { ERR("DBus fail [%s]\n", g_error->message); @@ -1118,6 +1204,7 @@ static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, } if (th->data_usage_cb == NULL) { ERR("There is no data_usage_cb\n"); + TETHERING_UNLOCK; return; } if (flag) { @@ -1131,6 +1218,7 @@ static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, th->data_usage_cb = NULL; th->data_usage_user_data = NULL; + TETHERING_UNLOCK; DBG("-\n"); } @@ -1138,13 +1226,25 @@ static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { DBG("+\n"); + TETHERING_LOCK; + + if (user_data == NULL) { + ERR("parameter(user_data) is NULL"); + TETHERING_UNLOCK; + return; + } - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); GError *g_error = NULL; GVariant *g_var; guint info; __tethering_h *th = (__tethering_h *)user_data; - tethering_error_e tethering_error; + tethering_error_e tethering_error = TETHERING_ERROR_NONE; + + if (!_tethering_check_handle((tethering_h)user_data)) { + DBG("Tethering handle is not valid now, ignore it."); + TETHERING_UNLOCK; + return; + } g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { @@ -1154,57 +1254,26 @@ static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res, else tethering_error = TETHERING_ERROR_OPERATION_FAILED; g_error_free(g_error); + } else { + g_variant_get(g_var, "(u)", &info); + if (tethering_error == TETHERING_ERROR_NONE) + tethering_error = __get_error(info); + g_variant_unref(g_var); } + if (th->settings_reloaded_cb == NULL) { DBG("There is no settings_reloaded_cb\n-\n"); + TETHERING_UNLOCK; return; } - g_variant_get(g_var, "(u)", &info); - tethering_error = __get_error(info); - g_variant_unref(g_var); th->settings_reloaded_cb(tethering_error, th->settings_reloaded_user_data); th->settings_reloaded_cb = NULL; th->settings_reloaded_user_data = NULL; - DBG("-\n"); -} - -static void __ap_settings_reloaded_cb(GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - DBG("+\n"); - - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - GError *g_error = NULL; - GVariant *g_var; - guint info; - __tethering_h *th = (__tethering_h *)user_data; - tethering_error_e tethering_error; - - g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); - if (g_error) { - ERR("DBus fail [%s]\n", g_error->message); - if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED) - tethering_error = TETHERING_ERROR_PERMISSION_DENIED; - else - tethering_error = TETHERING_ERROR_OPERATION_FAILED; - g_error_free(g_error); - } - if (th->ap_settings_reloaded_cb == NULL) { - DBG("There is no settings_reloaded_cb\n-\n"); - return; - } - g_variant_get(g_var, "(u)", &info); - tethering_error = __get_error(info); - g_variant_unref(g_var); - - th->ap_settings_reloaded_cb(tethering_error, - th->ap_settings_reloaded_user_data); - th->ap_settings_reloaded_cb = NULL; - th->ap_settings_reloaded_user_data = NULL; + TETHERING_UNLOCK; DBG("-\n"); } @@ -1252,19 +1321,15 @@ static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len) case TETHERING_TYPE_USB: g_strlcpy(buf, TETHERING_USB_IF, len); break; - case TETHERING_TYPE_WIFI: g_strlcpy(buf, TETHERING_WIFI_IF, len); break; - case TETHERING_TYPE_BT: g_strlcpy(buf, TETHERING_BT_IF, len); break; - - case TETHERING_TYPE_RESERVED: - g_strlcpy(buf, TETHERING_WIFI_IF, len); + case TETHERING_TYPE_P2P: + g_strlcpy(buf, TETHERING_P2P_IF, len); break; - default: ERR("Not supported type : %d\n", type); return false; @@ -1280,19 +1345,15 @@ static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int le case TETHERING_TYPE_USB: g_strlcpy(buf, TETHERING_USB_GATEWAY, len); break; - case TETHERING_TYPE_WIFI: g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len); break; - case TETHERING_TYPE_BT: g_strlcpy(buf, TETHERING_BT_GATEWAY, len); break; - - case TETHERING_TYPE_RESERVED: - g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len); + case TETHERING_TYPE_P2P: + g_strlcpy(buf, TETHERING_P2P_GATEWAY, len); break; - default: ERR("Not supported type : %d\n", type); return false; @@ -1307,30 +1368,53 @@ static int __get_common_ssid(char *ssid, unsigned int size) return TETHERING_ERROR_INVALID_PARAMETER; } - char *ptr = NULL; - char *ptr_tmp = NULL; +#ifdef TIZEN_TV_EXT + if (__get_ssid_from_vconf(VCONFKEY_WIFI_SSID, ssid, size)) + return TETHERING_ERROR_NONE; + else + ERR("vconf key get failed for ssid or invalid ssid is found"); +#endif /* TIZEN_TV_EXT */ - ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); - if (ptr == NULL) { + if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR, + ssid, size) == false) { ERR("vconf_get_str is failed and set default ssid"); g_strlcpy(ssid, TETHERING_DEFAULT_SSID, size); - } else - g_strlcpy(ssid, ptr, size); + } - free(ptr); + return TETHERING_ERROR_NONE; +} - if (!g_utf8_validate(ssid, -1, (const char **)&ptr_tmp)) - *ptr_tmp = '\0'; +static bool __get_wifi_mode_type(tethering_wifi_mode_type_e type, char **buf) +{ + _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n"); - return TETHERING_ERROR_NONE; + switch (type) { + case TETHERING_WIFI_MODE_TYPE_B: + *buf = g_strdup("b"); + break; + case TETHERING_WIFI_MODE_TYPE_G: + *buf = g_strdup("g"); + break; + case TETHERING_WIFI_MODE_TYPE_A: + *buf = g_strdup("a"); + break; + case TETHERING_WIFI_MODE_TYPE_AD: + *buf = g_strdup("ad"); + break; + default: + ERR("Not supported type : %d\n", type); + return false; + } + return true; } static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *set) { - DBG("+\n"); + INFO("+\n"); __tethering_h *th = (__tethering_h *)tethering; tethering_error_e ret = TETHERING_ERROR_NONE; + char *ptr = NULL; if (th == NULL || set == NULL) { ERR("null parameter\n-\n"); @@ -1350,6 +1434,19 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se if (ret != TETHERING_ERROR_NONE) set->visibility = th->visibility; + set->mac_filter = th->mac_filter; + set->max_connected = th->wifi_max_connected; + set->channel = th->channel; + set->txpower = th->txpower; + + __get_wifi_mode_type(th->mode_type, &ptr); + if (ptr == NULL) { + g_strlcpy(set->mode, "", sizeof(set->mode)); + } else { + g_strlcpy(set->mode, ptr, sizeof(set->mode)); + free(ptr); + } + if (set->sec_type == TETHERING_WIFI_SECURITY_TYPE_NONE) { g_strlcpy(set->key, "", sizeof(set->key)); } else { @@ -1375,71 +1472,77 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se } if (parameters != NULL) { - g_variant_get(parameters, "(siu)", passphrase, &len, &ret); + g_variant_get(parameters, "(siu)", &passphrase, &len, &ret); + g_strlcpy(set->key, passphrase, sizeof(set->key) - 1); + g_free(passphrase); g_variant_unref(parameters); } - - g_strlcpy(set->key, passphrase, sizeof(set->key)); - } - DBG("-\n"); - return TETHERING_ERROR_NONE; -} - -static int __prepare_wifi_ap_settings(tethering_h tethering, _softap_settings_t *set) -{ - DBG("+\n"); - - __tethering_h *th = (__tethering_h *)tethering; - - if (th == NULL || set == NULL) { - ERR("null parameter\n"); - return TETHERING_ERROR_INVALID_PARAMETER; } - g_strlcpy(set->ssid, th->ap_ssid, sizeof(set->ssid)); - set->sec_type = th->sec_type; - set->visibility = th->visibility; - - if (set->sec_type == TETHERING_WIFI_SECURITY_TYPE_NONE) - g_strlcpy(set->key, "", sizeof(set->key)); + if (strlen(th->ip_address)) + g_strlcpy(set->ip_address, th->ip_address, sizeof(set->ip_address)); else - g_strlcpy(set->key, th->passphrase, sizeof(set->key)); - - DBG("-\n"); + g_strlcpy(set->ip_address, TETHERING_WIFI_GATEWAY, sizeof(set->ip_address)); + + INFO("ssid: %s security: %d mode: %s " + "channel: %d visibility: %s ip_address: [%s]\n", + set->ssid, set->sec_type, set->mode, set->channel, + (set->visibility) ? "true" : "false", + set->ip_address); + INFO("-\n"); return TETHERING_ERROR_NONE; } -static bool __check_precondition(tethering_type_e type) +static bool __check_precondition(__tethering_h *th, tethering_type_e type) { - int dnet_state = 0; + int dnet_status = 0; int cellular_state = 0; - int wifi_state = 0; /* data network through cellular */ vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state); if (cellular_state == VCONFKEY_NETWORK_CELLULAR_ON) { - ERR("Data Network can be connected later"); + INFO("Data Network can be connected later"); return TRUE; } - vconf_get_int(VCONFKEY_DNET_STATE, &dnet_state); - if (dnet_state > VCONFKEY_DNET_OFF) { - ERR("Data Network is connected"); + /* data network status */ + vconf_get_int(VCONFKEY_NETWORK_STATUS, &dnet_status); + if ((dnet_status == VCONFKEY_NETWORK_WIFI + && type != TETHERING_TYPE_WIFI) + || (th->wifi_sharing && dnet_status == VCONFKEY_NETWORK_WIFI + && type == TETHERING_TYPE_WIFI) + || dnet_status == VCONFKEY_NETWORK_ETHERNET) return TRUE; + + ERR("Network is not available!"); + return FALSE; +} + +#ifdef TIZEN_TV_EXT +static void __set_vconf_values_for_tv(__tethering_h *tethering) +{ + int ret, channel, txpower; + __tethering_h *th = tethering; + + if (th == NULL) + return; + + ret = vconf_get_int(VCONFKEY_WIFI_CHANNEL, &channel); + if (ret < 0) { + ERR("vconf key get failed for channel !!"); + channel = TETHERING_WIFI_CHANNEL; } - /* data network through wifi */ - if (type != TETHERING_TYPE_WIFI) { - vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); - if (wifi_state > VCONFKEY_WIFI_UNCONNECTED) { - ERR("Wi-Fi is connected!"); - return TRUE; - } + ret = vconf_get_int(VCONFKEY_WIFI_TXPOWER, &txpower); + if (ret < 0) { + ERR("vconf key get failed for txpower !!"); + txpower = TETHERING_WIFI_MAX_TXPOWER; } - ERR("Network is not available!"); - return FALSE; + th->channel = channel; + th->txpower = txpower; } +#endif /* TIZEN_TV_EXT */ /** * @internal @@ -1461,7 +1564,7 @@ API int tethering_create(tethering_h *tethering) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - DBG("+\n"); + INFO("+\n"); __tethering_h *th = NULL; GError *error = NULL; @@ -1474,6 +1577,12 @@ API int tethering_create(tethering_h *tethering) memset(th, 0x00, sizeof(__tethering_h)); th->sec_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK; th->visibility = true; + th->mac_filter = false; + th->wifi_sharing = false; + th->channel = TETHERING_WIFI_CHANNEL; + th->mode_type = TETHERING_WIFI_MODE_TYPE_G; + th->wifi_max_connected = TETHERING_WIFI_MAX_STA; + th->txpower = TETHERING_WIFI_MAX_TXPOWER; if (__generate_initial_passphrase(th->passphrase, sizeof(th->passphrase)) == 0) { @@ -1488,12 +1597,12 @@ API int tethering_create(tethering_h *tethering) return TETHERING_ERROR_OPERATION_FAILED; } - th->ap_ssid = g_strdup(ssid); - if (th->ap_ssid == NULL) { - ERR("g_strdup failed\n"); - free(th); - return TETHERING_ERROR_OPERATION_FAILED; - } +#ifdef TIZEN_TV_EXT + __set_vconf_values_for_tv(th); +#endif /* TIZEN_TV_EXT */ + SINFO("ssid: %s, key: %s, channel: %d, mode: %d, txpower: %d, security: %d max_device: %d\n", + ssid, th->passphrase, th->channel, th->mode_type, th->txpower, th->sec_type, + th->wifi_max_connected); #if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); @@ -1505,21 +1614,20 @@ API int tethering_create(tethering_h *tethering) g_error_free(error); g_cancellable_cancel(cancellable); g_object_unref(cancellable); - g_free(th->ap_ssid); free(th); return TETHERING_ERROR_OPERATION_FAILED; } th->cancellable = cancellable; - th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_NONE, + th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION, NULL, TETHERING_SERVICE_NAME, TETHERING_SERVICE_OBJECT_PATH, TETHERING_SERVICE_INTERFACE, th->cancellable, &error); if (!th->client_bus_proxy) { - ERR("Couldn't create the proxy object because of %s\n", error->message); + if (error) + ERR("Couldn't create the proxy object because of %s\n", error->message); g_cancellable_cancel(th->cancellable); g_object_unref(th->cancellable); g_object_unref(th->client_bus); - g_free(th->ap_ssid); free(th); return TETHERING_ERROR_OPERATION_FAILED; } @@ -1527,8 +1635,9 @@ API int tethering_create(tethering_h *tethering) __connect_signals((tethering_h)th); *tethering = (tethering_h)th; - DBG("Tethering Handle : 0x%X\n", th); - DBG("-\n"); + _tethering_add_handle(th); + INFO("Tethering Handle : %p\n", th); + INFO("-\n"); return TETHERING_ERROR_NONE; } @@ -1546,31 +1655,112 @@ API int tethering_create(tethering_h *tethering) */ API int tethering_destroy(tethering_h tethering) { - DBG("+\n"); + INFO("+\n"); CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - DBG("Tethering Handle : 0x%X\n", th); + INFO("Tethering Handle : %p\n", th); + __disconnect_signals(tethering); + _tethering_remove_handle(th); if (th->ssid) free(th->ssid); - if (th->ap_ssid) - free(th->ap_ssid); g_object_unref(th->cancellable); g_object_unref(th->client_bus_proxy); g_object_unref(th->client_bus); memset(th, 0x00, sizeof(__tethering_h)); + free(th); - DBG("-\n"); + INFO("-\n"); return TETHERING_ERROR_NONE; } +static GVariant *__get_wifi_settings_dbus_params(const char *wifi_tether_type, _softap_settings_t *set) +{ + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + if (builder == NULL) { + ERR("Failed to create builder"); + return NULL; + } + + g_variant_builder_add(builder, "{sv}", + "ssid", + g_variant_new_string(set->ssid)); + + if (set->sec_type != TETHERING_WIFI_SECURITY_TYPE_NONE) + g_variant_builder_add(builder, "{sv}", + "passphrase", + g_variant_new_string(set->key)); + + if (!g_strcmp0(set->mode, "b")) { + g_variant_builder_add(builder, "{sv}", + "mode", g_variant_new_int32(0)); + } else if (!g_strcmp0(set->mode, "g")) { + g_variant_builder_add(builder, "{sv}", + "mode", g_variant_new_int32(1)); + } else if (!g_strcmp0(set->mode, "n")) { + g_variant_builder_add(builder, "{sv}", + "mode", g_variant_new_int32(2)); + } else if (!g_strcmp0(set->mode, "ac")) { + g_variant_builder_add(builder, "{sv}", + "mode", g_variant_new_int32(3)); + } else { + /* Do Nothing */ + } + + g_variant_builder_add(builder, "{sv}", + "visibility", + g_variant_new_boolean(set->visibility)); + + g_variant_builder_add(builder, "{sv}", + "channel", + g_variant_new_int32(set->channel)); + + g_variant_builder_add(builder, "{sv}", + "sec_type", + g_variant_new_int32(set->sec_type)); + + g_variant_builder_add(builder, "{sv}", + "mac_filter", + g_variant_new_boolean(set->mac_filter)); + + g_variant_builder_add(builder, "{sv}", + "max_sta", + g_variant_new_int32(set->max_connected)); + + g_variant_builder_add(builder, "{sv}", + "address_type", + g_variant_new_int32(TETHERING_ADDRESS_FAMILY_IPV4)); + + g_variant_builder_add(builder, "{sv}", + "txpower", + g_variant_new_int32(set->txpower)); + + if (strlen(set->ip_address)) + g_variant_builder_add(builder, "{sv}", + "ip_address", + g_variant_new_string(set->ip_address)); + + if (wifi_tether_type) + g_variant_builder_add(builder, "{sv}", + "tether_type", + g_variant_new_string(wifi_tether_type)); + + params = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); + g_variant_builder_unref(builder); + + return params; +} + /** * @internal * @brief Enables the tethering, asynchronously. @@ -1588,7 +1778,7 @@ API int tethering_destroy(tethering_h tethering) */ API int tethering_enable(tethering_h tethering, tethering_type_e type) { - DBG("+ type : %d\n", type); + INFO("+ type : %d\n", type); CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); @@ -1602,11 +1792,15 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) GDBusProxy *proxy = th->client_bus_proxy; GDBusConnection *connection = th->client_bus; +#ifdef TIZEN_TV_EXT + g_dbus_proxy_set_default_timeout(proxy, DBUS_DEFAULT_REPLY_TIMEOUT); +#else /* TIZEN_TV_EXT */ g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE); +#endif /* TIZEN_TV_EXT */ - if (type != TETHERING_TYPE_RESERVED - && __check_precondition(type) == FALSE) { - DBG("-\n"); + if (__check_precondition(th, type) == FALSE) { + INFO("-\n"); + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); return TETHERING_ERROR_OPERATION_FAILED; } @@ -1615,13 +1809,16 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_USB_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL, + g_dbus_proxy_call(proxy, "enable_usb_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); break; case TETHERING_TYPE_WIFI: { - _softap_settings_t set = {"", "", 0, false}; + GVariant *params = NULL; + _softap_settings_t set; + memset(&set, 0, sizeof(_softap_settings_t)); ret = __prepare_wifi_settings(tethering, &set); if (ret != TETHERING_ERROR_NONE) { @@ -1632,10 +1829,22 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_wifi_tethering", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), + SINFO("ssid %s, key %s, channel %d, mode %s, " + "txpower %d, security %d, max_device %d, " + "ip_address [%s]\n", + set.ssid, set.key, set.channel, set.mode, + set.txpower, set.sec_type, + set.max_connected, set.ip_address); + + if (th->wifi_sharing) + params = __get_wifi_settings_dbus_params("wifi_sharing", &set); + else + params = __get_wifi_settings_dbus_params("wifi_tether", &set); + + g_dbus_proxy_call(proxy, "enable_wifi_tethering", params, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, - (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, + (gpointer)tethering); break; } @@ -1643,35 +1852,41 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_BT_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_bt_tethering", NULL, + g_dbus_proxy_call(proxy, "enable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); break; - case TETHERING_TYPE_RESERVED: { - _softap_settings_t set = {"", "", 0, false}; + case TETHERING_TYPE_P2P: { + _softap_settings_t p2p_set; + memset(&p2p_set, 0, sizeof(_softap_settings_t)); - ret = __prepare_wifi_ap_settings(tethering, &set); + ret = __prepare_wifi_settings(tethering, &p2p_set); if (ret != TETHERING_ERROR_NONE) { - ERR("softap settings initialization failed\n"); + ERR("p2p settings initialization failed\n"); + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + DBG("-\n"); return TETHERING_ERROR_OPERATION_FAILED; } - g_dbus_connection_signal_unsubscribe(connection, - sigs[E_SIGNAL_WIFI_AP_ON].sig_id); - - g_dbus_proxy_call(proxy, "enable_wifi_ap", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), - G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __wifi_ap_enabled_cfm_cb, (gpointer)tethering); + g_dbus_proxy_call(proxy, "enable_p2p_tethering", + g_variant_new("(ssi)", p2p_set.ssid, p2p_set.key, p2p_set.channel), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __p2p_enabled_cfm_cb, (gpointer)tethering); break; } + case TETHERING_TYPE_ALL: { - _softap_settings_t set = {"", "", 0, false}; + GVariant *params = NULL; + _softap_settings_t set; + memset(&set, 0, sizeof(_softap_settings_t)); ret = __prepare_wifi_settings(tethering, &set); if (ret != TETHERING_ERROR_NONE) { ERR("softap settings initialization failed\n"); + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); return TETHERING_ERROR_OPERATION_FAILED; } @@ -1679,7 +1894,8 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_USB_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL, + g_dbus_proxy_call(proxy, "enable_usb_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); @@ -1687,16 +1903,22 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_wifi_tethering", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), + if (th->wifi_sharing) + params = __get_wifi_settings_dbus_params("wifi_sharing", &set); + else + params = __get_wifi_settings_dbus_params("wifi_tether", &set); + + g_dbus_proxy_call(proxy, "enable_wifi_tethering", params, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, - (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, + (gpointer)tethering); /* TETHERING_TYPE_BT */ g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_BT_TETHER_ON].sig_id); - g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL, + g_dbus_proxy_call(proxy, "enable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); break; @@ -1711,10 +1933,164 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) } g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + INFO("-\n"); + return TETHERING_ERROR_NONE; +} + +API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type) +{ + DBG("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; + int ret = 0; + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE); + + if (__check_precondition(th, type) == FALSE) { + DBG("-\n"); + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + return TETHERING_ERROR_OPERATION_FAILED; + } + + switch (type) { + case TETHERING_TYPE_USB: { + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_ON].sig_id); + + g_dbus_proxy_call(proxy, "enable_usb_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); + break; + } + + case TETHERING_TYPE_WIFI: { + GVariant *params = NULL; + _softap_settings_t set; + memset(&set, 0, sizeof(_softap_settings_t)); + + ret = __prepare_wifi_settings(tethering, &set); + if (ret != TETHERING_ERROR_NONE) { + ERR("softap settings initialization failed\n"); + DBG("-\n"); + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + return TETHERING_ERROR_OPERATION_FAILED; + } + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id); + + SINFO("ssid %s, key %s, channel %d, mode %s, txpower %d, security %d max_device %d\n", + set.ssid, set.key, set.channel, set.mode, set.txpower, set.sec_type, + set.max_connected); + + char key[TETHERING_WIFI_KEY_MAX_LEN + 1] = "wifi_tether"; + if (th->wifi_sharing) + g_strlcpy(key, "wifi_sharing", TETHERING_WIFI_KEY_MAX_LEN + 1); + + SINFO("enable_wifi_tethering key: %s", key); + if (th->wifi_sharing) + params = __get_wifi_settings_dbus_params("wifi_sharing", &set); + else + params = __get_wifi_settings_dbus_params("wifi_tether", &set); + + g_dbus_proxy_call(proxy, "enable_wifi_tethering", params, + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, + (gpointer)tethering); + break; + } + + case TETHERING_TYPE_BT: { + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_ON].sig_id); + + g_dbus_proxy_call(proxy, "enable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); + + break; + } + + default: { + ERR("Unknown type : %d\n", type); + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + + DBG("-\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + } + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); DBG("-\n"); return TETHERING_ERROR_NONE; } +API int tethering_ipv6_disable(tethering_h tethering, tethering_type_e type) +{ + DBG("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; + + switch (type) { + case TETHERING_TYPE_USB: + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_usb_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; + + case TETHERING_TYPE_WIFI: + DBG("Disable wifi tethering.."); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_wifi_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; + + case TETHERING_TYPE_BT: + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; + + default: + ERR("Not supported tethering type [%d]\n", type); + DBG("-\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + DBG("-\n"); + return TETHERING_ERROR_NONE; +} /** * @internal * @brief Disables the tethering, asynchronously. @@ -1732,10 +2108,11 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) */ API int tethering_disable(tethering_h tethering, tethering_type_e type) { - DBG("+ type : %d\n", type); - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + INFO("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1750,18 +2127,21 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); g_dbus_proxy_call(proxy, "disable_usb_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; case TETHERING_TYPE_WIFI: - g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); + SINFO("Disable Wi-Fi Tethering !"); + g_dbus_proxy_call(proxy, "disable_wifi_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(ii)", TETHERING_ADDRESS_FAMILY_IPV4, th->mode_type), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; @@ -1771,15 +2151,13 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); g_dbus_proxy_call(proxy, "disable_bt_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; - case TETHERING_TYPE_RESERVED: - g_dbus_connection_signal_unsubscribe(connection, - sigs[E_SIGNAL_WIFI_AP_OFF].sig_id); - - g_dbus_proxy_call(proxy, "disable_wifi_ap", + case TETHERING_TYPE_P2P: + g_dbus_proxy_call(proxy, "disable_p2p_tethering", NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; @@ -1789,21 +2167,24 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); g_dbus_proxy_call(proxy, "disable_usb_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); g_dbus_proxy_call(proxy, "disable_wifi_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); g_dbus_proxy_call(proxy, "disable_bt_tethering", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; @@ -1812,7 +2193,7 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) DBG("-\n"); return TETHERING_ERROR_INVALID_PARAMETER; } - DBG("-\n"); + INFO("-\n"); return TETHERING_ERROR_NONE; } @@ -1828,6 +2209,7 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) */ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) { + INFO("+ type : %d\n", type); int is_on = 0; int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE; @@ -1849,14 +2231,15 @@ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT; break; - case TETHERING_TYPE_RESERVED: - vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP; + case TETHERING_TYPE_P2P: + vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_P2P; break; default: ERR("Not supported type : %d\n", type); break; } + INFO("- enabled: %s\n", (is_on & vconf_type) ? "true" : "false"); return is_on & vconf_type ? true : false; } @@ -1882,9 +2265,10 @@ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) */ API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering_is_enabled(tethering, type) == false, TETHERING_ERROR_NOT_ENABLED, @@ -1950,9 +2334,10 @@ API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, */ API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering_is_enabled(tethering, type) == false, TETHERING_ERROR_NOT_ENABLED, @@ -1997,10 +2382,10 @@ API int tethering_get_network_interface_name(tethering_h tethering, tethering_ty */ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address) { - - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering_is_enabled(tethering, type) == false, TETHERING_ERROR_NOT_ENABLED, @@ -2033,6 +2418,61 @@ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, t _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY, "Not enough memory\n"); + if (type == TETHERING_TYPE_WIFI) { + __tethering_h *th = (__tethering_h *)tethering; + g_strlcpy(th->ip_address, *ip_address, sizeof(th->ip_address)); + } + + return TETHERING_ERROR_NONE; +} + +/** + * @brief Sets the local IP address. + * @since_tizen 6.5 + * @privlevel platform + * @privilege %http://tizen.org/privilege/tethering.admin + * @remarks API is only available for TETHERING_TYPE_WIFI. + * @param[in] tethering The tethering handle + * @param[in] type The tethering type + * @param[in] address_family The address family of IP address (currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported) + * @param[out] ip_address The local IP address + * @return 0 on success, otherwise negative error value + * @retval #TETHERING_ERROR_NONE Successful + * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #TETHERING_ERROR_OUT_OF_MEMORY Out of memory + * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed + * @see tethering_enable() + */ +int tethering_set_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, const char *ip_address) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_WIFI) + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else + return TETHERING_ERROR_INVALID_PARAMETER; + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(ip_address) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + int ip_len = 0; + + if (address_family == TETHERING_ADDRESS_FAMILY_IPV4) { + ip_len = strlen(ip_address); + if (ip_len < TETHERING_IPV4_ADDRESS_MIN_LEN || + ip_len > TETHERING_IPV4_ADDRESS_MAX_LEN) { + ERR("parameter(ip_address) is too short or long\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + g_strlcpy(th->ip_address, ip_address, sizeof(th->ip_address)); + } else { + /* IPv6 is not supported yet. */ + ERR("IPv6 address is not supported yet\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + return TETHERING_ERROR_NONE; } @@ -2059,26 +2499,34 @@ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, t */ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); - - _retvm_if(tethering_is_enabled(tethering, type) == false, - TETHERING_ERROR_NOT_ENABLED, - "tethering type[%d] is not enabled\n", type); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(gateway_address) is NULL\n"); + _retvm_if(tethering_is_enabled(tethering, type) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", type); + + __tethering_h *th = (__tethering_h *)tethering; - char gateway_buf[TETHERING_STR_INFO_LEN] = {0, }; + if (type == TETHERING_TYPE_WIFI && strlen(th->ip_address)) { + *gateway_address = strdup(th->ip_address); - _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)), - TETHERING_ERROR_OPERATION_FAILED, - "getting gateway address is failed\n"); + } else { + char gateway_buf[TETHERING_STR_INFO_LEN] = {0, }; + + _retvm_if(!__get_gateway_addr(type, gateway_buf, + sizeof(gateway_buf)), + TETHERING_ERROR_OPERATION_FAILED, + "getting gateway address is failed\n"); - *gateway_address = strdup(gateway_buf); + *gateway_address = strdup(gateway_buf); + } return TETHERING_ERROR_NONE; } @@ -2106,9 +2554,10 @@ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e ty */ API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering_is_enabled(tethering, type) == false, TETHERING_ERROR_NOT_ENABLED, @@ -2185,28 +2634,19 @@ API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb * @see tethering_is_enabled() * @see tethering_enable() */ -API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data) + +API int tethering_is_dualband_supported(tethering_h tethering, tethering_type_e type, bool *supported) { - DBG("+\n"); - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(callback) is NULL\n"); - _retvm_if(__any_tethering_is_enabled(tethering) == false, - TETHERING_ERROR_NOT_ENABLED, - "tethering is not enabled\n"); - mobile_ap_type_e interface; __tethering_h *th = (__tethering_h *)tethering; - __tethering_client_h client = {0, }; - gchar *ip = NULL; - gchar *mac = NULL; - gchar *hostname = NULL; - guint timestamp = 0; + gchar *if_name = NULL; + gboolean Is2GBandSupported = FALSE; + gboolean Is5GBandSupported = FALSE; GError *error = NULL; GVariant *result = NULL; GVariantIter *outer_iter = NULL; @@ -2214,39 +2654,115 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ GVariant *station = NULL; GVariant *value = NULL; gchar *key = NULL; + int count = 0; - result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info", - NULL, G_DBUS_CALL_FLAGS_NONE, - -1, th->cancellable, &error); - if (error) + DBG("+"); + __reset_dualband_support(); + result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_wifi_interfaces", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_error_free(error); + return TETHERING_ERROR_OPERATION_FAILED; + } g_variant_get(result, "(a(a{sv}))", &outer_iter); while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) { g_variant_get(station, "a{sv}", &inner_iter); while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) { - if (g_strcmp0(key, "Type") == 0) { - interface = g_variant_get_int32(value); - if (interface == MOBILE_AP_TYPE_USB) - client.interface = TETHERING_TYPE_USB; - else if (interface == MOBILE_AP_TYPE_WIFI) - client.interface = TETHERING_TYPE_WIFI; - else if (interface == MOBILE_AP_TYPE_BT) - client.interface = TETHERING_TYPE_BT; - else if (interface == MOBILE_AP_TYPE_WIFI_AP) - client.interface = TETHERING_TYPE_RESERVED; - else { - ERR("Invalid interface\n"); - g_free(key); - g_variant_unref(value); - break; - } - DBG("interface is %d\n", client.interface); - if (client.interface != type && (TETHERING_TYPE_ALL != type && - client.interface != TETHERING_TYPE_RESERVED)) { - g_free(key); - g_variant_unref(value); - break; - } + if (g_strcmp0(key, "IfName") == 0) { + g_variant_get(value, "s", &if_name); + SDBG("Interface Name is %s\n", if_name); + } else if (g_strcmp0(key, "Is2GBandSupported") == 0) { + Is2GBandSupported = g_variant_get_boolean(value); + SDBG("Is2GBandSupported is %d\n", Is2GBandSupported); + if (Is2GBandSupported) + __set_dualband_support(DUAL_BAND_2G); + } else if (g_strcmp0(key, "Is5GBandSupported") == 0) { + Is5GBandSupported = g_variant_get_boolean(value); + SDBG("Is5GBandSupported is %d\n", Is5GBandSupported); + if (Is5GBandSupported) + __set_dualband_support(DUAL_BAND_5G); + } else { + ERR("Key %s not required\n", key); + } + } + count++; + + g_variant_iter_free(inner_iter); + } + if (count >= 2) + __set_dualband_support(DUAL_BAND_MIN_INTERFACE); + *supported = __is_dualband_support(); + DBG("count:%d is dualband suppport: %d", count, *supported); + g_variant_iter_free(outer_iter); + g_variant_unref(result); + DBG("-\n"); + return TETHERING_ERROR_NONE; +} +API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(callback) is NULL\n"); + _retvm_if(__any_tethering_is_enabled(tethering) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering is not enabled\n"); + + mobile_ap_type_e interface; + tethering_band_e band; + __tethering_h *th = (__tethering_h *)tethering; + __tethering_client_h client = {0, }; + gchar *ip = NULL; + gchar *mac = NULL; + gchar *hostname = NULL; + guint timestamp = 0; + GError *error = NULL; + GVariant *result = NULL; + GVariantIter *outer_iter = NULL; + GVariantIter *inner_iter = NULL; + GVariant *station = NULL; + GVariant *value = NULL; + gchar *key = NULL; + + result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info", + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_error_free(error); + return TETHERING_ERROR_OPERATION_FAILED; + } + + g_variant_get(result, "(a(a{sv}))", &outer_iter); + while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) { + g_variant_get(station, "a{sv}", &inner_iter); + while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "Type") == 0) { + interface = g_variant_get_int32(value); + tethering_type_e converted_type = __convert_to_tethering_type(interface); + if (converted_type == TETHERING_TYPE_MAX) { + ERR("Invalid interface\n"); + g_free(key); + g_variant_unref(value); + break; + } else { + client.interface = converted_type; + } + + DBG("interface is %d\n", client.interface); + if (client.interface != type && (TETHERING_TYPE_ALL != type)) { + g_free(key); + g_variant_unref(value); + break; + } } else if (g_strcmp0(key, "IP") == 0) { g_variant_get(value, "s", &ip); SDBG("ip is %s\n", ip); @@ -2264,6 +2780,10 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ timestamp = g_variant_get_int32(value); DBG("timestamp is %d\n", timestamp); client.tm = (time_t)timestamp; + } else if (g_strcmp0(key, "Band") == 0) { + band = g_variant_get_int32(value); + client.band = (!band) ? TETHERING_WIFI_BAND_2G : TETHERING_WIFI_BAND_5G; + SDBG("band type %d\n", band); } else { ERR("Key %s not required\n", key); } @@ -2271,20 +2791,30 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ g_free(hostname); g_free(ip); g_free(mac); + + hostname = NULL; + ip = NULL; + mac = NULL; + g_variant_iter_free(inner_iter); + if ((th->mode_type == 0 || th->mode_type == 1) && client.band != TETHERING_WIFI_BAND_2G) //if band is not for 2g continue + continue; + if ((th->mode_type == 2 || th->mode_type == 3) && client.band != TETHERING_WIFI_BAND_5G) //if band is not for 5g continue + continue; + SDBG("mode_type: %d and client.band: %d ", th->mode_type, client.band); if (callback((tethering_client_h)&client, user_data) == false) { DBG("iteration is stopped\n"); g_free(client.hostname); + client.hostname = NULL; g_variant_iter_free(outer_iter); - g_variant_unref(station); g_variant_unref(result); DBG("-\n"); return TETHERING_ERROR_OPERATION_FAILED; } g_free(client.hostname); + client.hostname = NULL; } g_variant_iter_free(outer_iter); - g_variant_unref(station); g_variant_unref(result); DBG("-\n"); return TETHERING_ERROR_NONE; @@ -2306,9 +2836,11 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ */ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2326,11 +2858,12 @@ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, t } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->enabled_cb[ti] = callback; th->enabled_user_data[ti] = user_data; } + INFO("-\n"); return TETHERING_ERROR_NONE; } @@ -2348,9 +2881,10 @@ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, t */ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2366,7 +2900,7 @@ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->enabled_cb[ti] = NULL; th->enabled_user_data[ti] = NULL; } @@ -2390,9 +2924,11 @@ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) */ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2410,11 +2946,11 @@ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->disabled_cb[ti] = callback; th->disabled_user_data[ti] = user_data; } - + INFO("-\n"); return TETHERING_ERROR_NONE; } @@ -2432,9 +2968,10 @@ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, */ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2450,7 +2987,7 @@ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->disabled_cb[ti] = NULL; th->disabled_user_data[ti] = NULL; } @@ -2474,9 +3011,11 @@ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type */ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2494,11 +3033,11 @@ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tetheri } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->changed_cb[ti] = callback; th->changed_user_data[ti] = user_data; } - + INFO("-\n"); return TETHERING_ERROR_NONE; } @@ -2516,9 +3055,10 @@ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tetheri */ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type) { - if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE); - else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); - else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2534,7 +3074,7 @@ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethe } /* TETHERING_TYPE_ALL */ - for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) { + for (ti = TETHERING_TYPE_USB; ti < TETHERING_TYPE_MAX; ti++) { th->changed_cb[ti] = NULL; th->changed_user_data[ti] = NULL; } @@ -2557,7 +3097,8 @@ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethe */ API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2587,7 +3128,8 @@ API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethe */ API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2615,7 +3157,8 @@ API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering) */ API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2643,7 +3186,8 @@ API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tet */ API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2671,7 +3215,8 @@ API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering) */ API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2699,7 +3244,8 @@ API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tetherin */ API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2729,22 +3275,35 @@ API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering) */ API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; tethering_error_e ret = TETHERING_ERROR_NONE; + char *sec_str = NULL; ret = __set_security_type(type); if (ret == TETHERING_ERROR_NONE) { + switch (type) { + case TETHERING_WIFI_SECURITY_TYPE_NONE: + sec_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR; + break; + case TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK: + sec_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR; + break; + case TETHERING_WIFI_SECURITY_TYPE_WPS: + sec_str = TETHERING_WIFI_SECURITY_TYPE_WPS_STR; + break; + case TETHERING_WIFI_SECURITY_TYPE_SAE: + sec_str = TETHERING_WIFI_SECURITY_TYPE_SAE_STR; + break; + } __send_dbus_signal(th->client_bus, - SIGNAL_NAME_SECURITY_TYPE_CHANGED, - type == TETHERING_WIFI_SECURITY_TYPE_NONE ? - TETHERING_WIFI_SECURITY_TYPE_OPEN_STR : - TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR); + SIGNAL_NAME_SECURITY_TYPE_CHANGED, sec_str); } return ret; } @@ -2765,8 +3324,11 @@ API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_s */ API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(type) is NULL\n"); @@ -2790,7 +3352,8 @@ API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_s */ API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2811,6 +3374,36 @@ API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid) _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY, "strdup is failed\n"); +#ifdef TIZEN_TV_EXT + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters; + GError *error = NULL; + tethering_error_e ret = TETHERING_ERROR_NONE; + + parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_ssid", + g_variant_new("(s)", ssid), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + free(p_ssid); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + } + + SINFO("set tethering ssid : %s", ssid); +#endif /* TIZEN_TV_EXT */ + if (th->ssid) free(th->ssid); th->ssid = p_ssid; @@ -2835,7 +3428,8 @@ API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid) */ API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2846,6 +3440,15 @@ API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid) __tethering_h *th = (__tethering_h *)tethering; char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, }; +#ifdef TIZEN_TV_EXT + if (__get_ssid_from_vconf(VCONFKEY_WIFI_SSID, + val, sizeof(val)) == true) { + *ssid = strdup(val); + SINFO("get tethering ssid : %s", *ssid); + return TETHERING_ERROR_NONE; + } +#endif /* TIZEN_TV_EXT */ + if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) { if (th->ssid != NULL) { DBG("Private SSID is set\n"); @@ -2891,7 +3494,8 @@ API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid) */ API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -2901,7 +3505,6 @@ API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) ret = __set_visible(visible); if (ret == TETHERING_ERROR_NONE) { - __send_dbus_signal(th->client_bus, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, visible ? SIGNAL_MSG_SSID_VISIBLE : @@ -2927,8 +3530,11 @@ API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) */ API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(visible) is NULL\n"); @@ -2952,7 +3558,8 @@ API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible) */ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -3019,7 +3626,8 @@ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphr */ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -3056,6 +3664,141 @@ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) return TETHERING_ERROR_NONE; } +API int tethering_wifi_set_channel(tethering_h tethering, int channel) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + +#ifdef TIZEN_TV_EXT + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters; + GError *error = NULL; + tethering_error_e ret = TETHERING_ERROR_NONE; + + parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_channel", + g_variant_new("(i)", channel), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + } + + SINFO("set channel : %d", channel); +#endif /* TIZEN_TV_EXT */ + + th->channel = channel; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_channel(tethering_h tethering, int *channel) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(channel) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; +#ifdef TIZEN_TV_EXT + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters = NULL; + GError *error = NULL; + int ch = -1; + int vconf_channel = -1; + tethering_error_e ret = TETHERING_ERROR_NONE; + + parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_channel", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(iu)", &ch, &ret); + g_variant_unref(parameters); + } + + if (ch < 0) { + ERR("failed to get Hostapd channel, set th->channel"); + *channel = th->channel; + } else + *channel = ch; + + if (vconf_get_int(VCONFKEY_WIFI_CHANNEL, &vconf_channel) < 0) + ERR("Failed to get vconf key for channel"); + else + *channel = vconf_channel; + + SINFO("get tethering channel : %d", *channel); +#else /* TIZEN_TV_EXT */ + *channel = th->channel; +#endif /* TIZEN_TV_EXT */ + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + th->mode_type = type; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(type) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *type = th->mode_type; + + return TETHERING_ERROR_NONE; +} + + /** * @internal * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility). @@ -3074,7 +3817,8 @@ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -3082,10 +3826,12 @@ API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_set "parameter(callback) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - _softap_settings_t set = {"", "", 0, false}; + _softap_settings_t set; GDBusProxy *proxy = th->client_bus_proxy; int ret = 0; + memset(&set, 0, sizeof(_softap_settings_t)); + DBG("+\n"); if (th->settings_reloaded_cb) { @@ -3102,333 +3848,1075 @@ API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_set th->settings_reloaded_cb = callback; th->settings_reloaded_user_data = user_data; + SINFO("ssid %s, key %s, channel %d, mode %s, txpower %d, security %d max_device %d\n", + set.ssid, set.key, set.channel, set.mode, set.txpower, set.sec_type, + set.max_connected); + g_dbus_proxy_call(proxy, "reload_wifi_settings", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), + g_variant_new("(sssiiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type, set.txpower), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering); return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Sets the security type of Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If security type is not set, WPA2_PSK is used - * @param[in] tethering The handle of tethering - * @param[in] type The security type - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed - * @see tethering_wifi_ap_get_security_type() - */ -API int tethering_wifi_ap_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type) +API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - th->sec_type = type; + th->mac_filter = mac_filter; + return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Gets the security type of Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If security type is not set, WPA2_PSK is used - * @param[in] tethering The handle of tethering - * @param[out] type The security type - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @see tethering_wifi_ap_set_security_type() - */ -API int tethering_wifi_ap_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type) +API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); - _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(type) is NULL\n"); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac_filter) is NULL\n"); + _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac_filter) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; + *mac_filter = th->mac_filter; - *type = th->sec_type; return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Sets the SSID (service set identifier) for Wi-Fi AP. The SSID cannot exceed 32 bytes. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If SSID is not set, Device name is used as SSID - * @param[in] tethering The handle of tethering - * @param[in] ssid The SSID - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OUT_OF_MEMORY Out of memory - */ -API int tethering_wifi_ap_set_ssid(tethering_h tethering, const char *ssid) +static int __add_mac_to_file(const char *filepath, const char *mac) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + FILE *fp = NULL; + char line[MAX_BUF_SIZE] = "\0"; + bool mac_exist = false; + char *p_mac = NULL; + + fp = fopen(filepath, "a+"); + if (!fp) { + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } - _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); - _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(ssid) is NULL\n"); + while (fgets(line, MAX_BUF_SIZE, fp) != NULL) { + if (strncmp(mac, line, 17) == 0) { + DBG("MAC %s already exist in the list\n", mac); + mac_exist = true; + break; + } + } - __tethering_h *th = (__tethering_h *)tethering; - char *p_ssid = NULL; - int ssid_len = 0; + if (!mac_exist) { + p_mac = strdup(mac); + if (p_mac == NULL) { + ERR("strdup failed\n"); + fclose(fp); + return TETHERING_ERROR_OUT_OF_MEMORY; + } - ssid_len = strlen(ssid); - if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) { - ERR("parameter(ssid) is too long"); - return TETHERING_ERROR_INVALID_PARAMETER; - } + fprintf(fp, "%s\n", mac); - p_ssid = strdup(ssid); - if (p_ssid == NULL) { - ERR("strdup failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; + if ((strcmp(filepath, ALLOWED_LIST) == 0)) + allowed_list = g_slist_append(allowed_list, p_mac); + else if ((strcmp(filepath, BLOCKED_LIST) == 0)) + blocked_list = g_slist_append(blocked_list, p_mac); + else + free(p_mac); } - if (th->ap_ssid) - g_free(th->ap_ssid); - th->ap_ssid = p_ssid; + fclose(fp); return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Gets the SSID (service set identifier) for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If SSID is not set, Device name is used as SSID - * @remarks @a ssid must be released with free() by you. - * @param[in] tethering The handle of tethering - * @param[out] ssid The SSID - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OUT_OF_MEMORY Out of memory - */ -API int tethering_wifi_ap_get_ssid(tethering_h tethering, char **ssid) +static int __remove_mac_from_file(const char *filepath, const char *mac) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + FILE *fp = NULL; + FILE *fp1 = NULL; + char line[MAX_BUF_SIZE] = "\0"; - _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); - _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(ssid) is NULL\n"); + fp = fopen(filepath, "r"); + if (!fp) { + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } - __tethering_h *th = (__tethering_h *)tethering; + fp1 = fopen(TEMP_LIST, "w+"); + if (!fp1) { + fclose(fp); + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } - *ssid = g_strdup(th->ap_ssid); - if (*ssid == NULL) { - ERR("strdup failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; + while (fgets(line, MAX_BUF_SIZE, fp) != NULL) { + if (strncmp(mac, line, 17) == 0) { + DBG("MAC %s found in the list\n", mac); + + if ((strcmp(filepath, ALLOWED_LIST) == 0)) { + GSList *list = NULL; + for (list = allowed_list; list != NULL; list = list->next) { + char *p_mac = (char *)list->data; + if (strncmp(mac, p_mac, strlen(mac)) == 0) + allowed_list = g_slist_remove(allowed_list, p_mac); + } + } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) { + GSList *list = NULL; + for (list = blocked_list; list != NULL; list = list->next) { + char *p_mac = (char *)list->data; + if (strncmp(mac, p_mac, strlen(mac)) == 0) + blocked_list = g_slist_remove(blocked_list, p_mac); + } + } + } else { + fprintf(fp1, "%s", line); + } + } + + fclose(fp); + fclose(fp1); + + if ((strcmp(filepath, ALLOWED_LIST) == 0)) { + if (rename(TEMP_LIST, ALLOWED_LIST) != 0) { + ERR("rename is failed (%s -> %s)", TEMP_LIST, ALLOWED_LIST); + return TETHERING_ERROR_OPERATION_FAILED; + } + } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) { + if (rename(TEMP_LIST, BLOCKED_LIST) != 0) { + ERR("rename is failed (%s -> %s)", TEMP_LIST, BLOCKED_LIST); + return TETHERING_ERROR_OPERATION_FAILED; + } } return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Sets the visibility of SSID(service set identifier) for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device. - * @details by default visibility is set to true. - * @remarks This change is applied next time Wi-Fi tethering is enabled - * @param[in] tethering The handle of tethering - * @param[in] visible The visibility of SSID: (@c true = visible, @c false = invisible) - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed - * @see tethering_wifi_ap_get_ssid_visibility() - */ -API int tethering_wifi_ap_set_ssid_visibility(tethering_h tethering, bool visible) +API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); - __tethering_h *th = (__tethering_h *)tethering; - th->visibility = visible; - return TETHERING_ERROR_NONE; + return __add_mac_to_file(ALLOWED_LIST, mac); } -/** - * @internal - * @brief Gets the visibility of SSID(service set identifier) for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device. - * @details by default visibility is set to true. - * @param[in] tethering The handle of tethering - * @param[out] visible The visibility of SSID: (@c true = visible, @c false = invisible) - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @see tethering_wifi_ap_set_ssid_visibility() - */ -API int tethering_wifi_ap_get_ssid_visibility(tethering_h tethering, bool *visible) +API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); - _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(visible) is NULL\n"); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); - __tethering_h *th = (__tethering_h *)tethering; + return __remove_mac_from_file(ALLOWED_LIST, mac); +} + +API int tethering_wifi_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(allowed_mac_list) is NULL\n"); - *visible = th->visibility; + *allowed_mac_list = g_slist_copy(allowed_list); return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Sets the passphrase for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If the passphrase is not set, random string of 8 alphabets will be used. - * @param[in] tethering The handle of tethering - * @param[in] passphrase The passphrase - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @see tethering_wifi_ap_get_passphrase() - */ -API int tethering_wifi_ap_set_passphrase(tethering_h tethering, const char *passphrase) +API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); - _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(passphrase) is NULL\n"); + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); - __tethering_h *th = (__tethering_h *)tethering; - int passphrase_len = 0; + return __add_mac_to_file(BLOCKED_LIST, mac); +} - passphrase_len = strlen(passphrase); +API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); - if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN || - passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) { - ERR("parameter(passphrase) is too short or long\n"); - return TETHERING_ERROR_INVALID_PARAMETER; - } + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); - if (!g_strcmp0(passphrase, th->passphrase)) - return TETHERING_ERROR_NONE; + return __remove_mac_from_file(BLOCKED_LIST, mac); +} + +API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); - g_strlcpy(th->passphrase, passphrase, sizeof(th->passphrase)); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(blocked_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(blocked_mac_list) is NULL\n"); + + *blocked_mac_list = g_slist_copy(blocked_list); return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Gets the passphrase for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @details If the passphrase is not set, random string of 8 alphabets will be used. - * @remarks @a passphrase must be released with free() by you. - * @param[in] tethering The handle of tethering - * @param[out] passphrase The passphrase - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OUT_OF_MEMORY Out of memory - * @see tethering_wifi_ap_set_passphrase() - */ -API int tethering_wifi_ap_get_passphrase(tethering_h tethering, char **passphrase) +API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(passphrase) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; __tethering_h *th = (__tethering_h *)tethering; - *passphrase = g_strdup(th->passphrase); - if (*passphrase == NULL) { - ERR("strdup is failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "enable_dhcp", + g_variant_new("(b)", enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + th->dhcp_enabled = false; + + return result; } + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + if (enable) + th->dhcp_enabled = true; + else + th->dhcp_enabled = false; + return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility) for Wi-Fi AP. - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @remarks Connected devices via MobileAP will be disconnected when the settings are reloaded - * @param[in] tethering The handle of tethering - * @param[in] callback The callback function to invoke - * @param[in] user_data The user data to be passed to the callback function - * @return 0 on success, otherwise negative error value. - * @retval #TETHERING_ERROR_NONE Successful - * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed - */ -API int tethering_wifi_ap_reload_settings(tethering_h tethering, tethering_wifi_ap_settings_reloaded_cb callback, void *user_data) - +API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop) { - CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(callback) is NULL\n"); + _retvm_if(rangestart == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(rangestart) is NULL\n"); + _retvm_if(rangestop == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(rangestop) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; __tethering_h *th = (__tethering_h *)tethering; - _softap_settings_t set = {"", "", 0, false}; + GDBusProxy *proxy = th->client_bus_proxy; - int ret = 0; - DBG("+\n"); + parameters = g_dbus_proxy_call_sync(proxy, "dhcp_range", + g_variant_new("(ss)", rangestart, rangestop), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); - if (th->ap_settings_reloaded_cb) { - ERR("Operation in progress\n"); - return TETHERING_ERROR_OPERATION_FAILED; - } + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; - ret = __prepare_wifi_ap_settings(tethering, &set); - if (ret != TETHERING_ERROR_NONE) { - ERR("softap settings initialization failed\n"); - return TETHERING_ERROR_OPERATION_FAILED; + g_error_free(error); + th->dhcp_enabled = false; + + return result; } - th->ap_settings_reloaded_cb = callback; - th->ap_settings_reloaded_user_data = user_data; + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + th->dhcp_enabled = true; - g_dbus_proxy_call(proxy, "reload_wifi_ap_settings", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), - G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, - (GAsyncReadyCallback) __ap_settings_reloaded_cb, (gpointer)tethering); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(dhcp_enabled) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *dhcp_enabled = th->dhcp_enabled; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_txpower(tethering_h tethering, unsigned int txpower) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + GError *error = NULL; + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI); + __tethering_h *th = (__tethering_h *)tethering; + th->txpower = txpower; + + g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_set_txpower", + g_variant_new("(u)", txpower), + G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + if (error) { + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_clear_error(&error); + return TETHERING_ERROR_OPERATION_FAILED; + } + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_txpower(tethering_h tethering, unsigned int *txpower) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + GError *error = NULL; + GVariant *result = NULL; + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(txpower == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(txpower) is NULL\n"); + _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI); + + __tethering_h *th = (__tethering_h *)tethering; + + result = g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_get_txpower", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + + if (result != NULL) { + g_variant_get(result, "(u)", txpower); + g_variant_unref(result); + } else { + if (error) + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_clear_error(&error); + return TETHERING_ERROR_OPERATION_FAILED; + } + g_clear_error(&error); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_mtu(tethering_h tethering, unsigned int mtu) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "set_mtu", + g_variant_new("(u)", mtu), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + + g_variant_unref(parameters); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_change_mac(tethering_h tethering, char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "change_mac", + g_variant_new("(s)", mac), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + if (result == MOBILE_AP_ERROR_NOT_PERMITTED) + return TETHERING_ERROR_NOT_SUPPORT_API; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + th->wifi_max_connected = max_device; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_max_connected_device(tethering_h tethering, int *max_device) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(max_device == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(max_device) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + *max_device = th->wifi_max_connected; + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_enable_port_forwarding(tethering_h tethering, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "enable_port_forwarding", + g_variant_new("(b)", enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + th->port_forwarding = true; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_port_forwarding_rule(tethering_h tethering, char *ifname, char *protocol, char *org_ip, int org_port, char *final_ip, int final_port) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(ifname == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(ifname) is NULL\n"); + _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(protocol) is NULL\n"); + _retvm_if(org_ip == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(org_ip) is NULL\n"); + _retvm_if(final_ip == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(final_ip) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + char cmd[MAX_BUF_SIZE] = { 0, }; + char *list = NULL; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "add_port_forwarding_rule", + g_variant_new("(sssisi)", ifname, protocol, org_ip, org_port, final_ip, final_port), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + snprintf(cmd, sizeof(cmd), "%s "PORT_FORWARD_RULE_STR, IPTABLES, TABLE_NAT, TETH_NAT_PRE, ifname, protocol, org_ip, org_port, final_ip, final_port); + + list = strdup(cmd); + if (list == NULL) { + ERR("strdup failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } + + port_forwarding = g_slist_append(port_forwarding, list); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_reset_port_forwarding_rule(tethering_h tethering) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "reset_port_forwarding_rule", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + + g_variant_unref(parameters); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_port_forwarding_enabled(tethering_h tethering, bool *forwarding_enabled) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(forwarding_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(forwarding_enabled) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + *forwarding_enabled = th->port_forwarding; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_port_forwarding_rule(tethering_h tethering, void **port_forwarding_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(port_forwarding_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(port_forwarding_list) is NULL\n"); + + *port_forwarding_list = g_slist_copy(port_forwarding); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_enable_port_filtering(tethering_h tethering, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "enable_port_filtering", + g_variant_new("(b)", enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + th->port_filtering = true; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_port_filtering_rule(tethering_h tethering, int port, char *protocol, bool allow) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(protocol) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + char *list = NULL; + int ret; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "add_port_filtering_rule", + g_variant_new("(isb)", port, protocol, allow), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + if (allow) + ret = asprintf(&list, "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_ACCEPT); + else + ret = asprintf(&list, "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_DROP); + + if (ret == -1 || list == NULL) { + ERR("asprintf failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } + + DBG("cmd:%s", list); + + port_filtering = g_slist_append(port_filtering, list); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_custom_port_filtering_rule(tethering_h tethering, int port1, int port2, char *protocol, bool allow) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(protocol) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + char *list = NULL; + int ret; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "add_custom_port_filtering_rule", + g_variant_new("(iisb)", port1, port2, protocol, allow), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + if (allow) + ret = asprintf(&list, "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_ACCEPT); + else + ret = asprintf(&list, "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_DROP); + + if (ret == -1 || list == NULL) { + ERR("asprintf failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } + + DBG("cmd:%s", list); + + custom_port_filtering = g_slist_append(custom_port_filtering, list); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_port_filtering_rule(tethering_h tethering, void **port_filtering_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(port_filtering_list) is NULL\n"); + + *port_filtering_list = g_slist_copy(port_filtering); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_custom_port_filtering_rule(tethering_h tethering, void **custom_port_filtering_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(custom_port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(custom_port_filtering_list) is NULL\n"); + + *custom_port_filtering_list = g_slist_copy(custom_port_filtering); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_port_filtering_enabled(tethering_h tethering, bool *filtering_enabled) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(filtering_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(filtering_enabled) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + *filtering_enabled = th->port_filtering; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_vpn_passthrough_rule(tethering_h tethering, tethering_vpn_passthrough_type_e type, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "set_vpn_passthrough_rule", + g_variant_new("(ib)", type, enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + + g_variant_unref(parameters); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_push_wps_button(tethering_h tethering) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL"); + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters = NULL; + int ret = 0; + GError *error = NULL; + + parameters = g_dbus_proxy_call_sync(proxy, "push_wps_button", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + } + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_wps_pin(tethering_h tethering, const char *wps_pin) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL"); + _retvm_if(wps_pin == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(wps_pin) is NULL"); + + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters = NULL; + int ret = 0; + GError *error = NULL; + + parameters = g_dbus_proxy_call_sync(proxy, "set_wps_pin", + g_variant_new("(s)", wps_pin), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + } + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_sharing_supported(tethering_h tethering, bool *supported) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(supported == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(supported) is NULL\n"); + + /** Check if wifi-sharing is supported */ + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + + int ret = TETHERING_ERROR_NONE; + int count = 0; + gchar *key = NULL; + GVariant *value = NULL; + GVariantIter *iter = NULL; + GVariantIter *sub_iter = NULL; + GVariant *parameters = NULL; + GError *error = NULL; + + parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_interfaces", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + goto error; + } + + g_variant_get(parameters, "(a(a{sv}))", &iter); + if (iter == NULL) { + g_variant_unref(parameters); + ret = TETHERING_ERROR_OPERATION_FAILED; + goto error; + } + + while (g_variant_iter_loop(iter, "(a{sv})", &sub_iter)) { + while (g_variant_iter_loop(sub_iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "IfName") == 0) { + const gchar *interface = g_variant_get_string(value, NULL); + ERR("interface: %s\n", interface); + if (strncmp(interface, "wlan", 4) == 0) + count++; + } + } + } + g_variant_unref(parameters); + + if (count > 1) + *supported = true; + else + *supported = false; + +error: + return ret; +} + +API int tethering_wifi_set_sharing(tethering_h tethering, bool sharing) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + th->wifi_sharing = sharing; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_sharing(tethering_h tethering, bool *sharing) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(sharing == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(sharing) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *sharing = th->wifi_sharing; return TETHERING_ERROR_NONE; }