X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftethering.c;h=e5ecc9ba24f43aa63136004a4d408e44c10df868;hb=baaf70c786a3ebf82e468d936b7bbc512b1689b6;hp=f51ccd22c95adc997fb34df5f246bad6a376885e;hpb=ce505f061bab7bf327105c640e7a5896dd0c210a;p=platform%2Fcore%2Fapi%2Ftethering.git diff --git a/src/tethering.c b/src/tethering.c index f51ccd2..e5ecc9b 100755 --- a/src/tethering.c +++ b/src/tethering.c @@ -29,8 +29,32 @@ #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 + +#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" + +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 +79,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,8 +119,6 @@ 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}, @@ -119,7 +133,7 @@ static int retry = 0; static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, const char *arg) { if (conn == NULL || signal_name == NULL) - return; + return; //LCOV_EXCL_LINE GVariant *message = NULL; GError *error = NULL; @@ -130,8 +144,8 @@ static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, c g_dbus_connection_emit_signal(conn, NULL, TETHERING_SERVICE_OBJECT_PATH, TETHERING_SERVICE_INTERFACE, signal_name, message, &error); if (error) { - ERR("g_dbus_connection_emit_signal is failed because %s\n", error->message); - g_error_free(error); + ERR("g_dbus_connection_emit_signal is failed because %s\n", error->message); //LCOV_EXCL_LINE + g_error_free(error); //LCOV_EXCL_LINE } g_variant_unref(message); } @@ -140,8 +154,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_BT)) return true; return false; @@ -150,7 +163,8 @@ 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) { ERR("Invalid param\n"); return TETHERING_ERROR_INVALID_PARAMETER; } @@ -258,9 +272,11 @@ static tethering_error_e __get_error(int agent_error) err = TETHERING_ERROR_NONE; break; + //LCOV_EXCL_START case MOBILE_AP_ERROR_RESOURCE: err = TETHERING_ERROR_OUT_OF_MEMORY; break; + //LCOV_EXCL_STOP case MOBILE_AP_ERROR_INTERNAL: err = TETHERING_ERROR_OPERATION_FAILED; @@ -294,6 +310,7 @@ static tethering_error_e __get_error(int agent_error) err = TETHERING_ERROR_OPERATION_FAILED; break; + //LCOV_EXCL_START case MOBILE_AP_ERROR_NOT_PERMITTED: err = TETHERING_ERROR_NOT_PERMITTED; break; @@ -301,8 +318,8 @@ static tethering_error_e __get_error(int agent_error) case MOBILE_AP_ERROR_PERMISSION_DENIED: err = TETHERING_ERROR_PERMISSION_DENIED; break; - - default: + //LCOV_EXCL_STOP + default : ERR("Not defined error : %d\n", agent_error); err = TETHERING_ERROR_OPERATION_FAILED; break; @@ -311,6 +328,7 @@ static tethering_error_e __get_error(int agent_error) return err; } +//LCOV_EXCL_START 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) @@ -350,9 +368,7 @@ static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name, 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 { + else { ERR("Not supported tethering type [%d]\n", ap_type); goto DONE; } @@ -378,7 +394,9 @@ DONE: g_free(name); DBG("-\n"); } +//LCOV_EXCL_STOP +//LCOV_EXCL_START 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) @@ -404,6 +422,7 @@ static void __handle_net_closed(GDBusConnection *connection, const gchar *sender DBG("-\n"); } +//LCOV_EXCL_STOP static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, @@ -459,6 +478,7 @@ static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *s DBG("-\n"); } +//LCOV_EXCL_START static void __handle_usb_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) @@ -510,6 +530,7 @@ static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *se g_free(buf); DBG("-\n"); } +//LCOV_EXCL_STOP static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, @@ -565,60 +586,7 @@ static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sen DBG("-\n"); } -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) -{ - 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); - DBG("-\n"); -} - -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) -{ - 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); - - DBG("-\n"); -} - +//LCOV_EXCL_START 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) @@ -658,7 +626,7 @@ static void __handle_low_battery_mode(GDBusConnection *connection, const gchar * void *data = NULL; tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY; - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_RESERVED; type++) { + for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { dcb = th->disabled_cb[type]; if (dcb == NULL) continue; @@ -683,7 +651,7 @@ static void __handle_flight_mode(GDBusConnection *connection, const gchar *sende void *data = NULL; tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE; - for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_RESERVED; type++) { + for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { dcb = th->disabled_cb[type]; if (dcb == NULL) continue; @@ -693,6 +661,7 @@ static void __handle_flight_mode(GDBusConnection *connection, const gchar *sende } DBG("-\n"); } +//LCOV_EXCL_STOP static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, @@ -719,6 +688,8 @@ 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 { SERR("Unknown type : %s\n", buf); g_free(buf); @@ -797,6 +768,7 @@ static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { + //LCOV_EXCL_START ERR("DBus error [%s]\n", g_error->message); if (g_error->code == G_DBUS_ERROR_NO_REPLY && ++retry < TETHERING_ERROR_RECOVERY_MAX) { @@ -808,6 +780,7 @@ static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, else error = TETHERING_ERROR_OPERATION_FAILED; g_error_free(g_error); + //LCOV_EXCL_STOP } else { g_variant_get(g_var, "(u)", &info); error = __get_error(info); @@ -844,6 +817,7 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { + //LCOV_EXCL_START ERR("DBus error [%s]\n", g_error->message); if (g_error->code == G_DBUS_ERROR_NO_REPLY && ++retry < TETHERING_ERROR_RECOVERY_MAX) { @@ -857,6 +831,7 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, else error = TETHERING_ERROR_OPERATION_FAILED; g_error_free(g_error); + //LCOV_EXCL_STOP } else { g_variant_get(g_var, "(u)", &info); g_variant_unref(g_var); @@ -878,6 +853,7 @@ static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, DBG("-\n"); } +//LCOV_EXCL_START static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { @@ -927,56 +903,7 @@ static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, ecb(error, TETHERING_TYPE_USB, true, data); DBG("-\n"); } - -static void __wifi_ap_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_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]; - - 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); - 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); - DBG("-\n"); - return; - } - if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED) - error = TETHERING_ERROR_PERMISSION_DENIED; - else - error = TETHERING_ERROR_OPERATION_FAILED; - g_error_free(g_error); - } else { - g_variant_get(g_var, "(u)", &info); - g_variant_unref(g_var); - error = __get_error(info); - } - 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) { - DBG("-\n"); - return; - } - - ecb(error, TETHERING_TYPE_RESERVED, true, data); - DBG("-\n"); -} +//LCOV_EXCL_STOP static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) @@ -997,9 +924,11 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { + //LCOV_EXCL_START ERR("DBus error [%s]\n", g_error->message); g_error_free(g_error); return; + //LCOV_EXCL_STOP } g_variant_get(g_var, "(uu)", &event_type, &info); DBG("cfm event : %d info : %d\n", event_type, info); @@ -1033,6 +962,7 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, dcb(error, type, code, data); break; + //LCOV_EXCL_START case MOBILE_AP_DISABLE_USB_TETHERING_CFM: sigs[E_SIGNAL_USB_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_OFF].name, @@ -1045,19 +975,7 @@ static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, if (dcb) 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; - dcb = th->disabled_cb[type]; - data = th->disabled_user_data[type]; - if (dcb) - dcb(error, type, code, data); - break; + //LCOV_EXCL_STOP case MOBILE_AP_DISABLE_CFM: @@ -1108,6 +1026,7 @@ static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error); if (g_error) { + //LCOV_EXCL_START ERR("DBus fail [%s]\n", g_error->message); if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED) tethering_error = TETHERING_ERROR_PERMISSION_DENIED; @@ -1115,6 +1034,7 @@ static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res, tethering_error = TETHERING_ERROR_OPERATION_FAILED; flag = true; + //LCOV_EXCL_STOP } if (th->data_usage_cb == NULL) { ERR("There is no data_usage_cb\n"); @@ -1171,43 +1091,6 @@ static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res, 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; - DBG("-\n"); -} - static void __connect_signals(tethering_h tethering) { DBG("+\n"); @@ -1249,10 +1132,11 @@ static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len) _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n"); switch (type) { + //LCOV_EXCL_START case TETHERING_TYPE_USB: g_strlcpy(buf, TETHERING_USB_IF, len); break; - + //LCOV_EXCL_STOP case TETHERING_TYPE_WIFI: g_strlcpy(buf, TETHERING_WIFI_IF, len); break; @@ -1261,10 +1145,6 @@ static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len) g_strlcpy(buf, TETHERING_BT_IF, len); break; - case TETHERING_TYPE_RESERVED: - g_strlcpy(buf, TETHERING_WIFI_IF, len); - break; - default: ERR("Not supported type : %d\n", type); return false; @@ -1289,10 +1169,6 @@ static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int le g_strlcpy(buf, TETHERING_BT_GATEWAY, len); break; - case TETHERING_TYPE_RESERVED: - g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len); - break; - default: ERR("Not supported type : %d\n", type); return false; @@ -1303,7 +1179,7 @@ static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int le static int __get_common_ssid(char *ssid, unsigned int size) { if (ssid == NULL) { - ERR("ssid is null\n"); + ERR("ssid is null\n"); //LCOV_EXCL_LINE return TETHERING_ERROR_INVALID_PARAMETER; } @@ -1325,12 +1201,37 @@ static int __get_common_ssid(char *ssid, unsigned int size) return TETHERING_ERROR_NONE; } +static bool __get_wifi_mode_type(tethering_wifi_mode_type_e type, char **buf) +{ + _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n"); + + 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"); __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 +1251,18 @@ 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; + + __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 { @@ -1363,6 +1276,7 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { + //LCOV_EXCL_START ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); if (error->code == G_DBUS_ERROR_ACCESS_DENIED) @@ -1372,10 +1286,11 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se g_error_free(error); return ret; + //LCOV_EXCL_STOP } if (parameters != NULL) { - g_variant_get(parameters, "(siu)", passphrase, &len, &ret); + g_variant_get(parameters, "(siu)", &passphrase, &len, &ret); g_variant_unref(parameters); } @@ -1385,30 +1300,6 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se 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)); - else - g_strlcpy(set->key, th->passphrase, sizeof(set->key)); - - DBG("-\n"); - return TETHERING_ERROR_NONE; -} - static bool __check_precondition(tethering_type_e type) { int dnet_state = 0; @@ -1422,11 +1313,20 @@ static bool __check_precondition(tethering_type_e type) return TRUE; } +#ifdef TIZEN_TV_EXT + /* data network through ethernet */ + vconf_get_int(VCONFKEY_NETWORK_STATUS, &dnet_state); + if (dnet_state == VCONFKEY_NETWORK_ETHERNET) { + ERR("Data Network is connected"); + return TRUE; + } +#else vconf_get_int(VCONFKEY_DNET_STATE, &dnet_state); if (dnet_state > VCONFKEY_DNET_OFF) { ERR("Data Network is connected"); return TRUE; } +#endif/*TIZEN_TV_EXT*/ /* data network through wifi */ if (type != TETHERING_TYPE_WIFI) { @@ -1474,23 +1374,20 @@ 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->channel = 6; + th->mode_type = TETHERING_WIFI_MODE_TYPE_G; + th->wifi_max_connected = TETHERING_WIFI_MAX_STA; if (__generate_initial_passphrase(th->passphrase, sizeof(th->passphrase)) == 0) { - ERR("random passphrase generation failed\n"); + ERR("random passphrase generation failed\n"); //LCOV_EXCL_LINE free(th); return TETHERING_ERROR_OPERATION_FAILED; } if (__get_common_ssid(ssid, sizeof(ssid)) != TETHERING_ERROR_NONE) { - ERR("common ssid get failed\n"); - free(th); - return TETHERING_ERROR_OPERATION_FAILED; - } - - th->ap_ssid = g_strdup(ssid); - if (th->ap_ssid == NULL) { - ERR("g_strdup failed\n"); + ERR("common ssid get failed\n"); //LCOV_EXCL_LINE free(th); return TETHERING_ERROR_OPERATION_FAILED; } @@ -1501,27 +1398,30 @@ API int tethering_create(tethering_h *tethering) GCancellable *cancellable = g_cancellable_new(); th->client_bus = g_bus_get_sync(DBUS_BUS_SYSTEM, cancellable, &error); if (error) { + //LCOV_EXCL_START ERR("Couldn't connect to the System bus[%s]", error->message); g_error_free(error); g_cancellable_cancel(cancellable); g_object_unref(cancellable); - g_free(th->ap_ssid); free(th); return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP } 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); + //LCOV_EXCL_START + 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; + //LCOV_EXCL_STOP } __connect_signals((tethering_h)th); @@ -1558,8 +1458,6 @@ API int tethering_destroy(tethering_h tethering) 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); @@ -1604,13 +1502,15 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE); - if (type != TETHERING_TYPE_RESERVED - && __check_precondition(type) == FALSE) { + if (__check_precondition(type) == FALSE) { + //LCOV_EXCL_START DBG("-\n"); return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP } switch (type) { + //LCOV_EXCL_START case TETHERING_TYPE_USB: g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_USB_TETHER_ON].sig_id); @@ -1619,9 +1519,10 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); break; + //LCOV_EXCL_STOP case TETHERING_TYPE_WIFI: { - _softap_settings_t set = {"", "", 0, false}; + _softap_settings_t set = {"", "", "", 0, false}; ret = __prepare_wifi_settings(tethering, &set); if (ret != TETHERING_ERROR_NONE) { @@ -1633,7 +1534,7 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) 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), + g_variant_new("(sssiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type), G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); break; @@ -1649,25 +1550,9 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) break; - case TETHERING_TYPE_RESERVED: { - _softap_settings_t set = {"", "", 0, false}; - - ret = __prepare_wifi_ap_settings(tethering, &set); - if (ret != TETHERING_ERROR_NONE) { - ERR("softap settings initialization failed\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); - break; - } + //LCOV_EXCL_START case TETHERING_TYPE_ALL: { - _softap_settings_t set = {"", "", 0, false}; + _softap_settings_t set = {"", "", "", 0, false}; ret = __prepare_wifi_settings(tethering, &set); if (ret != TETHERING_ERROR_NONE) { @@ -1700,6 +1585,7 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); break; + //LCOV_EXCL_STOP } default: ERR("Unknown type : %d\n", type); @@ -1775,15 +1661,6 @@ API int tethering_disable(tethering_h tethering, tethering_type_e type) (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", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, - (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); - break; - case TETHERING_TYPE_ALL: g_dbus_connection_signal_unsubscribe(connection, sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); @@ -1849,10 +1726,6 @@ 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; - break; - default: ERR("Not supported type : %d\n", type); break; @@ -2232,8 +2105,6 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ 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); @@ -2241,8 +2112,7 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ break; } DBG("interface is %d\n", client.interface); - if (client.interface != type && (TETHERING_TYPE_ALL != type && - client.interface != TETHERING_TYPE_RESERVED)) { + if (client.interface != type && (TETHERING_TYPE_ALL != type)) { g_free(key); g_variant_unref(value); break; @@ -2736,15 +2606,25 @@ API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_s __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; + } + __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; } @@ -2978,6 +2858,7 @@ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphr g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { + //LCOV_EXCL_START ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); if (error->code == G_DBUS_ERROR_ACCESS_DENIED) @@ -2987,6 +2868,7 @@ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphr g_error_free(error); return ret; + //LCOV_EXCL_STOP } g_variant_get(parameters, "(u)", &ret); @@ -3037,6 +2919,7 @@ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { + //LCOV_EXCL_START ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); if (error->code == G_DBUS_ERROR_ACCESS_DENIED) @@ -3046,6 +2929,7 @@ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) g_error_free(error); return ret; + //LCOV_EXCL_STOP } if (parameters != NULL) { @@ -3056,379 +2940,1018 @@ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) return TETHERING_ERROR_NONE; } -/** - * @internal - * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility). - * @since_tizen 2.3 - * @privlevel platform - * @privilege http://tizen.org/privilege/tethering.admin - * @remarks Connected devices via Wi-Fi tethering or 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_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data) - +API int tethering_wifi_set_channel(tethering_h tethering, int channel) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); __tethering_h *th = (__tethering_h *)tethering; - _softap_settings_t set = {"", "", 0, false}; - GDBusProxy *proxy = th->client_bus_proxy; - int ret = 0; + th->channel = channel; - DBG("+\n"); + return TETHERING_ERROR_NONE; +} - if (th->settings_reloaded_cb) { - ERR("Operation in progress\n"); - return TETHERING_ERROR_OPERATION_FAILED; - } +API int tethering_wifi_get_channel(tethering_h tethering, int *channel) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); - ret = __prepare_wifi_settings(tethering, &set); - if (ret != TETHERING_ERROR_NONE) { - ERR("softap settings initialization failed\n"); - return TETHERING_ERROR_OPERATION_FAILED; - } - - th->settings_reloaded_cb = callback; - th->settings_reloaded_user_data = user_data; + _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(channel) is NULL\n"); - g_dbus_proxy_call(proxy, "reload_wifi_settings", - g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type), - G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, - (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering); + __tethering_h *th = (__tethering_h *)tethering; + *channel = th->channel; 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_mode(tethering_h tethering, tethering_wifi_mode_type_e type) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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->mode_type = type; + 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_mode(tethering_h tethering, tethering_wifi_mode_type_e *type) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); + "parameter(type) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; + *type = th->mode_type; - *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. + * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility). * @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 Connected devices via Wi-Fi tethering or MobileAP will be disconnected when the settings are reloaded * @param[in] tethering The handle of tethering - * @param[in] ssid The SSID + * @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_OUT_OF_MEMORY Out of memory + * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed */ -API int tethering_wifi_ap_set_ssid(tethering_h tethering, const char *ssid) +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); _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"); + _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(callback) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - char *p_ssid = NULL; - int ssid_len = 0; + _softap_settings_t set = {"", "", "", 0, false}; + GDBusProxy *proxy = th->client_bus_proxy; + int ret = 0; - ssid_len = strlen(ssid); - if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) { - ERR("parameter(ssid) is too long"); - return TETHERING_ERROR_INVALID_PARAMETER; + DBG("+\n"); + + if (th->settings_reloaded_cb) { + ERR("Operation in progress\n"); + return TETHERING_ERROR_OPERATION_FAILED; } - p_ssid = strdup(ssid); - if (p_ssid == NULL) { - ERR("strdup failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; + ret = __prepare_wifi_settings(tethering, &set); + if (ret != TETHERING_ERROR_NONE) { + ERR("softap settings initialization failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; } - if (th->ap_ssid) - g_free(th->ap_ssid); - th->ap_ssid = p_ssid; + th->settings_reloaded_cb = callback; + th->settings_reloaded_user_data = user_data; + + g_dbus_proxy_call(proxy, "reload_wifi_settings", + g_variant_new("(sssiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering); 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) +API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); _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"); __tethering_h *th = (__tethering_h *)tethering; - - *ssid = g_strdup(th->ap_ssid); - if (*ssid == NULL) { - ERR("strdup failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; - } + th->mac_filter = mac_filter; 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_get_mac_filter(tethering_h tethering, bool *mac_filter) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + "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; - th->visibility = visible; + *mac_filter = th->mac_filter; + return TETHERING_ERROR_NONE; } -/** - * @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) +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; - _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(visible) is NULL\n"); + p_mac = strdup(mac); + if (p_mac == NULL) { + ERR("strdup failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } - __tethering_h *th = (__tethering_h *)tethering; + fp = fopen(filepath, "a+"); + if (!fp) { + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + 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; + } + } + + if (!mac_exist) { + fprintf(fp, "%s\n", mac); + + 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); + } + + fclose(fp); - *visible = th->visibility; 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) +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(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(passphrase) 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; - int passphrase_len = 0; + fp1 = fopen(TEMP_LIST, "w+"); + if (!fp1) { + fclose(fp); + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } - passphrase_len = strlen(passphrase); + while (fgets(line, MAX_BUF_SIZE, fp) != NULL) { + if (strncmp(mac, line, 17) == 0) { + DBG("MAC %s found in the list\n", mac); - 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; + 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); + } } - if (!g_strcmp0(passphrase, th->passphrase)) - return TETHERING_ERROR_NONE; + fclose(fp); + fclose(fp1); + + if ((strcmp(filepath, ALLOWED_LIST) == 0)) + rename(TEMP_LIST, ALLOWED_LIST); + else if ((strcmp(filepath, BLOCKED_LIST) == 0)) + rename(TEMP_LIST, BLOCKED_LIST); - g_strlcpy(th->passphrase, passphrase, sizeof(th->passphrase)); 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_add_allowed_mac_list(tethering_h tethering, const char *mac) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); - __tethering_h *th = (__tethering_h *)tethering; + return __add_mac_to_file(ALLOWED_LIST, mac); +} - *passphrase = g_strdup(th->passphrase); - if (*passphrase == NULL) { - ERR("strdup is failed\n"); - return TETHERING_ERROR_OUT_OF_MEMORY; - } +API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); - return TETHERING_ERROR_NONE; + return __remove_mac_from_file(ALLOWED_LIST, mac); } -/** - * @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_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list) { CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(allowed_mac_list) is NULL\n"); - __tethering_h *th = (__tethering_h *)tethering; - _softap_settings_t set = {"", "", 0, false}; - GDBusProxy *proxy = th->client_bus_proxy; - int ret = 0; + *allowed_mac_list = g_slist_copy(allowed_list); + return TETHERING_ERROR_NONE; +} - DBG("+\n"); +API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); - if (th->ap_settings_reloaded_cb) { - ERR("Operation in progress\n"); - return TETHERING_ERROR_OPERATION_FAILED; - } + return __add_mac_to_file(BLOCKED_LIST, mac); +} - ret = __prepare_wifi_ap_settings(tethering, &set); - if (ret != TETHERING_ERROR_NONE) { - ERR("softap settings initialization failed\n"); - return TETHERING_ERROR_OPERATION_FAILED; - } +API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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"); - th->ap_settings_reloaded_cb = callback; - th->ap_settings_reloaded_user_data = user_data; + return __remove_mac_from_file(BLOCKED_LIST, mac); +} - 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); +API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + _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; } + +API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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_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; +} + +API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) 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; + + GDBusProxy *proxy = th->client_bus_proxy; + + 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 (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); + + th->dhcp_enabled = true; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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) +{ + GError *error = NULL; + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + + _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; + + 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) +{ + GError *error = NULL; + GVariant *result = NULL; + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE); + + _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; + + 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, 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, 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); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, 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, 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, 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, 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 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, 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, 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, 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, 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, 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 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_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) + snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_ACCEPT); + else + snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_DROP); + + DBG("cmd:%s", cmd); + + list = strdup(cmd); + if (list == NULL) { + ERR("strdup failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } + + 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, 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 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_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) + snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_ACCEPT); + else + snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_DROP); + + DBG("cmd:%s", cmd); + + list = strdup(cmd); + if (list == NULL) { + ERR("strdup failed\n"); + return TETHERING_ERROR_OUT_OF_MEMORY; + } + + 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, 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, 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, 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, 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, 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, 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, "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; +} + +