Replace WPS scan to BSSID scan keywords.
[platform/core/connectivity/net-config.git] / src / wifi-wps.c
index ac222a0..38d4544 100755 (executable)
 
 static gboolean netconfig_is_wps_enabled = FALSE;
 static gboolean netconfig_is_device_scanning = FALSE;
-static gboolean netconfig_is_wps_scan_aborted = FALSE;
+static gboolean netconfig_is_bssid_scan_aborted = FALSE;
 static int wps_bss_list_count = 0;
 
-struct wps_bss_info_t {
+struct bssid_scan_info_t {
        unsigned char ssid[NETCONFIG_SSID_LEN + 1];
        unsigned char bssid[NETCONFIG_BSSID_LEN + 1];
        int ssid_len;
@@ -51,6 +51,13 @@ struct wps_bss_info_t {
        int mode;
 };
 
+struct netconfig_wifi_wps {
+       char *pin;
+       gboolean pbc;
+};
+
+static struct netconfig_wifi_wps wifi_wps;
+
 static GSList *wps_bss_info_list = NULL;
 
 static void __netconfig_wps_set_mode(gboolean enable)
@@ -66,6 +73,91 @@ gboolean netconfig_wifi_is_wps_enabled(void)
        return netconfig_is_wps_enabled;
 }
 
+void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key)
+{
+       GVariantBuilder *builder;
+       GVariant *params;
+       const char *sig_name = "WpsCredentials";
+       const char *prop_ssid = "ssid";
+       const char *prop_key = "key";
+       GVariantBuilder *rawssid_builder = NULL;
+       int i;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+       for (i = 0; i < ssid_len; i++)
+               g_variant_builder_add(rawssid_builder, "y", ssid[i]);
+       g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
+       g_variant_builder_unref(rawssid_builder);
+       g_variant_builder_add(builder, "{sv}", prop_key, g_variant_new_string(wps_key));
+
+       params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+       netconfig_dbus_emit_signal(NULL,
+                               NETCONFIG_WIFI_PATH,
+                               NETCONFIG_WIFI_INTERFACE,
+                               sig_name,
+                               params);
+
+       INFO("Sent signal (%s)", sig_name);
+       return;
+}
+
+void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len)
+{
+       GVariantBuilder *builder;
+       GVariant *params;
+       const char *sig_name = "WpsCompleted";
+       const char *prop_ssid = "ssid";
+       GVariantBuilder *rawssid_builder = NULL;
+       int i;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+       for (i = 0; i < ssid_len; i++)
+               g_variant_builder_add(rawssid_builder, "y", ssid[i]);
+       g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
+       g_variant_builder_unref(rawssid_builder);
+
+       params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+       netconfig_dbus_emit_signal(NULL,
+                               NETCONFIG_WIFI_PATH,
+                               NETCONFIG_WIFI_INTERFACE,
+                               sig_name,
+                               params);
+
+       INFO("Sent signal (%s)", sig_name);
+       return;
+}
+
+void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication)
+{
+       GVariantBuilder *builder;
+       GVariant *params;
+       const char *sig_name = "WpsFailEvent";
+       const char *prop_config_error = "config_error";
+       const char *prop_error_indication = "error_indication";
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       g_variant_builder_add(builder, "{sv}", prop_config_error, g_variant_new_int32(config_error));
+       g_variant_builder_add(builder, "{sv}", prop_error_indication, g_variant_new_int32(error_indication));
+
+       params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+       netconfig_dbus_emit_signal(NULL,
+                               NETCONFIG_WIFI_PATH,
+                               NETCONFIG_WIFI_INTERFACE,
+                               sig_name,
+                               params);
+
+       INFO("Sent signal (%s)", sig_name);
+       return;
+}
+
 static void __netconfig_wifi_wps_notify_scan_done(void)
 {
        GVariantBuilder *builder = NULL;
@@ -78,7 +170,7 @@ static void __netconfig_wifi_wps_notify_scan_done(void)
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
        for (list = wps_bss_info_list; list != NULL; list = list->next) {
-               struct wps_bss_info_t *bss_info = (struct wps_bss_info_t *)list->data;
+               struct bssid_scan_info_t *bss_info = (struct bssid_scan_info_t *)list->data;
 
                if (bss_info) {
                        gchar bssid_buff[18] = { 0, };
@@ -106,7 +198,7 @@ static void __netconfig_wifi_wps_notify_scan_done(void)
                }
        }
 
-       wifi_emit_wps_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
+       wifi_emit_bssid_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
        g_variant_builder_unref(builder);
 
        if (wps_bss_info_list != NULL)
@@ -114,7 +206,7 @@ static void __netconfig_wifi_wps_notify_scan_done(void)
 
        wps_bss_info_list = NULL;
        wps_bss_list_count = 0;
-       INFO("WpsScanCompleted");
+       INFO("BSSIDScanCompleted");
 
        return;
 }
