Add mock driver
Create mock driver that simulates hardware events to exercise the scan,
associate, disassociate code paths.
Change-Id: I7d6696b0df530d57ad7dd619a2256b2da78a9e31
diff --git a/src/drivers/driver_mock.c b/src/drivers/driver_mock.c
new file mode 100644
index 0000000..1f71583
--- /dev/null
+++ b/src/drivers/driver_mock.c
@@ -0,0 +1,184 @@
+/*
+ * A mock driver used for exercising wpa_supplicant code.
+ *
+ * Copyright (c) 2016 The Fuchsia Authors
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ *
+ */
+
+#include "includes.h"
+
+#include <stdbool.h>
+
+#include "common.h"
+#include "driver.h"
+#include "eloop.h"
+#include "os.h"
+
+static const u8 MOCK_BSSID[ETH_ALEN] = {0, 1, 2, 3, 4, 5};
+static const u8 MOCK_SSID[6] = {'M', 'o', 'c', 'k', 'A', 'p'};
+
+// TODO(alangardner): queue wpa_supplicant_event calls on eloop
+struct mock_driver_data {
+ void *ctx;
+ struct wpa_driver_capa capa;
+ struct wpa_scan_results *scan_results;
+ bool associated;
+};
+
+static int mock_driver_send_ether(void *priv, const u8 *dst, const u8 *src,
+ u16 proto, const u8 *data, size_t data_len) {
+ return 0;
+}
+
+static void mock_driver_enabled(void *eloop_data, void *user_ctx) {
+ struct mock_driver_data *drv = eloop_data;
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
+ wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
+}
+
+static void mock_driver_scan_completed(void *eloop_data, void *user_ctx) {
+ struct mock_driver_data *drv = eloop_data;
+ wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
+}
+
+static void mock_driver_disassociated(void *eloop_data, void *user_ctx) {
+ struct mock_driver_data *drv = eloop_data;
+ drv->associated = false;
+ wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
+}
+
+static void mock_driver_associated(void *eloop_data, void *user_ctx) {
+ struct mock_driver_data *drv = eloop_data;
+ drv->associated = true;
+ wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
+ eloop_register_timeout(5, 0, mock_driver_disassociated, drv, NULL);
+}
+
+static void mock_driver_capa(struct mock_driver_data *drv) {
+ drv->capa.key_mgmt =
+ WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+ WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
+ drv->capa.enc = WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104 |
+ WPA_DRIVER_CAPA_ENC_TKIP | WPA_DRIVER_CAPA_ENC_CCMP;
+ drv->capa.flags |= WPA_DRIVER_FLAGS_AP;
+ drv->capa.max_scan_ssids = 1;
+ drv->capa.auth =
+ WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED | WPA_DRIVER_AUTH_LEAP;
+}
+
+static void mock_scan_results(struct mock_driver_data *drv) {
+ int ssid_len = sizeof(MOCK_SSID) / sizeof(*MOCK_SSID);
+ int bssid_len = sizeof(MOCK_BSSID) / sizeof(*MOCK_BSSID);
+ int ie_len = 2 + ssid_len;
+ struct wpa_scan_res *result = os_zalloc(sizeof(struct wpa_scan_res));
+ result->flags = 0;
+ os_memcpy(&result->bssid, MOCK_BSSID, bssid_len);
+ result->freq = 2412; // Channel 1
+ result->beacon_int = 100;
+ result->caps = 0;
+ result->qual = 0;
+ result->noise = 0;
+ result->level = 0;
+ // Note: 'tsf' and 'age' will get updated when scan is called
+ result->est_throughput = 0;
+ result->snr = 0;
+ result->ie_len = ie_len;
+ result->beacon_ie_len = 0;
+
+ u8 *pos = (u8 *)(result + 1);
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = ssid_len;
+ os_memcpy(pos, MOCK_SSID, ssid_len);
+ pos += ssid_len;
+
+ drv->scan_results = os_zalloc(sizeof(struct wpa_scan_results));
+ drv->scan_results->num = 1;
+ drv->scan_results->res = os_calloc(1, sizeof(struct wpa_scan_res *));
+ drv->scan_results->res[0] = result;
+}
+
+static void *mock_driver_init(void *ctx, const char *ifname) {
+ wpa_printf(MSG_DEBUG, "MOCK INIT");
+ struct mock_driver_data *drv = os_zalloc(sizeof(struct mock_driver_data));
+ if (drv == NULL) {
+ wpa_printf(MSG_ERROR, "Could not allocate memory for mock driver data");
+ return NULL;
+ }
+ drv->ctx = ctx;
+ mock_driver_capa(drv);
+ mock_scan_results(drv);
+ drv->associated = false;
+
+ eloop_register_timeout(0, 0, mock_driver_enabled, drv, NULL);
+ return drv;
+}
+
+static void mock_driver_deinit(void *priv) {
+ struct mock_driver_data *drv = priv;
+ wpa_scan_results_free(drv->scan_results);
+ os_free(drv);
+}
+
+static int mock_driver_get_capa(void *priv, struct wpa_driver_capa *capa) {
+ wpa_printf(MSG_DEBUG, "MOCK GET CAPA");
+ struct mock_driver_data *drv = priv;
+ os_memcpy(capa, &drv->capa, sizeof(*capa));
+ return 0;
+}
+
+static int mock_driver_scan(void *priv, struct wpa_driver_scan_params *params) {
+ wpa_printf(MSG_DEBUG, "MOCK SCAN");
+ struct mock_driver_data *drv = priv;
+ eloop_register_timeout(0, 0, mock_driver_scan_completed, drv, NULL);
+ return 0;
+}
+
+static struct wpa_scan_results *mock_driver_get_scan_results(void *priv) {
+ wpa_printf(MSG_DEBUG, "MOCK GET SCAN RESULTS");
+ struct mock_driver_data *drv = priv;
+ return drv->scan_results;
+}
+
+static int mock_driver_associate(void *priv,
+ struct wpa_driver_associate_params *params) {
+ struct mock_driver_data *drv = priv;
+ eloop_register_timeout(0, 0, mock_driver_associated, drv, NULL);
+ return 0;
+}
+
+static int mock_driver_get_bssid(void *priv, u8 *bssid) {
+ struct mock_driver_data *drv = priv;
+ if (drv->associated) {
+ os_memcpy(bssid, &MOCK_BSSID, ETH_ALEN);
+ } else {
+ os_memset(bssid, 0, ETH_ALEN);
+ }
+ return 0;
+}
+
+static int mock_driver_get_ssid(void *priv, u8 *ssid) {
+ struct mock_driver_data *drv = priv;
+ if (drv->associated) {
+ os_memcpy(ssid, &MOCK_SSID, sizeof(MOCK_SSID));
+ return sizeof(MOCK_SSID);
+ } else {
+ return 0;
+ }
+}
+
+const struct wpa_driver_ops wpa_driver_mock_ops = {
+ .name = "mock",
+ .desc = "simulates a working driver for testing",
+ .send_ether = mock_driver_send_ether,
+ .init = mock_driver_init,
+ .deinit = mock_driver_deinit,
+ .get_capa = mock_driver_get_capa,
+ .scan2 = mock_driver_scan,
+ .get_scan_results2 = mock_driver_get_scan_results,
+ .associate = mock_driver_associate,
+ .get_bssid = mock_driver_get_bssid,
+ .get_ssid = mock_driver_get_ssid,
+};
diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c
index a98af9a..4276588 100644
--- a/src/drivers/drivers.c
+++ b/src/drivers/drivers.c
@@ -9,30 +9,29 @@
#include "utils/includes.h"
#include "utils/common.h"
#include "driver.h"
-
#ifdef CONFIG_DRIVER_WEXT
extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */
-#endif /* CONFIG_DRIVER_WEXT */
+#endif /* CONFIG_DRIVER_WEXT */
#ifdef CONFIG_DRIVER_NL80211
extern struct wpa_driver_ops wpa_driver_nl80211_ops; /* driver_nl80211.c */
-#endif /* CONFIG_DRIVER_NL80211 */
+#endif /* CONFIG_DRIVER_NL80211 */
#ifdef CONFIG_DRIVER_HOSTAP
extern struct wpa_driver_ops wpa_driver_hostap_ops; /* driver_hostap.c */
-#endif /* CONFIG_DRIVER_HOSTAP */
+#endif /* CONFIG_DRIVER_HOSTAP */
#ifdef CONFIG_DRIVER_BSD
extern struct wpa_driver_ops wpa_driver_bsd_ops; /* driver_bsd.c */
-#endif /* CONFIG_DRIVER_BSD */
+#endif /* CONFIG_DRIVER_BSD */
#ifdef CONFIG_DRIVER_OPENBSD
extern struct wpa_driver_ops wpa_driver_openbsd_ops; /* driver_openbsd.c */
-#endif /* CONFIG_DRIVER_OPENBSD */
+#endif /* CONFIG_DRIVER_OPENBSD */
#ifdef CONFIG_DRIVER_NDIS
extern struct wpa_driver_ops wpa_driver_ndis_ops; /* driver_ndis.c */
-#endif /* CONFIG_DRIVER_NDIS */
+#endif /* CONFIG_DRIVER_NDIS */
#ifdef CONFIG_DRIVER_WIRED
extern struct wpa_driver_ops wpa_driver_wired_ops; /* driver_wired.c */
-#endif /* CONFIG_DRIVER_WIRED */
+#endif /* CONFIG_DRIVER_WIRED */
#ifdef CONFIG_DRIVER_MACSEC_QCA
- /* driver_macsec_qca.c */
+/* driver_macsec_qca.c */
extern struct wpa_driver_ops wpa_driver_macsec_qca_ops;
#endif /* CONFIG_DRIVER_MACSEC_QCA */
#ifdef CONFIG_DRIVER_ROBOSWITCH
@@ -41,46 +40,49 @@
#endif /* CONFIG_DRIVER_ROBOSWITCH */
#ifdef CONFIG_DRIVER_ATHEROS
extern struct wpa_driver_ops wpa_driver_atheros_ops; /* driver_atheros.c */
-#endif /* CONFIG_DRIVER_ATHEROS */
+#endif /* CONFIG_DRIVER_ATHEROS */
#ifdef CONFIG_DRIVER_NONE
extern struct wpa_driver_ops wpa_driver_none_ops; /* driver_none.c */
-#endif /* CONFIG_DRIVER_NONE */
+#endif /* CONFIG_DRIVER_NONE */
+#ifdef CONFIG_DRIVER_MOCK
+extern struct wpa_driver_ops wpa_driver_mock_ops; /* driver_mock.c */
+#endif /* CONFIG_DRIVER_MOCK */
-
-const struct wpa_driver_ops *const wpa_drivers[] =
-{
+const struct wpa_driver_ops *const wpa_drivers[] = {
#ifdef CONFIG_DRIVER_NL80211
- &wpa_driver_nl80211_ops,
+ &wpa_driver_nl80211_ops,
#endif /* CONFIG_DRIVER_NL80211 */
#ifdef CONFIG_DRIVER_WEXT
- &wpa_driver_wext_ops,
+ &wpa_driver_wext_ops,
#endif /* CONFIG_DRIVER_WEXT */
#ifdef CONFIG_DRIVER_HOSTAP
- &wpa_driver_hostap_ops,
+ &wpa_driver_hostap_ops,
#endif /* CONFIG_DRIVER_HOSTAP */
#ifdef CONFIG_DRIVER_BSD
- &wpa_driver_bsd_ops,
+ &wpa_driver_bsd_ops,
#endif /* CONFIG_DRIVER_BSD */
#ifdef CONFIG_DRIVER_OPENBSD
- &wpa_driver_openbsd_ops,
+ &wpa_driver_openbsd_ops,
#endif /* CONFIG_DRIVER_OPENBSD */
#ifdef CONFIG_DRIVER_NDIS
- &wpa_driver_ndis_ops,
+ &wpa_driver_ndis_ops,
#endif /* CONFIG_DRIVER_NDIS */
#ifdef CONFIG_DRIVER_WIRED
- &wpa_driver_wired_ops,
+ &wpa_driver_wired_ops,
#endif /* CONFIG_DRIVER_WIRED */
#ifdef CONFIG_DRIVER_MACSEC_QCA
- &wpa_driver_macsec_qca_ops,
+ &wpa_driver_macsec_qca_ops,
#endif /* CONFIG_DRIVER_MACSEC_QCA */
#ifdef CONFIG_DRIVER_ROBOSWITCH
- &wpa_driver_roboswitch_ops,
+ &wpa_driver_roboswitch_ops,
#endif /* CONFIG_DRIVER_ROBOSWITCH */
#ifdef CONFIG_DRIVER_ATHEROS
- &wpa_driver_atheros_ops,
+ &wpa_driver_atheros_ops,
#endif /* CONFIG_DRIVER_ATHEROS */
#ifdef CONFIG_DRIVER_NONE
- &wpa_driver_none_ops,
+ &wpa_driver_none_ops,
#endif /* CONFIG_DRIVER_NONE */
- NULL
-};
+#ifdef CONFIG_DRIVER_MOCK
+ &wpa_driver_mock_ops,
+#endif /* CONFIG_DRIVER_MOCK */
+ NULL};
diff --git a/wpa_supplicant/BUILD.gn b/wpa_supplicant/BUILD.gn
index 1eb68e3..62fe29e 100644
--- a/wpa_supplicant/BUILD.gn
+++ b/wpa_supplicant/BUILD.gn
@@ -38,7 +38,7 @@
defines = [
"CONFIG_BACKEND_FILE",
"CONFIG_CRYPTO_INTERNAL",
- "CONFIG_DRIVER_NONE",
+ "CONFIG_DRIVER_MOCK",
"CONFIG_NO_PBKDF2",
"CONFIG_NO_CONFIG_BLOBS",
"CONFIG_NO_SCAN_PROCESSING",
@@ -64,7 +64,7 @@
"../src/crypto/sha256-tlsprf.c",
"../src/crypto/tls_none.c",
"../src/drivers/driver_common.c",
- "../src/drivers/driver_none.c",
+ "../src/drivers/driver_mock.c",
"../src/drivers/drivers.c",
"../src/l2_packet/l2_packet_none.c",
"../src/utils/common.c",
diff --git a/wpa_supplicant/main_fuchsia.c b/wpa_supplicant/main_fuchsia.c
index 884e336..16a2a51 100644
--- a/wpa_supplicant/main_fuchsia.c
+++ b/wpa_supplicant/main_fuchsia.c
@@ -9,6 +9,7 @@
#include "includes.h"
#include "common.h"
+#include "config.h"
#include "wpa_supplicant_i.h"
int main(int argc, char *argv[]) {
@@ -18,17 +19,27 @@
struct wpa_global *global;
memset(¶ms, 0, sizeof(params));
- params.wpa_debug_level = MSG_DEBUG;
+ params.wpa_debug_level = MSG_EXCESSIVE;
global = wpa_supplicant_init(¶ms);
if (global == NULL) return -1;
memset(&iface, 0, sizeof(iface));
- iface.ifname = "none";
+ iface.ifname = "mock";
iface.ctrl_interface = "";
if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL) exitcode = -1;
+ if (exitcode == 0) {
+ struct wpa_supplicant *supplicant = global->ifaces;
+ struct wpa_ssid *ssid = wpa_config_add_network(supplicant->conf);
+ wpa_config_set_network_defaults(ssid);
+ wpa_config_set_quoted(ssid, "ssid", "MockAp");
+ wpa_config_set(ssid, "key_mgmt", "NONE", 0);
+ }
+
+ // TODO(alangardner): Create option to terminate
+
if (exitcode == 0) exitcode = wpa_supplicant_run(global);
wpa_supplicant_deinit(global);