From: Nishant Chaprana Date: Wed, 6 Jan 2021 11:23:46 +0000 (+0530) Subject: Add API to set local device's IP address X-Git-Tag: submit/tizen/20210126.014105^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F04%2F251004%2F7;p=platform%2Fcore%2Fapi%2Ftethering.git Add API to set local device's IP address Change-Id: I16faccb08b40d398061994f94f1ce4dbc6c86e0a Signed-off-by: Nishant Chaprana --- diff --git a/include/tethering.h b/include/tethering.h index 999c17f..e6a3515 100644 --- a/include/tethering.h +++ b/include/tethering.h @@ -432,6 +432,24 @@ int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e */ int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address); +/** + * @brief Sets the local IP address. + * @since_tizen 6.5 + * @privlevel platform + * @privilege %http://tizen.org/privilege/tethering.admin + * @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); + /** * @brief Gets the Gateway address. * @since_tizen 2.3 diff --git a/include/tethering_private.h b/include/tethering_private.h index c0b12a6..882edf1 100644 --- a/include/tethering_private.h +++ b/include/tethering_private.h @@ -134,6 +134,9 @@ int _tethering_check_feature_supported(const char* feature, ...); * Common configuration */ #define TETHERING_STR_INFO_LEN 40 /**< length of the ip or mac address */ +#define TETHERING_IPV4_ADDRESS_MAX_LEN 15 /**< Maximum length of IP address */ +#define TETHERING_IPV4_ADDRESS_MIN_LEN 7 /**< Minimum length of IP address */ + /** * Mobile AP error code @@ -312,6 +315,7 @@ typedef struct { char passphrase[TETHERING_WIFI_KEY_MAX_LEN + 1]; tethering_wifi_security_type_e sec_type; tethering_wifi_mode_type_e mode_type; + char ip_address[TETHERING_IPV4_ADDRESS_MAX_LEN + 1]; bool visibility; bool mac_filter; bool port_forwarding; @@ -344,6 +348,7 @@ typedef struct { char ssid[TETHERING_WIFI_SSID_MAX_LEN + 1]; char key[TETHERING_WIFI_KEY_MAX_LEN + 1]; char mode[TETHERING_WIFI_MODE_MAX_LEN + 1]; + char ip_address[TETHERING_IPV4_ADDRESS_MAX_LEN + 1]; tethering_wifi_security_type_e sec_type; bool visibility; bool mac_filter; diff --git a/packaging/capi-network-tethering.spec b/packaging/capi-network-tethering.spec index b5926e2..eb7b99d 100644 --- a/packaging/capi-network-tethering.spec +++ b/packaging/capi-network-tethering.spec @@ -1,6 +1,6 @@ Name: capi-network-tethering Summary: Tethering Framework -Version: 1.1.5 +Version: 1.1.6 Release: 1 Group: System/Network License: Apache-2.0 diff --git a/src/tethering.c b/src/tethering.c index 18c2651..4eab262 100755 --- a/src/tethering.c +++ b/src/tethering.c @@ -1676,9 +1676,16 @@ static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *se } } - INFO("ssid: %s security: %d mode: %s channel: %d visibility: %s\n", - set->ssid, set->sec_type, set->mode, set->channel, - (set->visibility) ? "true" : "false"); + if (strlen(th->ip_address)) + g_strlcpy(set->ip_address, th->ip_address, sizeof(set->ip_address)); + else + 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; } @@ -1871,6 +1878,86 @@ API int tethering_destroy(tethering_h tethering) 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. @@ -1926,7 +2013,9 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) 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) { @@ -1937,21 +2026,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); - 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); + 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); - 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); + params = __get_wifi_settings_dbus_params("wifi_sharing", &set); + else + params = __get_wifi_settings_dbus_params("wifi_tether", &set); - SINFO("enable_wifi_tethering key: %s", key); - g_dbus_proxy_call(proxy, "enable_wifi_tethering", - g_variant_new("(ssssiiiiiii)", key, set.ssid, set.key, set.mode, - set.channel, set.visibility, set.mac_filter, set.max_connected, - set.sec_type, set.txpower, TETHERING_ADDRESS_FAMILY_IPV4), + 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; } @@ -1967,7 +2057,9 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) break; case TETHERING_TYPE_P2P: { - _softap_settings_t p2p_set = {"", "", "", 0, false}; + _softap_settings_t p2p_set; + memset(&p2p_set, 0, sizeof(_softap_settings_t)); + ret = __prepare_wifi_settings(tethering, &p2p_set); if (ret != TETHERING_ERROR_NONE) { ERR("p2p settings initialization failed\n"); @@ -1984,7 +2076,9 @@ API int tethering_enable(tethering_h tethering, tethering_type_e type) } 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) { @@ -2006,12 +2100,15 @@ 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("(ssssiiiiiii)", "wifi_tether", set.ssid, set.key, set.mode, - set.channel, set.visibility, set.mac_filter, set.max_connected, - set.sec_type, set.txpower, TETHERING_ADDRESS_FAMILY_IPV4), + 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, @@ -2074,7 +2171,9 @@ API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type) } case TETHERING_TYPE_WIFI: { - _softap_settings_t set = {"", "", "", 0, false, false, 0, 0}; + 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) { @@ -2095,12 +2194,15 @@ API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type) g_strlcpy(key, "wifi_sharing", TETHERING_WIFI_KEY_MAX_LEN + 1); SINFO("enable_wifi_tethering key: %s", key); - g_dbus_proxy_call(proxy, "enable_wifi_tethering", - g_variant_new("(ssssiiiiiii)", key, set.ssid, set.key, set.mode, - set.channel, set.visibility, set.mac_filter, set.max_connected, - set.sec_type, set.txpower, TETHERING_ADDRESS_FAMILY_IPV6), + 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; } @@ -2513,6 +2615,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; } @@ -2544,21 +2701,29 @@ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e ty 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, - "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); - char gateway_buf[TETHERING_STR_INFO_LEN] = {0, }; + __tethering_h *th = (__tethering_h *)tethering; - _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)), - TETHERING_ERROR_OPERATION_FAILED, - "getting gateway address is failed\n"); + if (type == TETHERING_TYPE_WIFI && strlen(th->ip_address)) { + *gateway_address = strdup(th->ip_address); - *gateway_address = strdup(gateway_buf); + } 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); + } return TETHERING_ERROR_NONE; } @@ -3862,10 +4027,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) { diff --git a/tests/tethering-gtest-common.cpp b/tests/tethering-gtest-common.cpp index d97055b..d4cc5de 100755 --- a/tests/tethering-gtest-common.cpp +++ b/tests/tethering-gtest-common.cpp @@ -250,6 +250,46 @@ TEST_F(TetheringTest, GetIpAddressP) free(ip); } +TEST_F(TetheringTest, SetIpAddressN) +{ + const char *ip = "192.168.0.1"; + + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(NULL, + TETHERING_TYPE_WIFI, TETHERING_ADDRESS_FAMILY_IPV4, ip)); + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(handle, + TETHERING_TYPE_WIFI, TETHERING_ADDRESS_FAMILY_IPV4, NULL)); + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(NULL, + TETHERING_TYPE_WIFI, TETHERING_ADDRESS_FAMILY_IPV4, NULL)); + + tethering_mock_set_enabled_state(false, false, false, false); + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(handle, TETHERING_TYPE_USB, + TETHERING_ADDRESS_FAMILY_IPV4, ip)); + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(handle, TETHERING_TYPE_BT, + TETHERING_ADDRESS_FAMILY_IPV4, ip)); + EXPECT_EQ(TETHERING_ERROR_INVALID_PARAMETER, + tethering_set_ip_address(handle, TETHERING_TYPE_P2P, + TETHERING_ADDRESS_FAMILY_IPV4, ip)); +} + +TEST_F(TetheringTest, SetIpAddressP) +{ + const char *ip = "192.168.0.1"; + + EXPECT_EQ(TETHERING_ERROR_NONE, + tethering_set_ip_address(handle, TETHERING_TYPE_WIFI, + TETHERING_ADDRESS_FAMILY_IPV4, ip)); + + tethering_mock_set_enabled_state(false, false, false, false); + EXPECT_EQ(TETHERING_ERROR_NONE, + tethering_set_ip_address(handle, TETHERING_TYPE_WIFI, + TETHERING_ADDRESS_FAMILY_IPV4, ip)); +} + TEST_F(TetheringTest, GetGatewayAddressN) { char *gateway = NULL; diff --git a/tools/tethering_test.c b/tools/tethering_test.c index 7f2c231..8f8f9ab 100755 --- a/tools/tethering_test.c +++ b/tools/tethering_test.c @@ -752,10 +752,18 @@ static int test_tethering_enable(void) if (type != TETHERING_TYPE_WIFI) return -1; - printf("Select 1: Wi-Fi sharing, 2: Dual band hotspot\n"); + printf("Select 0: Normal, 1: Wi-Fi sharing, 2: Dual band hotspot\n"); ret = scanf("%d", &choice); - if (choice == 1) { + switch (choice) { + case 0: + ret = tethering_wifi_set_sharing(th, true); + if (__is_err(ret) == true) { + printf("Fail to unset wifi sharing\n"); + return -1; + } + break; + case 1: ret = tethering_wifi_is_sharing_supported(th, &supported); if (__is_err(ret) == true) { @@ -775,7 +783,8 @@ static int test_tethering_enable(void) return -1; } } - } else if (choice == 2) { + break; + case 2: ret = tethering_is_dualband_supported(handle, type, &supported); if (__is_err(ret) == true) { @@ -783,10 +792,11 @@ static int test_tethering_enable(void) return -1; } else printf("DualBand is %s\n", supported ? "Supported" : "Not Supported"); - } else { - printf("Invalid!!\n"); + break; + default: + printf("option not supported.\n"); return -1; - } + }; if (address_type) ret = tethering_ipv6_enable(handle, type);