WPS methods exported over DBus
authorJaime Soriano Pastor <jsoriano@warp.es>
Wed, 6 May 2009 10:23:41 +0000 (13:23 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 6 May 2009 10:23:41 +0000 (13:23 +0300)
I've exported the methods wpsPbc, wpsReg and wpsPin (patch attached),
so wpa_supplicant should be able to connect with WPS using the dbus
interface. I couldn't test it well because the problem seems to be in
my wireless card, a Broadcom BCM4328. At least it seems to do the same
using both interfaces. With ndiswrapper driver the "wpsie" entry
(thanks Dan!) didn't appear, and with the Broadcom wl driver it
appears but I cannot associate using WPS.

wpa_supplicant/ctrl_iface_dbus.c
wpa_supplicant/ctrl_iface_dbus.h
wpa_supplicant/ctrl_iface_dbus_handlers.c
wpa_supplicant/ctrl_iface_dbus_handlers.h

index 434f1a6..26a3e9d 100644 (file)
@@ -545,6 +545,14 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
                        reply = wpas_dbus_iface_set_blobs(message, wpa_s);
                else if (!strcmp(method, "removeBlobs"))
                        reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
+#ifdef CONFIG_WPS
+               else if (!os_strcmp(method, "wpsPbc"))
+                       reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
+               else if (!os_strcmp(method, "wpsPin"))
+                       reply = wpas_dbus_iface_wps_pin(message, wpa_s);
+               else if (!os_strcmp(method, "wpsReg"))
+                       reply = wpas_dbus_iface_wps_reg(message, wpa_s);
+#endif /* CONFIG_WPS */
        }
 
        /* If the message was handled, send back the reply */
index 68919de..8e9036d 100644 (file)
@@ -74,6 +74,15 @@ struct wps_credential;
 #define WPAS_ERROR_REMOVE_NETWORK_ERROR \
        WPAS_DBUS_IFACE_INTERFACE ".RemoveNetworkError"
 
+#ifdef CONFIG_WPS
+#define WPAS_ERROR_WPS_PBC_ERROR \
+       WPAS_DBUS_IFACE_INTERFACE ".WpsPbcError"
+#define WPAS_ERROR_WPS_PIN_ERROR \
+       WPAS_DBUS_IFACE_INTERFACE ".WpsPinError"
+#define WPAS_ERROR_WPS_REG_ERROR \
+       WPAS_DBUS_IFACE_INTERFACE ".WpsRegError"
+#endif /* CONFIG_WPS */
+
 #define WPAS_DBUS_BSSID_FORMAT "%02x%02x%02x%02x%02x%02x"
 
 struct wpa_global;
index 3fbe5d3..e9dd9a5 100644 (file)
@@ -25,6 +25,7 @@
 #include "ieee802_11_defs.h"
 #include "wpas_glue.h"
 #include "eapol_supp/eapol_supp_sm.h"
+#include "wps_supplicant.h"
 
 extern int wpa_debug_level;
 extern int wpa_debug_show_keys;
@@ -1460,3 +1461,146 @@ DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
 
        return wpas_dbus_new_success_reply(message);
 }
+
+
+#ifdef CONFIG_WPS
+
+/**
+ * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: %wpa_supplicant data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ *          failure (0)
+ *
+ * Handler function for "wpsPbc" method call
+ */
+DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s)
+{
+       char *arg_bssid = NULL;
+       u8 bssid[ETH_ALEN];
+       int ret = 0;
+
+       if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
+                                  DBUS_TYPE_INVALID))
+               return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+       if (!os_strcmp(arg_bssid, "any"))
+               ret = wpas_wps_start_pbc(wpa_s, NULL);
+       else if (!hwaddr_aton(arg_bssid, bssid))
+               ret = wpas_wps_start_pbc(wpa_s, bssid);
+       else {
+               return wpas_dbus_new_invalid_opts_error(message,
+                                                       "Invalid BSSID");
+       }
+
+       if (ret < 0) {
+               return dbus_message_new_error(message,
+                                             WPAS_ERROR_WPS_PBC_ERROR,
+                                             "Could not start PBC "
+                                             "negotiation");
+       }
+
+       return wpas_dbus_new_success_reply(message);
+}
+
+
+/**
+ * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: %wpa_supplicant data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ *          failure (0)
+ *
+ * Handler function for "wpsPin" method call
+ */
+DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s)
+{
+       DBusMessage *reply = NULL;
+       char *arg_bssid;
+       char *pin = NULL;
+       u8 bssid[ETH_ALEN], *_bssid = NULL;
+       int ret = 0;
+
+       if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
+                                  DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
+               return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+       if (!os_strcmp(arg_bssid, "any"))
+               _bssid = NULL;
+       else if (!hwaddr_aton(arg_bssid, bssid))
+               _bssid = bssid;
+       else {
+               return wpas_dbus_new_invalid_opts_error(message,
+                                                       "Invalid BSSID");
+       }
+
+       if (os_strlen(pin) > 0)
+               ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
+       else
+               ret = wpas_wps_start_pin(wpa_s, _bssid, NULL);
+
+       if (ret < 0) {
+               return dbus_message_new_error(message,
+                                             WPAS_ERROR_WPS_PIN_ERROR,
+                                             "Could not init PIN");
+       }
+
+       reply = dbus_message_new_method_return(message);
+       if (reply == NULL)
+               return NULL;
+
+       if (ret == 0) {
+               dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
+                                        DBUS_TYPE_INVALID);
+       } else {
+               char npin[9];
+               sprintf(npin, "%08d", ret);
+               dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin,
+                                        DBUS_TYPE_INVALID);
+       }
+       return reply;
+}
+
+
+/**
+ * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: %wpa_supplicant data structure
+ * Returns: A dbus message containing a UINT32 indicating success (1) or
+ *          failure (0)
+ *
+ * Handler function for "wpsReg" method call
+ */
+DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s)
+{
+       char *arg_bssid;
+       char *pin = NULL;
+       u8 bssid[ETH_ALEN];
+       int ret = 0;
+
+       if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
+                                  DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
+               return wpas_dbus_new_invalid_opts_error(message, NULL);
+
+       if (!os_strcmp(arg_bssid, "any"))
+               ret = wpas_wps_start_reg(wpa_s, NULL, pin);
+       else if (!hwaddr_aton(arg_bssid, bssid))
+               ret = wpas_wps_start_reg(wpa_s, bssid, pin);
+       else {
+               return wpas_dbus_new_invalid_opts_error(message,
+                                                       "Invalid BSSID");
+       }
+
+       if (ret < 0) {
+               return dbus_message_new_error(message,
+                                             WPAS_ERROR_WPS_PBC_ERROR,
+                                             "Could not request credentials");
+       }
+
+       return wpas_dbus_new_success_reply(message);
+}
+
+#endif /* CONFIG_WPS */
index 2800520..0df5f3e 100644 (file)
@@ -83,6 +83,17 @@ DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
 DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
                                           struct wpa_supplicant *wpa_s);
 
+#ifdef CONFIG_WPS
+DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s);
+
+DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s);
+#endif /* CONFIG_WPS */
+
 #endif /* CONFIG_CTRL_IFACE_DBUS */
 
 #endif /* CTRL_IFACE_DBUS_HANDLERS_H */