X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftethering.c;h=0bad2978e71ba9c92007fea15e0baa4244cf5216;hb=ab7fdad2421e78843f4c1a96d2f711998a6a1678;hp=3ca6c0b03d116c73af94fd18f401d4b65fa35645;hpb=af82a35a60559f6c7ecf3d80bd13d963f729e0d7;p=platform%2Fcore%2Fapi%2Ftethering.git diff --git a/src/tethering.c b/src/tethering.c old mode 100644 new mode 100755 index 3ca6c0b..0bad297 --- a/src/tethering.c +++ b/src/tethering.c @@ -23,42 +23,131 @@ #include #include #include - +#include +#include #include - -#include "tethering-client-stub.h" -#include "marshal.h" +#include +#include +#include +#include #include "tethering_private.h" -static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data); -static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data); +#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); + +static void __handle_wifi_tether_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_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); + +static void __handle_usb_tether_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_bt_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); + +static void __handle_bt_tether_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); + +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); + +static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data); + +static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data); + +static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data); + +static void __handle_ssid_visibility_changed(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_passphrase_changed(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_dhcp(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data); static __tethering_sig_t sigs[] = { - {SIGNAL_NAME_NET_CLOSED, __handle_net_closed}, - {SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on}, - {SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off}, - {SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on}, - {SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off}, - {SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on}, - {SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off}, - {SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout}, - {SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode}, - {SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode}, - {SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed}, - {SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed}, - {SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed}, - {"", NULL}}; + {0, SIGNAL_NAME_NET_CLOSED, __handle_net_closed}, + {0, SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on}, + {0, SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off}, + {0, SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on}, + {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_NO_DATA_TIMEOUT, __handle_no_data_timeout}, + {0, SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode}, + {0, SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode}, + {0, SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed}, + {0, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed}, + {0, SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed}, + {0, SIGNAL_NAME_DHCP_STATUS, __handle_dhcp} }; + +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; //LCOV_EXCL_LINE + + GVariant *message = NULL; + GError *error = NULL; + + if (arg) + message = g_variant_new("(s)", arg); + + 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); //LCOV_EXCL_LINE + g_error_free(error); //LCOV_EXCL_LINE + } + g_variant_unref(message); +} static bool __any_tethering_is_enabled(tethering_h tethering) { @@ -70,6 +159,109 @@ static bool __any_tethering_is_enabled(tethering_h tethering) return false; } +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_WPS) { + ERR("Invalid param\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + + if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, security_type) < 0) { + ERR("vconf_set_int is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + return TETHERING_ERROR_NONE; +} + +static tethering_error_e __get_security_type(tethering_wifi_security_type_e *security_type) +{ + if (security_type == NULL) { + ERR("Invalid param\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + + if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, + (int *)security_type) < 0) { + ERR("vconf_get_int is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + return TETHERING_ERROR_NONE; +} + +static bool __get_ssid_from_vconf(const char *path, char *ssid, unsigned int size) +{ + if (path == NULL || ssid == NULL || size == 0) + return false; + + char *ptr = NULL; + char *ptr_tmp = NULL; + + ptr = vconf_get_str(path); + if (ptr == NULL) + return false; + + if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp)) + *ptr_tmp = '\0'; + + g_strlcpy(ssid, ptr, size); + free(ptr); + + return true; +} + +static tethering_error_e __set_visible(const bool visible) +{ + if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, visible ? 0 : 1) < 0) { + ERR("vconf_set_int is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + return TETHERING_ERROR_NONE; +} + +static tethering_error_e __get_visible(bool *visible) +{ + if (visible == NULL) { + ERR("Invalid param\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + + int hide = 0; + + if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, &hide) < 0) { + ERR("vconf_get_int is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + if (hide) + *visible = false; + else + *visible = true; + return TETHERING_ERROR_NONE; +} + +static unsigned int __generate_initial_passphrase(char *passphrase, unsigned int size) +{ + if (passphrase == NULL || + size == 0 || size < TETHERING_WIFI_KEY_MIN_LEN + 1) + return 0; + + guint32 rand_int = 0; + int index = 0; + + for (index = 0; index < TETHERING_WIFI_KEY_MIN_LEN; index++) { + rand_int = g_random_int_range('a', 'z'); + passphrase[index] = rand_int; + } + passphrase[index] = '\0'; + + return index; +} + static tethering_error_e __get_error(int agent_error) { tethering_error_e err = TETHERING_ERROR_NONE; @@ -79,9 +271,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; @@ -115,10 +309,15 @@ 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_OPERATION_FAILED; + err = TETHERING_ERROR_NOT_PERMITTED; break; + case MOBILE_AP_ERROR_PERMISSION_DENIED: + err = TETHERING_ERROR_PERMISSION_DENIED; + break; + //LCOV_EXCL_STOP default: ERR("Not defined error : %d\n", agent_error); err = TETHERING_ERROR_OPERATION_FAILED; @@ -128,9 +327,10 @@ static tethering_error_e __get_error(int agent_error) return err; } -static void __handle_dhcp(DBusGProxy *proxy, const char *member, - guint interface, const char *ip, const char *mac, - const char *name, gpointer user_data) +//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) { DBG("+\n"); @@ -139,46 +339,66 @@ static void __handle_dhcp(DBusGProxy *proxy, const char *member, __tethering_h *th = (__tethering_h *)user_data; bool opened = false; tethering_type_e type = 0; + mobile_ap_type_e ap_type = 0; tethering_connection_state_changed_cb ccb = NULL; - __tethering_client_h client = {0, }; + __tethering_client_h client; void *data = NULL; + char *buf = NULL; + char *name = NULL; + char *mac = NULL; + char *ip = NULL; + guint timestamp; - if (!g_strcmp0(member, "DhcpConnected")) { + memset(&client, 0, sizeof(__tethering_client_h)); + g_variant_get(parameters, "(susssu)", &buf, &ap_type, &ip, &mac, &name, ×tamp); + + if (!g_strcmp0(buf, "DhcpConnected")) { opened = true; - } else if (!g_strcmp0(member, "DhcpLeaseDeleted")) { + } else if (!g_strcmp0(buf, "DhcpLeaseDeleted")) { opened = false; } else { - ERR("Unknown event [%s]\n", member); - return; + ERR("Unknown event [%s]\n", buf); + goto DONE; } - if (interface == MOBILE_AP_TYPE_USB) + if (ap_type == MOBILE_AP_TYPE_USB) type = TETHERING_TYPE_USB; - else if (interface == MOBILE_AP_TYPE_WIFI) + else if (ap_type == MOBILE_AP_TYPE_WIFI) type = TETHERING_TYPE_WIFI; - else if (interface == MOBILE_AP_TYPE_BT) + else if (ap_type == MOBILE_AP_TYPE_BT) type = TETHERING_TYPE_BT; else { - ERR("Not supported tethering type [%d]\n", interface); - return; + ERR("Not supported tethering type [%d]\n", ap_type); + goto DONE; } ccb = th->changed_cb[type]; if (ccb == NULL) - return; + goto DONE; data = th->changed_user_data[type]; client.interface = type; g_strlcpy(client.ip, ip, sizeof(client.ip)); g_strlcpy(client.mac, mac, sizeof(client.mac)); - g_strlcpy(client.hostname, name, sizeof(client.hostname)); + if (name != NULL) + client.hostname = g_strdup(name); + client.tm = (time_t)timestamp; ccb((tethering_client_h)&client, opened, data); - - return; + g_free(client.hostname); +DONE: + g_free(buf); + g_free(ip); + g_free(mac); + g_free(name); + DBG("-\n"); } +//LCOV_EXCL_STOP -static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data) +//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) { DBG("+\n"); @@ -199,10 +419,13 @@ static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpoin dcb(TETHERING_ERROR_NONE, type, code, data); } - return; + DBG("-\n"); } +//LCOV_EXCL_STOP -static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data) +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) { DBG("+\n"); @@ -220,9 +443,12 @@ static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, g data = th->enabled_user_data[type]; ecb(TETHERING_ERROR_NONE, type, is_requested, data); + DBG("-\n"); } -static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_wifi_tether_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"); @@ -233,23 +459,28 @@ static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, 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]; - - if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) + 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(value_name, SIGNAL_MSG_TIMEOUT)) + else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) code = TETHERING_DISABLED_BY_TIMEOUT; + g_free(buf); dcb(TETHERING_ERROR_NONE, type, code, data); - return; + DBG("-\n"); } -static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data) +//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) { DBG("+\n"); @@ -267,9 +498,12 @@ static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gp data = th->enabled_user_data[type]; ecb(TETHERING_ERROR_NONE, type, is_requested, data); + DBG("-\n"); } -static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_usb_tether_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"); @@ -280,21 +514,26 @@ static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, g 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]; - if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) + g_variant_get(parameters, "(s)", &buf); + if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) code = TETHERING_DISABLED_BY_USB_DISCONNECTION; dcb(TETHERING_ERROR_NONE, type, code, data); - - return; + g_free(buf); + DBG("-\n"); } +//LCOV_EXCL_STOP -static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_bt_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) { DBG("+\n"); @@ -312,9 +551,12 @@ static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpo data = th->enabled_user_data[type]; ecb(TETHERING_ERROR_NONE, type, is_requested, data); + DBG("-\n"); } -static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_bt_tether_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"); @@ -325,23 +567,28 @@ static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gp 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]; - - if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) + g_variant_get(parameters, "(s)", &buf); + if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE)) code = TETHERING_DISABLED_BY_BT_OFF; - else if (!g_strcmp0(value_name, SIGNAL_MSG_TIMEOUT)) + else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT)) code = TETHERING_DISABLED_BY_TIMEOUT; dcb(TETHERING_ERROR_NONE, type, code, data); - return; + g_free(buf); + DBG("-\n"); } -static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data) +//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) { DBG("+\n"); @@ -361,9 +608,12 @@ static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, dcb(TETHERING_ERROR_NONE, type, code, data); } + DBG("-\n"); } -static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) { DBG("+\n"); @@ -383,9 +633,12 @@ static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, dcb(TETHERING_ERROR_NONE, type, code, data); } + DBG("-\n"); } -static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) { DBG("+\n"); @@ -405,69 +658,86 @@ static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpoi dcb(TETHERING_ERROR_NONE, type, code, data); } + 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, + GVariant *parameters, gpointer user_data) -static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data) { DBG("+\n"); _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - __tethering_h *th = (__tethering_h *)user_data; + tethering_wifi_security_type_changed_cb scb = NULL; void *data = NULL; tethering_wifi_security_type_e security_type; + char *buf = NULL; scb = th->security_type_changed_cb; if (scb == NULL) return; + g_variant_get(parameters, "(s)", &buf); data = th->security_type_user_data; - if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0) + if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0) security_type = TETHERING_WIFI_SECURITY_TYPE_NONE; - else if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0) + 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 { - ERR("Unknown security type : %s\n", value_name); + SERR("Unknown type : %s\n", buf); + g_free(buf); return; } - + g_free(buf); scb(security_type, data); return; } -static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_ssid_visibility_changed(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) { DBG("+\n"); _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - __tethering_h *th = (__tethering_h *)user_data; + tethering_wifi_ssid_visibility_changed_cb scb = NULL; void *data = NULL; bool visible = false; + char *buf = NULL; scb = th->ssid_visibility_changed_cb; - if (scb == NULL) + if (scb == NULL) { + DBG("-\n"); return; - + } + g_variant_get(parameters, "(s)", &buf); data = th->ssid_visibility_user_data; - if (g_strcmp0(value_name, SIGNAL_MSG_SSID_VISIBLE) == 0) + if (g_strcmp0(buf, SIGNAL_MSG_SSID_VISIBLE) == 0) visible = true; scb(visible, data); - - return; + g_free(buf); + DBG("-\n"); } -static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data) +static void __handle_passphrase_changed(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) { DBG("+\n"); _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - __tethering_h *th = (__tethering_h *)user_data; + tethering_wifi_passphrase_changed_cb pcb = NULL; void *data = NULL; @@ -478,105 +748,251 @@ static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_nam data = th->passphrase_user_data; pcb(data); + DBG("-\n"); +} - return; +static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + INFO("+\n"); + + _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + GError *g_error = NULL; + GVariant *g_var; + guint info; + tethering_error_e error; + __tethering_h *th = (__tethering_h *)user_data; + tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_WIFI]; + void *data = th->enabled_user_data[TETHERING_TYPE_WIFI]; + + 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) { + g_error_free(g_error); + tethering_enable((tethering_h)th, TETHERING_TYPE_WIFI); + return; + } else 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); + //LCOV_EXCL_STOP + } else { + g_variant_get(g_var, "(u)", &info); + error = __get_error(info); + } + retry = 0; + + INFO("cfm event : wifi tethering enable info : %d\n", error); + + sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_ON].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_WIFI_TETHER_ON].cb, (gpointer)th, NULL); + + if (!ecb) { + INFO("-\n"); + return; + } + ecb(error, TETHERING_TYPE_WIFI, true, data); + g_variant_unref(g_var); + INFO("-\n"); } -static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info, - GError *g_error, gpointer user_data) +static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + DBG("+\n"); + _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + GError *g_error = NULL; + GVariant *g_var; + guint info; + tethering_error_e error; + + __tethering_h *th = (__tethering_h *)user_data; + tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_BT]; + void *data = th->enabled_user_data[TETHERING_TYPE_BT]; + + 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) { + g_error_free(g_error); + tethering_enable((tethering_h)th, TETHERING_TYPE_BT); + 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); + //LCOV_EXCL_STOP + } else { + g_variant_get(g_var, "(u)", &info); + g_variant_unref(g_var); + error = __get_error(info); + } + retry = 0; + + sigs[E_SIGNAL_BT_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_ON].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_BT_TETHER_ON].cb, (gpointer)th, NULL); + + if (!ecb) { + DBG("-\n"); + return; + } + + ecb(error, TETHERING_TYPE_BT, true, data); + DBG("-\n"); +} + +//LCOV_EXCL_START +static void __usb_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_USB]; + void *data = th->enabled_user_data[TETHERING_TYPE_USB]; + + 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_USB); + 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_USB_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_ON].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_USB_TETHER_ON].cb, (gpointer)th, NULL); + + if (!ecb) { + DBG("-\n"); + return; + } + + ecb(error, TETHERING_TYPE_USB, true, data); + DBG("-\n"); +} +//LCOV_EXCL_STOP + +static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + INFO("+\n"); + _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + GError *g_error = NULL; + GVariant *g_var; + guint info, event_type; + tethering_error_e error; + tethering_type_e type; tethering_h tethering = (tethering_h)user_data; __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - - tethering_type_e type = 0; - tethering_error_e error = __get_error(info); - bool is_requested = true; tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST; - - tethering_enabled_cb ecb = NULL; tethering_disabled_cb dcb = NULL; void *data = NULL; + 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 } - - DBG("cfm event : %d info : %d\n", event, info); - switch (event) { - case MOBILE_AP_ENABLE_WIFI_TETHERING_CFM: - type = TETHERING_TYPE_WIFI; - ecb = th->enabled_cb[type]; - data = th->enabled_user_data[type]; - if (ecb) - ecb(error, type, is_requested, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON, - G_CALLBACK(__handle_wifi_tether_on), - (gpointer)tethering, NULL); - break; - + g_variant_get(g_var, "(uu)", &event_type, &info); + INFO("cfm event : %d info : %d\n", event_type, info); + g_variant_unref(g_var); + error = __get_error(info); + INFO("cfm event : %d info : %d\n", event_type, error); + switch (event_type) { case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM: + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL); + type = TETHERING_TYPE_WIFI; dcb = th->disabled_cb[type]; data = th->disabled_user_data[type]; if (dcb) dcb(error, type, code, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF, - G_CALLBACK(__handle_wifi_tether_off), - (gpointer)tethering, NULL); - break; - - case MOBILE_AP_ENABLE_BT_TETHERING_CFM: - type = TETHERING_TYPE_BT; - ecb = th->enabled_cb[type]; - data = th->enabled_user_data[type]; - if (ecb) - ecb(error, type, is_requested, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON, - G_CALLBACK(__handle_bt_tether_on), - (gpointer)tethering, NULL); break; case MOBILE_AP_DISABLE_BT_TETHERING_CFM: + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL); + type = TETHERING_TYPE_BT; dcb = th->disabled_cb[type]; data = th->disabled_user_data[type]; if (dcb) dcb(error, type, code, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF, - G_CALLBACK(__handle_bt_tether_off), - (gpointer)tethering, NULL); - break; - - case MOBILE_AP_ENABLE_USB_TETHERING_CFM: - type = TETHERING_TYPE_USB; - ecb = th->enabled_cb[type]; - data = th->enabled_user_data[type]; - if (ecb) - ecb(error, type, is_requested, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON, - G_CALLBACK(__handle_usb_tether_on), - (gpointer)tethering, NULL); 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, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_USB_TETHER_OFF].cb, (gpointer)th, NULL); + type = TETHERING_TYPE_USB; dcb = th->disabled_cb[type]; data = th->disabled_user_data[type]; if (dcb) dcb(error, type, code, data); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF, - G_CALLBACK(__handle_usb_tether_off), - (gpointer)tethering, NULL); break; + //LCOV_EXCL_STOP case MOBILE_AP_DISABLE_CFM: + + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL); + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus, + NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL); + 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, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[E_SIGNAL_USB_TETHER_OFF].cb, (gpointer)th, NULL); + for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) { dcb = th->disabled_cb[type]; if (dcb == NULL) @@ -585,119 +1001,143 @@ static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info, dcb(error, type, code, data); } - - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF, - G_CALLBACK(__handle_usb_tether_off), - (gpointer)tethering, NULL); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF, - G_CALLBACK(__handle_wifi_tether_off), - (gpointer)tethering, NULL); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF, - G_CALLBACK(__handle_bt_tether_off), - (gpointer)tethering, NULL); break; default: ERR("Invalid event\n"); - return; + break; } - - return; + INFO("-\n"); } -static void __get_data_usage_cb(DBusGProxy *remoteobj, guint event, - guint64 tx_bytes, guint64 rx_bytes, - GError *error, gpointer user_data) +static void __get_data_usage_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 event_type; + guint64 tx_bytes, rx_bytes; __tethering_h *th = (__tethering_h *)user_data; + tethering_error_e tethering_error = TETHERING_ERROR_NONE; + bool flag = false; + 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; + else + 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"); return; } + if (flag) { + th->data_usage_cb(tethering_error, 0LL, 0LL, th->data_usage_user_data); + } else { + g_variant_get(g_var, "(utt)", &event_type, &tx_bytes, &rx_bytes); + th->data_usage_cb(TETHERING_ERROR_NONE, + rx_bytes, tx_bytes, th->data_usage_user_data); + g_variant_unref(g_var); + } + th->data_usage_cb = NULL; + th->data_usage_user_data = NULL; - if (error || event != MOBILE_AP_GET_DATA_PACKET_USAGE_CFM) { - if (error) { - ERR("DBus fail [%s]\n", error->message); - g_error_free(error); - } + DBG("-\n"); +} - th->data_usage_cb(TETHERING_ERROR_OPERATION_FAILED, - 0LL, 0LL, th->data_usage_user_data); +static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + DBG("+\n"); - th->data_usage_cb = NULL; - th->data_usage_user_data = NULL; + _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->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->data_usage_cb(TETHERING_ERROR_NONE, - rx_bytes, tx_bytes, th->data_usage_user_data); - - th->data_usage_cb = NULL; - th->data_usage_user_data = NULL; + th->settings_reloaded_cb(tethering_error, + th->settings_reloaded_user_data); - return; + th->settings_reloaded_cb = NULL; + th->settings_reloaded_user_data = NULL; + DBG("-\n"); } static void __connect_signals(tethering_h tethering) { + DBG("+\n"); _retm_if(tethering == NULL, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; int i = 0; - for (i = 0; sigs[i].cb != NULL; i++) { - dbus_g_proxy_add_signal(proxy, sigs[i].name, - G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(proxy, sigs[i].name, - G_CALLBACK(sigs[i].cb), (gpointer)tethering, NULL); + for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++) { + sigs[i].sig_id = g_dbus_connection_signal_subscribe(connection, + NULL, TETHERING_SERVICE_INTERFACE, sigs[i].name, + TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + sigs[i].cb, tethering, NULL); } - - dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_STRING_STRING_STRING, - G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_add_signal(proxy, SIGNAL_NAME_DHCP_STATUS, - G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_DHCP_STATUS, - G_CALLBACK(__handle_dhcp), (gpointer)tethering, NULL); - - return; + DBG("-\n"); } static void __disconnect_signals(tethering_h tethering) { + DBG("+\n"); + _retm_if(tethering == NULL, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; int i = 0; - for (i = 0; sigs[i].cb != NULL; i++) { - dbus_g_proxy_disconnect_signal(proxy, sigs[i].name, - G_CALLBACK(sigs[i].cb), (gpointer)tethering); - } + for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++) + g_dbus_connection_signal_unsubscribe(connection, sigs[i].sig_id); + DBG("-\n"); +} - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_DHCP_STATUS, - G_CALLBACK(__handle_dhcp), (gpointer)tethering); - return; -} 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; @@ -710,7 +1150,6 @@ static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len) ERR("Not supported type : %d\n", type); return false; } - return true; } @@ -735,139 +1174,275 @@ static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int le ERR("Not supported type : %d\n", type); return false; } - return true; } -static void __deinit_cb(DBusGProxy *remoteobj, - GError *error, gpointer user_data) +static int __get_common_ssid(char *ssid, unsigned int size) { - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - if (error) { - ERR("DBus fail [%s]\n", error->message); - g_error_free(error); + if (ssid == NULL) { + ERR("ssid is null\n"); //LCOV_EXCL_LINE + return TETHERING_ERROR_INVALID_PARAMETER; } - return; -} - -static void __wifi_set_security_type_cb(DBusGProxy *remoteobj, - GError *error, gpointer user_data) -{ - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + char *ptr = NULL; + char *ptr_tmp = NULL; - tethering_h tethering = (tethering_h)user_data; - __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR); + if (ptr == NULL) { + ERR("vconf_get_str is failed and set default ssid"); + g_strlcpy(ssid, TETHERING_DEFAULT_SSID, size); + } else + g_strlcpy(ssid, ptr, size); - if (error) { - ERR("DBus fail [%s]\n", error->message); - g_error_free(error); - } + free(ptr); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED, - G_CALLBACK(__handle_security_type_changed), - (gpointer)tethering, NULL); + if (!g_utf8_validate(ssid, -1, (const char **)&ptr_tmp)) + *ptr_tmp = '\0'; - return; + return TETHERING_ERROR_NONE; } -static void __wifi_set_ssid_visibility_cb(DBusGProxy *remoteobj, - GError *error, gpointer user_data) +static bool __get_wifi_mode_type(tethering_wifi_mode_type_e type, char **buf) { - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); - - tethering_h tethering = (tethering_h)user_data; - __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - - if (error) { - ERR("DBus fail [%s]\n", error->message); - g_error_free(error); - } + _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n"); - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, - G_CALLBACK(__handle_ssid_visibility_changed), - (gpointer)tethering, NULL); - - return; + 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 void __wifi_set_passphrase_cb(DBusGProxy *remoteobj, - GError *error, gpointer user_data) +static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *set) { - _retm_if(user_data == NULL, "parameter(user_data) is NULL\n"); + INFO("+\n"); - tethering_h tethering = (tethering_h)user_data; __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + tethering_error_e ret = TETHERING_ERROR_NONE; + char *ptr = NULL; - if (error) { - ERR("DBus fail [%s]\n", error->message); - g_error_free(error); + if (th == NULL || set == NULL) { + ERR("null parameter\n-\n"); + return TETHERING_ERROR_INVALID_PARAMETER; } - dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED, - G_CALLBACK(__handle_passphrase_changed), - (gpointer)tethering, NULL); + if (th->ssid == NULL) + __get_common_ssid(set->ssid, sizeof(set->ssid)); + else + g_strlcpy(set->ssid, th->ssid, sizeof(set->ssid)); + + ret = __get_security_type(&set->sec_type); + if (ret != TETHERING_ERROR_NONE) + set->sec_type = th->sec_type; - return; + ret = __get_visible(&set->visibility); + 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 { + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters; + GError *error = NULL; + char *passphrase = NULL; + unsigned int len = 0; + + parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_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) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + //LCOV_EXCL_STOP + } + + if (parameters != NULL) { + g_variant_get(parameters, "(siu)", &passphrase, &len, &ret); + g_variant_unref(parameters); + } + + g_strlcpy(set->key, passphrase, sizeof(set->key)); + } + + 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"); + INFO("-\n"); + return TETHERING_ERROR_NONE; +} + +static bool __check_precondition(tethering_type_e type) +{ + int dnet_state = 0; + int cellular_state = 0; + int wifi_state = 0; + + /* data network through cellular */ + vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state); + if (cellular_state == VCONFKEY_NETWORK_CELLULAR_ON) { + INFO("Data Network can be connected later"); + return TRUE; + } + +#ifdef TIZEN_TV_EXT + /* data network through ethernet */ + vconf_get_int(VCONFKEY_NETWORK_STATUS, &dnet_state); + if (dnet_state == VCONFKEY_NETWORK_ETHERNET) { + INFO("Data Network is connected"); + return TRUE; + } +#else + vconf_get_int(VCONFKEY_DNET_STATE, &dnet_state); + if (dnet_state > VCONFKEY_DNET_OFF) { + INFO("Data Network is connected"); + return TRUE; + } +#endif/*TIZEN_TV_EXT*/ + + /* data network through wifi */ + if (type != TETHERING_TYPE_WIFI) { + vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + if (wifi_state > VCONFKEY_WIFI_UNCONNECTED) { + INFO("Wi-Fi is connected!"); + return TRUE; + } + } + + ERR("Network is not available!"); + return FALSE; } /** + * @internal * @brief Creates the handle of tethering. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks The @a tethering must be released tethering_destroy() by you. * @param[out] tethering A handle of a new mobile ap handle on success * @return 0 on success, otherwise a 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_NOT_SUPPORT_API API is not supported * @see tethering_destroy() */ API int tethering_create(tethering_h *tethering) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); + INFO("+\n"); __tethering_h *th = NULL; GError *error = NULL; + char ssid[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, }; th = (__tethering_h *)malloc(sizeof(__tethering_h)); + _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY, "malloc is failed\n"); 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"); //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"); //LCOV_EXCL_LINE + free(th); + return TETHERING_ERROR_OPERATION_FAILED; + } +#if !GLIB_CHECK_VERSION(2, 36, 0) g_type_init(); - th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); +#endif + 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); free(th); return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP } + th->cancellable = cancellable; - th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus, - TETHERING_SERVICE_NAME, - TETHERING_SERVICE_OBJECT_PATH, - TETHERING_SERVICE_INTERFACE); + 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"); - dbus_g_connection_unref(th->client_bus); + //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); free(th); return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP } __connect_signals((tethering_h)th); *tethering = (tethering_h)th; - DBG("Tethering Handle : 0x%X\n", th); - + INFO("Tethering Handle : 0x%X\n", th); + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Destroys the handle of tethering. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @return 0 on success, otherwise a negative error value. * @retval #TETHERING_ERROR_NONE Successful @@ -876,27 +1451,36 @@ API int tethering_create(tethering_h *tethering) */ API int tethering_destroy(tethering_h tethering) { + INFO("+\n"); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - DBG("Tethering Handle : 0x%X\n", th); + INFO("Tethering Handle : 0x%X\n", th); + __disconnect_signals(tethering); - com_samsung_mobileap_deinit_async(th->client_bus_proxy, __deinit_cb, - (gpointer)tethering); + if (th->ssid) + free(th->ssid); + g_object_unref(th->cancellable); g_object_unref(th->client_bus_proxy); - dbus_g_connection_unref(th->client_bus); + g_object_unref(th->client_bus); memset(th, 0x00, sizeof(__tethering_h)); free(th); + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Enables the tethering, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @return 0 on success, otherwise negative error value. @@ -906,75 +1490,248 @@ API int tethering_destroy(tethering_h tethering) * @see tethering_is_enabled() * @see tethering_disable() */ -int tethering_enable(tethering_h tethering, tethering_type_e type) +API int tethering_enable(tethering_h tethering, tethering_type_e type) { - DBG("+\n"); + INFO("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); + tethering_error_e ret = TETHERING_ERROR_NONE; __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE); + + if (__check_precondition(type) == FALSE) { + //LCOV_EXCL_START + INFO("-\n"); + return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP + } switch (type) { + //LCOV_EXCL_START case TETHERING_TYPE_USB: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON, - G_CALLBACK(__handle_usb_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_usb_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_ON].sig_id); + + g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL, + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); break; + //LCOV_EXCL_STOP - case TETHERING_TYPE_WIFI: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON, - G_CALLBACK(__handle_wifi_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false, - __cfm_cb, (gpointer)tethering); + case TETHERING_TYPE_WIFI: { + _softap_settings_t set = {"", "", "", 0, false}; + + ret = __prepare_wifi_settings(tethering, &set); + if (ret != TETHERING_ERROR_NONE) { + ERR("softap settings initialization failed\n"); + DBG("-\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + 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("(sssiiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type, TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); break; + } case TETHERING_TYPE_BT: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON, - G_CALLBACK(__handle_bt_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_bt_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_ON].sig_id); + + g_dbus_proxy_call(proxy, "enable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); break; - case TETHERING_TYPE_ALL: + //LCOV_EXCL_START + case TETHERING_TYPE_ALL: { + _softap_settings_t set = {"", "", "", 0, false}; + + ret = __prepare_wifi_settings(tethering, &set); + if (ret != TETHERING_ERROR_NONE) { + ERR("softap settings initialization failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + /* TETHERING_TYPE_USB */ - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON, - G_CALLBACK(__handle_usb_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_usb_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_ON].sig_id); + + g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL, + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering); /* TETHERING_TYPE_WIFI */ - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON, - G_CALLBACK(__handle_wifi_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false, - __cfm_cb, (gpointer)tethering); + 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("(sssiiiiii)", set.ssid, set.key, set.mode, + set.channel, set.visibility, set.mac_filter, set.max_connected, + set.sec_type, TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); /* TETHERING_TYPE_BT */ - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON, - G_CALLBACK(__handle_bt_tether_on), - (gpointer)tethering); - com_samsung_mobileap_enable_bt_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); - break; + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_ON].sig_id); + g_dbus_proxy_call(proxy, "enable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + 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); + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + + DBG("-\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + INFO("-\n"); + return TETHERING_ERROR_NONE; +} + +API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type) +{ + DBG("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; + int ret = 0; + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE); + + if (__check_precondition(type) == FALSE) { + //LCOV_EXCL_START + DBG("-\n"); + return TETHERING_ERROR_OPERATION_FAILED; + //LCOV_EXCL_STOP + } + + switch (type) { + //LCOV_EXCL_START + case TETHERING_TYPE_WIFI: { + _softap_settings_t set = {"", "", "", 0, false, false, 0, 0}; + + ret = __prepare_wifi_settings(tethering, &set); + if (ret != TETHERING_ERROR_NONE) { + ERR("softap settings initialization failed\n"); + DBG("-\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + 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("(sssiiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type, TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering); + break; + } + case TETHERING_TYPE_BT: { + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_ON].sig_id); + + /* For TEST */ + g_dbus_proxy_call(proxy, "enable_bt_tethering", g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering); + + break; + } + + default: { + ERR("Unknown type : %d\n", type); + + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + + DBG("-\n"); return TETHERING_ERROR_INVALID_PARAMETER; } + } + g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT); + DBG("-\n"); return TETHERING_ERROR_NONE; } +API int tethering_ipv6_disable(tethering_h tethering, tethering_type_e type) +{ + DBG("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; + + switch (type) { + case TETHERING_TYPE_WIFI: + DBG("Disable wifi tethering.."); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_wifi_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; + case TETHERING_TYPE_BT: + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; + + default: + ERR("Not supported tethering type [%d]\n", type); + DBG("-\n"); + return TETHERING_ERROR_INVALID_PARAMETER; + } + DBG("-\n"); + return TETHERING_ERROR_NONE; +} /** + * @internal * @brief Disables the tethering, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @return 0 on success, otherwise negative error value. @@ -986,79 +1743,106 @@ int tethering_enable(tethering_h tethering, tethering_type_e type) */ API int tethering_disable(tethering_h tethering, tethering_type_e type) { + INFO("+ type : %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusProxy *proxy = th->client_bus_proxy; + GDBusConnection *connection = th->client_bus; switch (type) { case TETHERING_TYPE_USB: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF, - G_CALLBACK(__handle_usb_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_usb_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_usb_tethering", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + break; case TETHERING_TYPE_WIFI: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF, - G_CALLBACK(__handle_wifi_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_wifi_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_wifi_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; + case TETHERING_TYPE_BT: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF, - G_CALLBACK(__handle_bt_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_bt_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; case TETHERING_TYPE_ALL: - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF, - G_CALLBACK(__handle_usb_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_usb_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); - - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF, - G_CALLBACK(__handle_wifi_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_wifi_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); - - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF, - G_CALLBACK(__handle_bt_tether_off), - (gpointer)tethering); - com_samsung_mobileap_disable_bt_tethering_async(proxy, - __cfm_cb, (gpointer)tethering); + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_USB_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_usb_tethering", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_wifi_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); + + g_dbus_connection_signal_unsubscribe(connection, + sigs[E_SIGNAL_BT_TETHER_OFF].sig_id); + + g_dbus_proxy_call(proxy, "disable_bt_tethering", + g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4), + G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering); break; - default : + default: ERR("Not supported tethering type [%d]\n", type); + DBG("-\n"); return TETHERING_ERROR_INVALID_PARAMETER; - break; } - + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Checks whetehr the tethering is enabled or not. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @return @c true if tethering is enabled, \n @c false if tethering is disabled. */ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) { + INFO("+ type : %d\n", type); int is_on = 0; int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE; - if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + + if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) return FALSE; - } switch (type) { case TETHERING_TYPE_USB: @@ -1077,12 +1861,16 @@ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) ERR("Not supported type : %d\n", type); break; } - + INFO("- enabled: %s\n", (is_on & vconf_type) ? "true" : "false"); return is_on & vconf_type ? true : false; } /** + * @internal * @brief Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1". + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a mac_address must be released with free() by you. * @param[in] tethering The handle of tethering * @param[in] type The type of tethering @@ -1097,15 +1885,20 @@ API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type) * @see tethering_is_enabled() * @see tethering_enable() */ -int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address) +API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _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(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(mac_address) is NULL\n"); - _retvm_if(tethering_is_enabled(tethering, type) == false, - TETHERING_ERROR_NOT_ENABLED, - "tethering type[%d] is not enabled\n", type); struct ifreq ifr; int s = 0; @@ -1142,7 +1935,11 @@ int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char } /** + * @internal * @brief Gets the name of network interface. For example, usb0. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a interface_name must be released with free() by you. * @param[in] tethering The handle of tethering * @param[in] type The type of tethering @@ -1159,13 +1956,18 @@ int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char */ API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering_is_enabled(tethering, type) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", type); _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(interface_name) is NULL\n"); - _retvm_if(tethering_is_enabled(tethering, type) == false, - TETHERING_ERROR_NOT_ENABLED, - "tethering type[%d] is not enabled\n", type); char intf[TETHERING_STR_INFO_LEN] = {0, }; @@ -1180,7 +1982,11 @@ API int tethering_get_network_interface_name(tethering_h tethering, tethering_ty } /** + * @internal * @brief Gets the local IP address. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a ip_address must be released with free() by you. * @param[in] tethering The handle of tethering * @param[in] type The type of tethering @@ -1198,13 +2004,18 @@ API int tethering_get_network_interface_name(tethering_h tethering, tethering_ty */ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _retvm_if(tethering_is_enabled(tethering, type) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", type); _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"); - _retvm_if(tethering_is_enabled(tethering, type) == false, - TETHERING_ERROR_NOT_ENABLED, - "tethering type[%d] is not enabled\n", type); struct ifreq ifr; int s = 0; @@ -1233,7 +2044,11 @@ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, t } /** + * @internal * @brief Gets the Gateway address. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a gateway_address must be released with free() by you. * @param[in] tethering The handle of tethering * @param[in] type The type of tethering @@ -1251,13 +2066,18 @@ API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, t */ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + + _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, }; @@ -1271,7 +2091,11 @@ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e ty } /** + * @internal * @brief Gets the Subnet Mask. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a subnet_mask must be released with free() by you. * @param[in] tethering The handle of tethering * @param[in] type The type of tethering @@ -1287,13 +2111,18 @@ API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e ty * @see tethering_is_enabled() * @see tethering_enable() */ -int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask) +API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask) { - _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering_is_enabled(tethering, type) == false, TETHERING_ERROR_NOT_ENABLED, "tethering is not enabled\n"); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(subnet_mask) is NULL\n"); @@ -1305,7 +2134,11 @@ int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, teth } /** + * @internal * @brief Gets the data usage. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[out] usage The data usage * @return 0 on success, otherwise negative error value. @@ -1319,6 +2152,8 @@ int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, teth */ API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1328,19 +2163,24 @@ API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb "tethering is not enabled\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusProxy *proxy = th->client_bus_proxy; th->data_usage_cb = callback; th->data_usage_user_data = user_data; - com_samsung_mobileap_get_data_packet_usage_async(proxy, - __get_data_usage_cb, (gpointer)th); + g_dbus_proxy_call(proxy, "get_data_packet_usage", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable, + (GAsyncReadyCallback) __get_data_usage_cb, (gpointer)tethering); return TETHERING_ERROR_NONE; } /** - * @brief Gets the client which is connected by USB tethering. + * @internal + * @brief Gets the client which is connected by tethering "type". + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @param[in] callback The callback function to invoke @@ -1355,6 +2195,11 @@ API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb */ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1363,64 +2208,99 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ TETHERING_ERROR_NOT_ENABLED, "tethering is not enabled\n"); + mobile_ap_type_e interface; __tethering_h *th = (__tethering_h *)tethering; __tethering_client_h client = {0, }; - - guint event = 0; - GPtrArray *array = NULL; - GValue value = {0, {{0}}}; - GError *error = NULL; - int i = 0; - int no_of_client = 0; - guint interface = 0; gchar *ip = NULL; gchar *mac = NULL; gchar *hostname = NULL; - - com_samsung_mobileap_get_station_info(th->client_bus_proxy, &event, - &array, &error); - if (error != NULL) { - ERR("DBus fail : %s\n", error->message); - g_error_free(error); - return TETHERING_ERROR_OPERATION_FAILED; - } - - g_value_init(&value, DBUS_STRUCT_STATIONS); - no_of_client = array->len; - for (i = 0; i < no_of_client; i++) { - g_value_set_boxed(&value, g_ptr_array_index(array, i)); - - dbus_g_type_struct_get(&value, 0, &interface, 1, &ip, - 2, &mac, 3, &hostname, G_MAXUINT); - - if (interface == MOBILE_AP_TYPE_USB) - client.interface = TETHERING_TYPE_USB; - else if (interface == MOBILE_AP_TYPE_WIFI) - client.interface = TETHERING_TYPE_WIFI; - else if (interface == MOBILE_AP_TYPE_BT) - client.interface = TETHERING_TYPE_BT; - - if (client.interface != type && TETHERING_TYPE_ALL != type) - continue; - - g_strlcpy(client.ip, ip, sizeof(client.ip)); - g_strlcpy(client.mac, mac, sizeof(client.mac)); - g_strlcpy(client.hostname, hostname, sizeof(client.hostname)); - + guint timestamp = 0; + GError *error = NULL; + GVariant *result = NULL; + GVariantIter *outer_iter = NULL; + GVariantIter *inner_iter = NULL; + GVariant *station = NULL; + GVariant *value = NULL; + gchar *key = NULL; + + result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info", + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + if (error) + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_variant_get(result, "(a(a{sv}))", &outer_iter); + while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) { + g_variant_get(station, "a{sv}", &inner_iter); + while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) { + if (g_strcmp0(key, "Type") == 0) { + interface = g_variant_get_int32(value); + if (interface == MOBILE_AP_TYPE_USB) + client.interface = TETHERING_TYPE_USB; + else if (interface == MOBILE_AP_TYPE_WIFI) + client.interface = TETHERING_TYPE_WIFI; + else if (interface == MOBILE_AP_TYPE_BT) + client.interface = TETHERING_TYPE_BT; + else { + ERR("Invalid interface\n"); + g_free(key); + g_variant_unref(value); + break; + } + DBG("interface is %d\n", client.interface); + if (client.interface != type && (TETHERING_TYPE_ALL != type)) { + g_free(key); + g_variant_unref(value); + break; + } + } else if (g_strcmp0(key, "IP") == 0) { + g_variant_get(value, "s", &ip); + SDBG("ip is %s\n", ip); + g_strlcpy(client.ip, ip, sizeof(client.ip)); + } else if (g_strcmp0(key, "MAC") == 0) { + g_variant_get(value, "s", &mac); + SDBG("mac is %s\n", mac); + g_strlcpy(client.mac, mac, sizeof(client.mac)); + } else if (g_strcmp0(key, "Name") == 0) { + g_variant_get(value, "s", &hostname); + SDBG("hsotname is %s\n", hostname); + if (hostname) + client.hostname = g_strdup(hostname); + } else if (g_strcmp0(key, "Time") == 0) { + timestamp = g_variant_get_int32(value); + DBG("timestamp is %d\n", timestamp); + client.tm = (time_t)timestamp; + } else { + ERR("Key %s not required\n", key); + } + } + g_free(hostname); + g_free(ip); + g_free(mac); + g_variant_iter_free(inner_iter); if (callback((tethering_client_h)&client, user_data) == false) { DBG("iteration is stopped\n"); - return TETHERING_ERROR_NONE; + g_free(client.hostname); + g_variant_iter_free(outer_iter); + g_variant_unref(station); + g_variant_unref(result); + DBG("-\n"); + return TETHERING_ERROR_OPERATION_FAILED; } + g_free(client.hostname); } - - if (array->len > 0) - g_ptr_array_free(array, TRUE); - + g_variant_iter_free(outer_iter); + g_variant_unref(station); + g_variant_unref(result); + DBG("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Registers the callback function called when tethering is enabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @param[in] callback The callback function to invoke @@ -1431,6 +2311,12 @@ API int tethering_foreach_connected_clients(tethering_h tethering, tethering_typ */ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data) { + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1452,11 +2338,16 @@ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, t th->enabled_user_data[ti] = user_data; } + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Unregisters the callback function called when tethering is disabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @retval #TETHERING_ERROR_NONE Successful @@ -1465,6 +2356,11 @@ API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, t */ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1488,7 +2384,11 @@ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) } /** + * @internal * @brief Registers the callback function called when tethering is disabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @param[in] callback The callback function to invoke @@ -1499,6 +2399,12 @@ API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type) */ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data) { + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1519,12 +2425,16 @@ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, th->disabled_cb[ti] = callback; th->disabled_user_data[ti] = user_data; } - + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Unregisters the callback function called when tethering is disabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @retval #TETHERING_ERROR_NONE Successful @@ -1533,6 +2443,11 @@ API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, */ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1556,7 +2471,11 @@ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type } /** + * @internal * @brief Registers the callback function called when the state of connection is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @param[in] callback The callback function to invoke @@ -1567,6 +2486,12 @@ API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type */ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data) { + INFO("+ type: %d\n", type); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1587,12 +2512,16 @@ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tetheri th->changed_cb[ti] = callback; th->changed_user_data[ti] = user_data; } - + INFO("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Unregisters the callback function called when the state of connection is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @retval #TETHERING_ERROR_NONE Successful @@ -1601,6 +2530,11 @@ API int tethering_set_connection_state_changed_cb(tethering_h tethering, tetheri */ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); + else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1624,7 +2558,11 @@ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethe } /** + * @internal * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @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 @@ -1634,6 +2572,9 @@ API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethe */ API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1649,7 +2590,11 @@ API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethe } /** + * @internal * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[in] type The type of tethering * @retval #TETHERING_ERROR_NONE Successful @@ -1658,6 +2603,9 @@ API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethe */ API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1670,7 +2618,11 @@ API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering) } /** + * @internal * @brief Registers the callback function called when the visibility of SSID is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @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 @@ -1680,6 +2632,9 @@ API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering) */ API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1694,7 +2649,11 @@ API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tet } /** + * @internal * @brief Unregisters the callback function called when the visibility of SSID is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @retval #TETHERING_ERROR_NONE Successful * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter @@ -1702,6 +2661,9 @@ API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tet */ API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1714,7 +2676,11 @@ API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering) } /** + * @internal * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @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 @@ -1724,6 +2690,9 @@ API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering) */ API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, @@ -1738,7 +2707,11 @@ API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tetherin } /** + * @internal * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @retval #TETHERING_ERROR_NONE Successful * @retval #TETHERING_ERROR_INVALID_PARAMETER Invalid parameter @@ -1746,6 +2719,9 @@ API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tetherin */ API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); @@ -1758,51 +2734,59 @@ API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering) } /** + * @internal * @brief Sets the security type of Wi-Fi tethering. - * @remarks You must set this value when Wi-Fi tethering is disabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin + * @remarks This change is applied next time Wi-Fi tethering is enabled * @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 - * @retval #TETHERING_ERROR_INVALID_OPERATION Invalid operation - * @pre Wi-Fi tethering must be disabled. - * @see tethering_is_enabled() * @see tethering_wifi_get_security_type() */ API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - DBG("+\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - char *type_str = NULL; + 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; + } - if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) { - type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR; - } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) { - type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR; - } else { - ERR("Unsupported type\n"); - return TETHERING_ERROR_INVALID_PARAMETER; + __send_dbus_signal(th->client_bus, + SIGNAL_NAME_SECURITY_TYPE_CHANGED, sec_str); } - - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED, - G_CALLBACK(__handle_security_type_changed), - (gpointer)tethering); - - com_samsung_mobileap_set_wifi_tethering_security_type_async(proxy, type_str, - __wifi_set_security_type_cb, (gpointer)tethering); - - DBG("-\n"); - return TETHERING_ERROR_NONE; + return ret; } /** + * @internal * @brief Gets the security type of Wi-Fi tethering. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @param[in] tethering The handle of tethering * @param[out] type The security type * @return 0 on success, otherwise negative error value. @@ -1813,133 +2797,161 @@ API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_s */ API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type) { - _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(type) is NULL\n"); - DBG("+\n"); - - __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - GError *error = NULL; - char *type_str = NULL; - - com_samsung_mobileap_get_wifi_tethering_security_type(proxy, &type_str, &error); - if (error != NULL) { - ERR("DBus fail : %s\n", error->message); - g_error_free(error); - return TETHERING_ERROR_OPERATION_FAILED; - } - - if (type_str == NULL) - return TETHERING_ERROR_OPERATION_FAILED; - - DBG("security type : %s\n", type_str); - if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0) - *type = TETHERING_WIFI_SECURITY_TYPE_NONE; - else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0) - *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK; - else { - ERR("Unknown security type : %s\n", type_str); - g_free(type_str); - return TETHERING_ERROR_OPERATION_FAILED; - } - - g_free(type_str); - DBG("-\n"); - return TETHERING_ERROR_NONE; + return __get_security_type(type); } /** - * @brief Gets the SSID (service set identifier). - * @remarks @a ssid must be released with free() by you. + * @internal + * @brief Sets the SSID (service set identifier). + * @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 This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle * @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 - * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed */ -API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid) +API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid) { + 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(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(ssid) is NULL\n"); - DBG("+\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - GError *error = NULL; - char *ssid_buf = NULL; + char *p_ssid = NULL; + int ssid_len = 0; - com_samsung_mobileap_get_wifi_tethering_ssid(proxy, &ssid_buf, &error); - if (error != NULL) { - ERR("dbus fail : %s\n", error->message); - g_error_free(error); - return TETHERING_ERROR_OPERATION_FAILED; + ssid_len = strlen(ssid); + if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) { + ERR("parameter(ssid) is too long"); + return TETHERING_ERROR_INVALID_PARAMETER; } - if (ssid_buf == NULL) - return TETHERING_ERROR_OPERATION_FAILED; + p_ssid = strdup(ssid); + _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY, + "strdup is failed\n"); + + if (th->ssid) + free(th->ssid); + th->ssid = p_ssid; + + return TETHERING_ERROR_NONE; +} + +/** + * @internal + * @brief Gets the SSID (service set identifier). + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin + * @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 + * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed + */ +API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid) +{ + 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(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(ssid) is NULL\n"); + DBG("+\n"); + + __tethering_h *th = (__tethering_h *)tethering; + char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, }; + + if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) { + if (th->ssid != NULL) { + DBG("Private SSID is set\n"); + *ssid = strdup(th->ssid); + } else { + if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR, + val, sizeof(val)) == false) { + return TETHERING_ERROR_OPERATION_FAILED; + } + *ssid = strdup(val); + } + } else { + if (__get_ssid_from_vconf(VCONFKEY_MOBILE_HOTSPOT_SSID, + val, sizeof(val)) == false) { + return TETHERING_ERROR_OPERATION_FAILED; + } + *ssid = strdup(val); + } - *ssid = strdup(ssid_buf); if (*ssid == NULL) { - ERR("Memory allocation failed\n"); + ERR("strdup is failed\n"); return TETHERING_ERROR_OUT_OF_MEMORY; } - g_free(ssid_buf); - - DBG("-\n"); return TETHERING_ERROR_NONE; } /** + * @internal * @brief Sets the visibility of SSID(service set identifier). + * @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. - * @remarks You must set this value when Wi-Fi tethering is disabled. + * @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 - * @retval #TETHERING_ERROR_INVALID_OPERATION Invalid operation - * @pre Wi-Fi tethering must be disabled. - * @see tethering_is_enabled() * @see tethering_wifi_get_ssid_visibility() */ -int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) +API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); - DBG("+\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - int hide_mode = 0; + tethering_error_e ret = TETHERING_ERROR_NONE; - if (visible) - hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF; - else - hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON; - - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, - G_CALLBACK(__handle_ssid_visibility_changed), - (gpointer)tethering); + ret = __set_visible(visible); + if (ret == TETHERING_ERROR_NONE) { - com_samsung_mobileap_set_wifi_tethering_hide_mode_async(proxy, hide_mode, - __wifi_set_ssid_visibility_cb, (gpointer)tethering); - - DBG("-\n"); - return TETHERING_ERROR_NONE; + __send_dbus_signal(th->client_bus, + SIGNAL_NAME_SSID_VISIBILITY_CHANGED, + visible ? SIGNAL_MSG_SSID_VISIBLE : + SIGNAL_MSG_SSID_HIDE); + } + return ret; } /** + * @internal * @brief Gets the visibility of SSID(service set identifier). + * @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. * @param[in] tethering The handle of tethering * @param[out] visible The visibility of SSID: (@c true = visible, @c false = invisible) @@ -1951,73 +2963,90 @@ int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible) */ API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible) { - _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, - "parameter(tethering) is NULL\n"); + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(visible) is NULL\n"); - DBG("+\n"); - - __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; - GError *error = NULL; - int hide_mode = 0; - - com_samsung_mobileap_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error); - if (error != NULL) { - ERR("dbus fail : %s\n", error->message); - g_error_free(error); - return TETHERING_ERROR_OPERATION_FAILED; - } - DBG("hide mode : %d\n", hide_mode); - - if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF) - *visible = true; - else - *visible = false; - DBG("-\n"); - return TETHERING_ERROR_NONE; + return __get_visible(visible); } /** + * @internal * @brief Sets the passphrase. - * @remarks You must set this value when Wi-Fi tethering is disabled. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin + * @remarks This change is applied next time Wi-Fi tethering is enabled * @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 * @retval #TETHERING_ERROR_OPERATION_FAILED Operation failed - * @retval #TETHERING_ERROR_INVALID_OPERATION Invalid operation - * @pre Wi-Fi tethering must be disabled. - * @see tethering_is_enabled() * @see tethering_wifi_get_passphrase() */ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(passphrase) is NULL\n"); - DBG("+\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters; + GError *error = NULL; + int passphrase_len = 0; + int ret = 0; + + DBG("+"); + passphrase_len = strlen(passphrase); + 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; + } - dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED, - G_CALLBACK(__handle_passphrase_changed), - (gpointer)tethering); + parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_passphrase", + g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - com_samsung_mobileap_set_wifi_tethering_passphrase_async(proxy, - passphrase, strlen(passphrase), - __wifi_set_passphrase_cb, (gpointer)tethering); + if (error) { + //LCOV_EXCL_START + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); - DBG("-\n"); - return TETHERING_ERROR_NONE; + 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; + //LCOV_EXCL_STOP + } + + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + + if (ret == TETHERING_ERROR_NONE) { + __send_dbus_signal(th->client_bus, + SIGNAL_NAME_PASSPHRASE_CHANGED, NULL); + } + + DBG("-"); + return ret; } /** + * @internal * @brief Gets the passphrase. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/tethering.admin * @remarks @a passphrase must be released with free() by you. * @param[in] tethering The handle of tethering * @param[out] passphrase The passphrase @@ -2030,37 +3059,1107 @@ API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphr */ API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase) { + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(tethering) is NULL\n"); _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER, "parameter(passphrase) is NULL\n"); - DBG("+\n"); __tethering_h *th = (__tethering_h *)tethering; - DBusGProxy *proxy = th->client_bus_proxy; + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters; GError *error = NULL; - char *passphrase_buf = NULL; unsigned int len = 0; + tethering_error_e ret = TETHERING_ERROR_NONE; + + parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_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) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; - com_samsung_mobileap_get_wifi_tethering_passphrase(proxy, - &passphrase_buf, &len, &error); - if (error != NULL) { - ERR("dbus fail : %s\n", error->message); g_error_free(error); + return ret; + //LCOV_EXCL_STOP + } + + if (parameters != NULL) { + g_variant_get(parameters, "(siu)", passphrase, &len, &ret); + g_variant_unref(parameters); + } + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_channel(tethering_h tethering, int channel) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + th->channel = channel; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_channel(tethering_h tethering, int *channel) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(channel) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *channel = th->channel; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + th->mode_type = type; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(type) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *type = th->mode_type; + + return TETHERING_ERROR_NONE; +} + + +/** + * @internal + * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility). + * @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) + +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(callback) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + _softap_settings_t set = {"", "", "", 0, false}; + GDBusProxy *proxy = th->client_bus_proxy; + int ret = 0; + + DBG("+\n"); + + if (th->settings_reloaded_cb) { + ERR("Operation in progress\n"); return TETHERING_ERROR_OPERATION_FAILED; } - if (passphrase_buf == NULL) + 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; - *passphrase = strdup(passphrase_buf); - if (*passphrase == NULL) { - ERR("Memory allocation failed\n"); + 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; +} + +API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + th->mac_filter = mac_filter; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac_filter) is NULL\n"); + _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac_filter) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *mac_filter = th->mac_filter; + + return TETHERING_ERROR_NONE; +} + +static int __add_mac_to_file(const char *filepath, const char *mac) +{ + FILE *fp = NULL; + char line[MAX_BUF_SIZE] = "\0"; + bool mac_exist = false; + char *p_mac = NULL; + + p_mac = strdup(mac); + if (p_mac == NULL) { + ERR("strdup failed\n"); return TETHERING_ERROR_OUT_OF_MEMORY; } - g_free(passphrase_buf); + fp = fopen(filepath, "a+"); + if (!fp) { + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } - DBG("-\n"); + while (fgets(line, MAX_BUF_SIZE, fp) != NULL) { + if (strncmp(mac, line, 17) == 0) { + DBG("MAC %s already exist in the list\n", mac); + mac_exist = true; + break; + } + } + + 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); + + return TETHERING_ERROR_NONE; +} + +static int __remove_mac_from_file(const char *filepath, const char *mac) +{ + FILE *fp = NULL; + FILE *fp1 = NULL; + char line[MAX_BUF_SIZE] = "\0"; + + fp = fopen(filepath, "r"); + if (!fp) { + ERR("fopen is failed\n"); + return TETHERING_ERROR_OPERATION_FAILED; + } + + fp1 = fopen(TEMP_LIST, "w+"); + if (!fp1) { + fclose(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 found in the list\n", mac); + + if ((strcmp(filepath, ALLOWED_LIST) == 0)) { + GSList *list = NULL; + for (list = allowed_list; list != NULL; list = list->next) { + char *p_mac = (char *)list->data; + if (strncmp(mac, p_mac, strlen(mac)) == 0) + allowed_list = g_slist_remove(allowed_list, p_mac); + } + } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) { + GSList *list = NULL; + for (list = blocked_list; list != NULL; list = list->next) { + char *p_mac = (char *)list->data; + if (strncmp(mac, p_mac, strlen(mac)) == 0) + blocked_list = g_slist_remove(blocked_list, p_mac); + } + } + } else { + fprintf(fp1, "%s", line); + } + } + + fclose(fp); + fclose(fp1); + + if ((strcmp(filepath, ALLOWED_LIST) == 0)) + rename(TEMP_LIST, ALLOWED_LIST); + else if ((strcmp(filepath, BLOCKED_LIST) == 0)) + rename(TEMP_LIST, BLOCKED_LIST); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); + + return __add_mac_to_file(ALLOWED_LIST, mac); +} + +API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); + + return __remove_mac_from_file(ALLOWED_LIST, mac); +} + +API int tethering_wifi_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(allowed_mac_list) is NULL\n"); + + *allowed_mac_list = g_slist_copy(allowed_list); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); + + return __add_mac_to_file(BLOCKED_LIST, mac); +} + +API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _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 __remove_mac_from_file(BLOCKED_LIST, mac); +} + +API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _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); + 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_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); + CHECK_FEATURE_SUPPORTED(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); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(dhcp_enabled) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + *dhcp_enabled = th->dhcp_enabled; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_txpower(tethering_h tethering, unsigned int txpower) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + GError *error = NULL; + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI); + __tethering_h *th = (__tethering_h *)tethering; + + g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_set_txpower", + g_variant_new("(u)", txpower), + G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + if (error) { + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_clear_error(&error); + return TETHERING_ERROR_OPERATION_FAILED; + } + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_txpower(tethering_h tethering, unsigned int *txpower) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + GError *error = NULL; + GVariant *result = NULL; + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false, + TETHERING_ERROR_NOT_ENABLED, + "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI); + + __tethering_h *th = (__tethering_h *)tethering; + + result = g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_get_txpower", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, th->cancellable, &error); + + if (result != NULL) { + g_variant_get(result, "(u)", txpower); + g_variant_unref(result); + } else { + if (error) + ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); + g_clear_error(&error); + return TETHERING_ERROR_OPERATION_FAILED; + } + g_clear_error(&error); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_mtu(tethering_h tethering, unsigned int mtu) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "set_mtu", + g_variant_new("(u)", mtu), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + + g_variant_unref(parameters); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_change_mac(tethering_h tethering, char *mac) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(mac) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "change_mac", + g_variant_new("(s)", mac), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + if (result == MOBILE_AP_ERROR_NOT_PERMITTED) + return TETHERING_ERROR_NOT_SUPPORT_API; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + th->wifi_max_connected = max_device; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_max_connected_device(tethering_h tethering, int *max_device) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(max_device == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(max_device) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + *max_device = th->wifi_max_connected; + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_enable_port_forwarding(tethering_h tethering, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "enable_port_forwarding", + g_variant_new("(b)", enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + g_variant_unref(parameters); + + th->port_forwarding = true; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_port_forwarding_rule(tethering_h tethering, char *ifname, char *protocol, char *org_ip, int org_port, char *final_ip, int final_port) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(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; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_add_port_filtering_rule(tethering_h tethering, int port, char *protocol, bool allow) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(protocol) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + char 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); + 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_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); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(port_filtering_list) is NULL\n"); + + *port_filtering_list = g_slist_copy(port_filtering); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_get_custom_port_filtering_rule(tethering_h tethering, void **custom_port_filtering_list) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(custom_port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(custom_port_filtering_list) is NULL\n"); + + *custom_port_filtering_list = g_slist_copy(custom_port_filtering); + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_is_port_filtering_enabled(tethering_h tethering, bool* filtering_enabled) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + _retvm_if(filtering_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(filtering_enabled) is NULL\n"); + + __tethering_h *th = (__tethering_h *)tethering; + + *filtering_enabled = th->port_filtering; + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_vpn_passthrough_rule(tethering_h tethering, tethering_vpn_passthrough_type_e type, bool enable) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL\n"); + + GVariant *parameters; + GError *error = NULL; + guint result; + + __tethering_h *th = (__tethering_h *)tethering; + + GDBusProxy *proxy = th->client_bus_proxy; + + parameters = g_dbus_proxy_call_sync(proxy, "set_vpn_passthrough_rule", + g_variant_new("(ib)", type, enable), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + result = TETHERING_ERROR_PERMISSION_DENIED; + else + result = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return result; + } + + g_variant_get(parameters, "(u)", &result); + + g_variant_unref(parameters); + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_push_wps_button(tethering_h tethering) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL"); + __tethering_h *th = (__tethering_h *)tethering; + GDBusProxy *proxy = th->client_bus_proxy; + GVariant *parameters = NULL; + int ret = 0; + GError *error = NULL; + + parameters = g_dbus_proxy_call_sync(proxy, "push_wps_button", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error) { + ERR("g_dbus_proxy_call_sync failed because %s\n", error->message); + + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + ret = TETHERING_ERROR_PERMISSION_DENIED; + else + ret = TETHERING_ERROR_OPERATION_FAILED; + + g_error_free(error); + return ret; + } + + if (parameters != NULL) { + g_variant_get(parameters, "(u)", &ret); + g_variant_unref(parameters); + } + + return TETHERING_ERROR_NONE; +} + +API int tethering_wifi_set_wps_pin(tethering_h tethering, const char *wps_pin) +{ + CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE); + CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE); + + _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER, + "parameter(tethering) is NULL"); + __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; +} + +