@@ -126,7 +218,7 @@ static void __netconfig_wifi_wps_get_bss_info_result(
        GVariant *value;
        GVariantIter *iter;
        gchar *key;
-       struct wps_bss_info_t *bss_info;
+       struct bssid_scan_info_t *bss_info;
        GDBusConnection *conn = NULL;
        GError *error = NULL;
 
@@ -139,7 +231,7 @@ static void __netconfig_wifi_wps_get_bss_info_result(
                goto done;
        }
 
-       bss_info = g_try_new0(struct wps_bss_info_t, 1);
+       bss_info = g_try_new0(struct bssid_scan_info_t, 1);
        if (bss_info == NULL)
                goto done;
 
@@ -205,7 +297,7 @@ done:
        if (wps_bss_list_count <= 0) {
                __netconfig_wifi_wps_notify_scan_done();
 
-               if (netconfig_is_wps_scan_aborted == FALSE)
+               if (netconfig_is_bssid_scan_aborted == FALSE)
                        wifi_power_driver_and_supplicant(FALSE);
        }
 }
@@ -272,11 +364,11 @@ done:
 
        netconfig_gdbus_pending_call_unref();
 
-       /* Send WpsScanCompleted signal even when the BSS count is 0 */
+       /* Send BssidScanCompleted signal even when the BSS count is 0 */
        if (wps_bss_list_count <= 0 && counter_flag == FALSE) {
                __netconfig_wifi_wps_notify_scan_done();
 
-               if (netconfig_is_wps_scan_aborted == FALSE)
+               if (netconfig_is_bssid_scan_aborted == FALSE)
                        wifi_power_driver_and_supplicant(FALSE);
        }
 }
@@ -320,7 +412,7 @@ void netconfig_wifi_wps_signal_scandone(void)
 void netconfig_wifi_wps_signal_scanaborted(void)
 {
        wps_bss_list_count = 0;
-       netconfig_is_wps_scan_aborted = TRUE;
+       netconfig_is_bssid_scan_aborted = TRUE;
        _netconfig_wifi_wps_get_bsss();
 
        netconfig_is_device_scanning = FALSE;
@@ -328,7 +420,7 @@ void netconfig_wifi_wps_signal_scanaborted(void)
        __netconfig_wps_set_mode(FALSE);
 }
 
-static int __netconfig_wifi_wps_request_scan(const char *if_path)
+static int __netconfig_wifi_bssid_request_scan(const char *if_path)
 {
        GDBusConnection *connection = NULL;
        GVariant *message = NULL;
@@ -377,7 +469,7 @@ static int __netconfig_wifi_wps_request_scan(const char *if_path)
                wps_bss_info_list = NULL;
        }
 
-       netconfig_is_wps_scan_aborted = FALSE;
+       netconfig_is_bssid_scan_aborted = FALSE;
 
        return 0;
 }
