#include "wifi.h"
+/* WPS Errors */
+#define WPS_CFG_NO_ERROR 0
+#define WPS_CFG_MSG_TIMEOUT 16
+#define WPS_EI_NO_ERROR 0
+#define WPS_EI_OPERATION_FAILED 1
+
gboolean netconfig_wifi_is_wps_enabled(void);
void netconfig_wifi_wps_signal_scandone(void);
void netconfig_wifi_wps_signal_scanaborted(void);
gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context);
-gboolean netconfig_iface_wifi_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation **context);
+gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param);
+gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context);
+void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len);
+void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication);
+void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key);
+gboolean netconfig_get_wps_field();
+gboolean netconfig_wifi_wps_connect();
#ifdef __cplusplus
}
</method>
<method name="RequestWpsScan">
</method>
+ <method name="RequestWpsCancel">
+ </method>
+ <method name="RequestWpsConnect">
+ <arg type="s" name="param" direction="in"/>
+ </method>
<method name="GetPasspoint">
<arg type="i" name="enable" direction="out"/>
</method>
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="DeleteEapConfig" privilege="http://tizen.org/privilege/network.profile" />
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="RequestSpecificScan" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="RequestWpsScan" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="RequestWpsCancel" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="RequestWpsConnect" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="CreateEapConfig" privilege="http://tizen.org/privilege/network.profile" />
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="LoadDriver" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.netconfig" send_interface="net.netconfig.wifi" send_member="RemoveDriver" privilege="http://tizen.org/privilege/network.set" />
#define SIGNAL_TDLS_CONNECTED "TDLSConnected"
#define SIGNAL_TDLS_DISCONNECTED "TDLSDisconnected"
#define SIGNAL_TDLS_PEER_FOUND "TDLSPeerFound"
+
+#define SIGNAL_WPS_CONNECTED "WPSConnected"
+#define SIGNAL_WPS_EVENT "Event"
+#define SIGNAL_WPS_CREDENTIALS "Credentials"
+
#define CONNMAN_SIGNAL_SERVICES_CHANGED "ServicesChanged"
#define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged"
#define CONNMAN_SIGNAL_NAME_CHANGED "NameOwnerChanged"
#define MAX_SIG_LEN 64
-#define TOTAL_CONN_SIGNALS 4
+#define TOTAL_CONN_SIGNALS 5
typedef enum {
SIG_INTERFACE_REMOVED = 0,
return;
}
+static void _supplicant_wifi_wps_connected(GVariant *param)
+{
+ gchar *key;
+ char ssid[32] = {0, };
+ gchar *name;
+ GVariantIter *iter;
+ GVariant *variant;
+ int config_error = 0;
+ int error_indication = 0;
+ gsize ssid_len = 0;
+
+ if (param == NULL) {
+ ERR("Param is NULL");
+ return;
+ }
+
+ g_variant_get(param, "(sa{sv})", &name, &iter);
+ INFO("wps Result: %s", name);
+ while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
+ INFO("wps Key is %s", key);
+ if (g_strcmp0(key, "SSID") == 0) {
+ const char *t_key = NULL;
+ t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar));
+ INFO("wps ssid_len is %d ", ssid_len);
+ if (t_key == NULL) {
+ g_free(key);
+ g_variant_unref(variant);
+ ERR("WPS PBC Connection Failed");
+ goto error;
+ }
+ if (ssid_len > 0 && ssid_len <= 32) {
+ memcpy(ssid, t_key, ssid_len);
+ } else {
+ memset(ssid, 0, sizeof(ssid));
+ ssid_len = 0;
+ }
+ INFO("WPS PBC Connection completed with AP %s", ssid);
+ netconfig_wifi_notify_wps_completed(ssid, ssid_len);
+ }
+ }
+
+ g_variant_iter_free(iter);
+ g_free(name);
+ return;
+
+error:
+ g_variant_iter_free(iter);
+ g_free(name);
+ error_indication = WPS_EI_OPERATION_FAILED;
+ config_error = WPS_CFG_NO_ERROR;
+ ERR("Error Occured! Notifying Fail Event");
+ netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
+
+}
+
+static void _supplicant_wifi_wps_event(GVariant *param)
+{
+ gchar *key;
+ gchar *name;
+ GVariantIter *iter;
+ GVariant *variant;
+ gint32 config_error = 0;
+ gint32 error_indication = 0;
+
+ if (param == NULL) {
+ ERR("Param is NULL");
+ return;
+ }
+
+ g_variant_get(param, "(sa{sv})", &name, &iter);
+ INFO("Event Result: %s", name);
+ if (g_strcmp0(name, "failed") == 0) {
+ while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
+ if (key == NULL)
+ goto error;
+ INFO("Key is %s", key);
+ if (g_strcmp0(key, "config_error") == 0) {
+ config_error = g_variant_get_int32(variant);
+ ERR("Config Error %d", config_error);
+ } else if (g_strcmp0(key, "error_indication") == 0) {
+ error_indication = g_variant_get_int32(variant);
+ ERR("Error Indication %d", error_indication);
+ }
+ }
+ netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
+ }
+
+ g_variant_iter_free(iter);
+ g_free(name);
+ return;
+
+error:
+ g_variant_iter_free(iter);
+ g_free(name);
+ error_indication = WPS_EI_OPERATION_FAILED;
+ config_error = WPS_CFG_NO_ERROR;
+ ERR("Error Occured! Notifying Fail Event");
+ netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
+}
+
+static void _supplicant_wifi_wps_credentials(GVariant *param)
+{
+ gchar *key;
+ char ssid[32];
+ char wps_key[100];
+ GVariantIter *iter;
+ GVariant *variant;
+ int config_error = 0;
+ int error_indication = 0;
+ gsize ssid_len = 0;
+
+ if (param == NULL) {
+ ERR("Param is NULL");
+ return;
+ }
+
+ g_variant_get(param, "(a{sv})", &iter);
+ while (g_variant_iter_loop(iter, "{sv}", &key, &variant)) {
+ if (key == NULL)
+ goto error;
+ INFO("wps Key is %s", key);
+ if (g_strcmp0(key, "Key") == 0) {
+ gsize key_len = 0;
+ const char *t_key = NULL;
+ key_len = g_variant_get_size(variant);
+
+ INFO("wps password len %d ", key_len);
+ if (key_len > 0) {
+ t_key = g_variant_get_fixed_array(variant, &key_len, sizeof(guchar));
+ if (!t_key) {
+ g_free(key);
+ g_variant_unref(variant);
+ goto error;
+ }
+ strncpy(wps_key, t_key, key_len);
+ wps_key[key_len] = '\0';
+ INFO("WPS Key in process credentials %s", wps_key);
+ } else
+ SLOGI("WPS AP Security ->Open");
+ } else if (g_strcmp0(key, "SSID") == 0) {
+ const char *t_key = NULL;
+ t_key = g_variant_get_fixed_array(variant, &ssid_len, sizeof(guchar));
+ INFO("wps ssid_len is %d ", ssid_len);
+ if (!t_key) {
+ g_free(key);
+ g_variant_unref(variant);
+ goto error;
+ }
+ if (ssid_len > 0 && ssid_len <= 32) {
+ memcpy(ssid, t_key, ssid_len);
+ } else {
+ memset(ssid, 0, sizeof(ssid));
+ ssid_len = 0;
+ }
+ INFO("SSID in process credentials %s", ssid);
+ }
+ }
+
+ g_variant_iter_free(iter);
+
+#if 0
+ /*
+ * Notify WPS Credentials only when requested through WPS PBC
+ * In case of WPS PIN connman will take care of notification
+ */
+ if (netconfig_get_wps_field() == TRUE)
+#endif
+ netconfig_wifi_notify_wps_credentials(ssid, ssid_len, wps_key);
+ return;
+
+error:
+ g_variant_iter_free(iter);
+ error_indication = WPS_EI_OPERATION_FAILED;
+ config_error = WPS_CFG_NO_ERROR;
+ ERR("Error Occured! Notifying Fail Event");
+ netconfig_wifi_notify_wps_fail_event(config_error, error_indication);
+}
+
+static void __netconfig_wps_signal_filter_handler(GDBusConnection *conn,
+ const gchar *name, const gchar *path, const gchar *interface,
+ const gchar *sig, GVariant *param, gpointer user_data)
+{
+ if (g_strcmp0(sig, SIGNAL_WPS_CREDENTIALS) == 0) {
+ INFO("Received wps CREDENTIALS Signal from Supplicant");
+ _supplicant_wifi_wps_credentials(param);
+ } else if (g_strcmp0(sig, SIGNAL_WPS_EVENT) == 0) {
+ INFO("Received wps EVENT Signal from Supplicant");
+ _supplicant_wifi_wps_event(param);
+ } else if (g_strcmp0(sig, SIGNAL_WPS_CONNECTED) == 0) {
+ INFO("Received WPSConnected Signal from Supplicant");
+ _supplicant_wifi_wps_connected(param);
+ }
+
+ return;
+}
+
static supplicant_signal_cb supplicant_cbs[SIG_MAX] = {
_supplicant_interface_removed,
_supplicant_properties_changed,
INFO("Successfully register connman DBus signal filters");
+ conn_subscription_ids[4] = g_dbus_connection_signal_subscribe(
+ connection,
+ SUPPLICANT_SERVICE,
+ SUPPLICANT_INTERFACE ".Interface.WPS",
+ NULL,
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ __netconfig_wps_signal_filter_handler,
+ NULL,
+ NULL);
+
+ INFO("Successfully register Supplicant WPS DBus signal filters");
+
for (sig = SIG_INTERFACE_REMOVED; sig < SIG_MAX; sig++) {
/*
* For SIG_INTERFACE_REMOVED INTERFACE_ADDED
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)
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;
return TRUE;
}
+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)
{
return reply;
}
-gboolean netconfig_iface_wifi_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation **context)
+gboolean netconfig_get_wps_field()
{
- if (TIZEN_TV) {
- DBG("Received WPS PBC Cancel Request");
- g_return_val_if_fail(wifi != NULL, FALSE);
- return __netconfig_wifi_invoke_wps_cancel();
+ return wifi_wps.pbc;
+}
+
+gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context)
+{
+ INFO("Received WPS PBC Cancel Request");
+ g_return_val_if_fail(wifi != NULL, FALSE);
+ __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 {
- /*Not supported for mobile and Wearable profile*/
- return FALSE;
+ wifi_wps.pin = g_strdup(param);
+ wifi_wps.pbc = FALSE;
}
+
+ netconfig_wifi_wps_connect();
+
+ wifi_complete_request_wps_connect(wifi, context);
+ return TRUE;
}
g_signal_connect(wifi_object, "handle-request-wps-scan",
G_CALLBACK(handle_request_wps_scan), NULL);
+ /* WPS Connect */
+ g_signal_connect(wifi_object, "handle-request-wps-connect",
+ G_CALLBACK(handle_request_wps_connect), NULL);
+ g_signal_connect(wifi_object, "handle-request-wps-cancel",
+ G_CALLBACK(handle_request_wps_cancel), NULL);
+
/* WIFI direct */
g_signal_connect(wifi_object, "handle-launch-direct",
G_CALLBACK(handle_launch_direct), NULL);