+ 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(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);
+ 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;
+