@@ -397,19 +489,17 @@ static void __netconfig_wifi_interface_create_result(
                g_variant_get(message, "(o)", &path);
 
                if (path) {
-                       __netconfig_wifi_wps_request_scan(path);
+                       __netconfig_wifi_bssid_request_scan(path);
                        g_free(path);
                }
-       }
-       else if (NULL != strstr(error->message, ".InterfaceExists")) {
+       } else if (NULL != strstr(error->message, ".InterfaceExists")) {
                INFO("Error Message %s %s", error->message, path);
                g_variant_get(message, "(o)", &path);
                if (path) {
-                       __netconfig_wifi_wps_request_scan(path);
+                       __netconfig_wifi_bssid_request_scan(path);
                        g_free(path);
-               }
-               else
-                       __netconfig_wifi_wps_request_scan(NULL);
+               } else
+                       __netconfig_wifi_bssid_request_scan(NULL);
        } else {
                ERR("Failed to create interface, Error: %d[%s]", error->code, error->message);
                __netconfig_wps_set_mode(FALSE);
@@ -455,7 +545,7 @@ static int  __netconfig_wifi_wps_create_interface(void)
        return 0;
 }
 
-static int __netconfig_wifi_wps_scan(void)
+static int __netconfig_wifi_bssid_scan(void)
 {
        int err = 0;
        wifi_tech_state_e wifi_tech_state;
@@ -472,7 +562,7 @@ static int __netconfig_wifi_wps_scan(void)
 
        netconfig_is_device_scanning = TRUE;
 
-       DBG("WPS scan requested");
+       DBG("BSSID scan requested");
        if (wifi_tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
                if (netconfig_wifi_get_scanning() == TRUE)
                        return -EINPROGRESS;
@@ -480,7 +570,7 @@ static int __netconfig_wifi_wps_scan(void)
                netconfig_wifi_bgscan_start(TRUE);
 
                if (wifi_tech_state == NETCONFIG_WIFI_TECH_CONNECTED)
-                       __netconfig_wifi_wps_request_scan(NULL);
+                       __netconfig_wifi_bssid_request_scan(NULL);
        } else {
                err = __netconfig_wifi_wps_create_interface();
        }
@@ -488,7 +578,7 @@ static int __netconfig_wifi_wps_scan(void)
        return err;
 }
 
-gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context)
+gboolean handle_request_bssid_scan(Wifi *wifi, GDBusMethodInvocation *context)
 {
        int err, enabled = 0;
        wifi_tech_state_e tech_state;
@@ -512,7 +602,7 @@ gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context)
        tech_state = wifi_state_get_technology_state();
        if (tech_state <= NETCONFIG_WIFI_TECH_OFF) {
 #if !defined TIZEN_WEARABLE
-               vconf_get_int(VCONF_WIFI_ALWAYS_ALLOW_SCANNING, &enabled);
+               enabled = 1;
 #else
                enabled = 0;
 #endif
@@ -525,7 +615,7 @@ gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context)
 
        __netconfig_wps_set_mode(TRUE);
 
-       err = __netconfig_wifi_wps_scan();
+       err = __netconfig_wifi_bssid_scan();
        if (err < 0) {
                if (err == -EINPROGRESS)
                        netconfig_error_inprogress(context);
@@ -535,11 +625,131 @@ gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context)
                return FALSE;
        }
 
-       wifi_complete_request_wps_scan(wifi, context);
+       wifi_complete_request_bssid_scan(wifi, context);
        return TRUE;
 }
 
-#if defined TIZEN_TV
+static void interface_wps_start_result(GObject *source_object,
+                       GAsyncResult *res, gpointer user_data)
+{
+       GVariant *reply;
+       GDBusConnection *conn = NULL;
+       GError *error = NULL;
+
+       conn = G_DBUS_CONNECTION(source_object);
+       reply = g_dbus_connection_call_finish(conn, res, &error);
+
+       if (reply == NULL) {
+               if (error != NULL) {
+                       ERR("Fail to request status [%d: %s]",
+                                       error->code, error->message);
+                       g_error_free(error);
+               } else {
+                       ERR("Fail torequest status");
+               }
+       } else {
+               DBG("Successfully M/W--->WPAS: Interface.WPS.Start Method");
+       }
+
+       g_variant_unref(reply);
+       netconfig_gdbus_pending_call_unref();
+}
+
+static void __netconfig_wifi_invoke_wps_connect(GObject *source_object,
+                       GAsyncResult *res, gpointer user_data)
+{
+       GVariant *message = NULL;
+       GVariantBuilder *builder = NULL;
+       const char *role = "enrollee", *type, *key;
+       const char *if_path = NULL;
+       gboolean reply = FALSE;
+
+       if (if_path == NULL)
+               if_path = netconfig_wifi_get_supplicant_interface();
+
+       if (if_path == NULL) {
+               DBG("Fail to get wpa_supplicant DBus path");
+               return;
+       }
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+       key = "Role";
+       g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(role));
+
+       key = "Type";
+
+       if (wifi_wps.pbc == TRUE)
+               type = "pbc";
+       else
+               type = "pin";
+
+       g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(type));
+
+       if (wifi_wps.pin != NULL) {
+               key = "Pin";
+               g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(wifi_wps.pin));
+       }
+       message = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+       DBG("[net-config]: TizenMW-->WPAS: .Interface.WPS.Start");
+       reply = netconfig_supplicant_invoke_dbus_method_nonblock(
+                       SUPPLICANT_SERVICE,
+                       if_path,
+                       SUPPLICANT_IFACE_WPS,
+                       "Start",
+                       message,
+                       (GAsyncReadyCallback) interface_wps_start_result);
+
+       if (reply != TRUE)
+               ERR("Fail to Scan");
+
+       return;
+}
+
+static gboolean __netconfig_wifi_invoke_wps_process_credentials(const char *object_path)
+{
+       gboolean reply = FALSE;
+       GVariant *params = NULL;
+       const char *interface = SUPPLICANT_IFACE_WPS;
+       const char *key = "ProcessCredentials";
+       gboolean credentials = TRUE;
+       GVariant *var = NULL;
+
+        var = g_variant_new_boolean(credentials);
+       params = g_variant_new("(ssv)", interface, key, var);
+
+       INFO("[net-config]: TizenMW-->WPAS: .Set");
+       reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
+                       object_path, DBUS_INTERFACE_PROPERTIES,
+                       "Set", params, __netconfig_wifi_invoke_wps_connect);
+
+       if (reply != TRUE)
+               ERR("M/W--->WPAS: Interface.WPS.Set Method Failed");
+
+       return reply;
+}
+
+gboolean netconfig_wifi_wps_connect()
+{
+       const char *if_path = NULL;
+
+       if_path = netconfig_wifi_get_supplicant_interface();
+       if (if_path == NULL) {
+               DBG("Fail to get wpa_supplicant DBus path");
+                return FALSE;
+       }
+
+       if (__netconfig_wifi_invoke_wps_process_credentials(if_path) == TRUE) {
+               ERR("Wi-Fi WPS Connect started");
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static void __interface_wps_cancel_result(GObject *source_object,
                        GAsyncResult *res, gpointer user_data)
 {
@@ -588,16 +798,41 @@ static gboolean __netconfig_wifi_invoke_wps_cancel()
 
        return reply;
 }
-#endif
 
-gboolean netconfig_iface_wifi_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation **context)
+gboolean netconfig_get_wps_field()
+{
+       return wifi_wps.pbc;
+}
+
+gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context)
 {
-#if defined TIZEN_TV
-       DBG("Received WPS PBC Cancel Request");
+       INFO("Received WPS PBC Cancel Request");
        g_return_val_if_fail(wifi != NULL, FALSE);
-       return __netconfig_wifi_invoke_wps_cancel();
-#else
-       /*Not supported for mobile and Wearable profile*/
-       return FALSE;
-#endif
+       __netconfig_wifi_invoke_wps_cancel();
+
+       wifi_complete_request_wps_cancel(wifi, context);
+       return TRUE;
+}
+
+gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param)
+{
+       INFO("Received WPS PBC/PIN Connection Request");
+
+       g_return_val_if_fail(wifi != NULL, FALSE);
+
+       /* Checking the value of pin if param have a string "PBC"
+        * in that scenario PBC will trigger otherwise PIN Connection */
+
+       if (g_strcmp0(param, "PBC") == 0) {
+               wifi_wps.pbc = TRUE;
+               wifi_wps.pin = NULL;
+       } else {
+               wifi_wps.pin = g_strdup(param);
+               wifi_wps.pbc = FALSE;
+       }
+
+       netconfig_wifi_wps_connect();
+
+       wifi_complete_request_wps_connect(wifi, context);
+       return TRUE;
 }