[PATCH] dbus_new: Add DBus TDLS methods
Paul Stewart
pstew
Mon Nov 11 12:13:55 PST 2013
Add DBus methods for TDLS operations similar to those available
for the control interface. This includes Discover, Setup and
Teardown commands. While here, add a method to query the TDLS
link status and add a DBus method for it.
Tested with CONFIG_TDLS enabled, on a TDLS-enabled host and
peer capable of TDLS:
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSStatus string:<peer-mac-address>
yields: string "peer does not exist"
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSDiscover string:<peer-mac-address>
yields no error
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSSetup string:<peer-mac-address>
yields no error
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSStatus string:<peer-mac-address>
yields: string "connected" after TDLS completes
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSTeardown string:<peer-mac-address>
yields no error
dbus-send --system --dest=fi.w1.wpa_supplicant1 --print-reply \
/fi/w1/wpa_supplicant1/Interfaces/0 \
fi.w1.wpa_supplicant1.Interface.TDLSStatus string:<peer-mac-address>
yields: string "peer not connected"
Signed-hostap: Paul Stewart <pstew at chromium.org>
---
src/rsn_supp/tdls.c | 22 +++++
src/rsn_supp/wpa.h | 1 +
wpa_supplicant/dbus/dbus_new.c | 31 ++++++
wpa_supplicant/dbus/dbus_new_handlers.c | 166 ++++++++++++++++++++++++++++++++
wpa_supplicant/dbus/dbus_new_handlers.h | 9 ++
5 files changed, 229 insertions(+)
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index e911ad0..92915f4 100644
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
@@ -797,6 +797,28 @@ void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr)
}
+char *wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr)
+{
+ struct wpa_tdls_peer *peer;
+
+ if (sm->tdls_disabled || !sm->tdls_supported)
+ return "disabled";
+
+ for (peer = sm->tdls; peer; peer = peer->next) {
+ if (os_memcmp(peer->addr, addr, ETH_ALEN) == 0)
+ break;
+ }
+
+ if (peer == NULL)
+ return "peer does not exist";
+
+ if (!peer->tpk_success)
+ return "peer not connected";
+
+ return "connected";
+}
+
+
static int wpa_tdls_recv_teardown(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 26e9c6c..861e78c 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -380,6 +380,7 @@ void wpa_tdls_teardown_peers(struct wpa_sm *sm);
void wpa_tdls_deinit(struct wpa_sm *sm);
void wpa_tdls_enable(struct wpa_sm *sm, int enabled);
void wpa_tdls_disable_link(struct wpa_sm *sm, const u8 *addr);
+char *wpa_tdls_get_link_status(struct wpa_sm *sm, const u8 *addr);
int wpa_tdls_is_external_setup(struct wpa_sm *sm);
int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index f9521f6..cce8782 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2736,6 +2736,37 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
}
},
#endif /* CONFIG_AUTOSCAN */
+#ifdef CONFIG_TDLS
+ { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler)wpas_dbus_handler_tdls_discover,
+ {
+ { "peer_address", "s", ARG_IN },
+ END_ARGS
+ }
+ },
+ { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler)wpas_dbus_handler_tdls_setup,
+ {
+ { "peer_address", "s", ARG_IN },
+ END_ARGS
+ }
+ },
+ { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler)wpas_dbus_handler_tdls_status,
+ {
+ { "peer_address", "s", ARG_IN },
+ { "status", "s", ARG_OUT },
+ END_ARGS
+ }
+ },
+ { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
+ (WPADBusMethodHandler)wpas_dbus_handler_tdls_teardown,
+ {
+ { "peer_address", "s", ARG_IN },
+ END_ARGS
+ }
+ },
+#endif /* CONFIG_TDLS */
{ NULL, NULL, NULL, { END_ARGS } }
};
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 9f923e6..2862877 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -1996,6 +1996,172 @@ DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message,
return NULL;
}
+#ifdef CONFIG_TDLS
+
+static DBusMessage *get_peer_hwaddr_helper(DBusMessage *message,
+ const char *func_name,
+ u8 *peer_address)
+{
+ const char *peer_string;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &peer_string,
+ DBUS_TYPE_INVALID))
+ return wpas_dbus_error_invalid_args(message, NULL);
+
+ if (hwaddr_aton(peer_string, peer_address)) {
+ wpa_printf(MSG_DEBUG, "%s: invalid address '%s'",
+ func_name, peer_string);
+ return wpas_dbus_error_invalid_args(
+ message,
+ "Invalid hardware address format");
+ }
+
+ return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_tdls_discover - Discover TDLS peer
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Handler function for "TDLSDiscover" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ u8 peer[ETH_ALEN];
+ DBusMessage *error_reply;
+ int ret;
+
+ error_reply = get_peer_hwaddr_helper(message, __func__, peer);
+ if (error_reply)
+ return error_reply;
+
+ wpa_printf(MSG_DEBUG, "DBUS TDLS_DISCOVER " MACSTR,
+ MAC2STR(peer));
+
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
+ else
+ ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+
+ if (ret)
+ return wpas_dbus_error_unknown_error(
+ message, "error performing TDLS discovery");
+
+ return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_tdls_setup - Setup TDLS session
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Handler function for "TDLSSetup" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ u8 peer[ETH_ALEN];
+ DBusMessage *error_reply;
+ int ret;
+
+ error_reply = get_peer_hwaddr_helper(message, __func__, peer);
+ if (error_reply)
+ return error_reply;
+
+ wpa_printf(MSG_DEBUG, "DBUS TDLS_SETUP " MACSTR,
+ MAC2STR(peer));
+
+ wpa_tdls_remove(wpa_s->wpa, peer);
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ ret = wpa_tdls_start(wpa_s->wpa, peer);
+ else
+ ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+
+ if (ret) {
+ return wpas_dbus_error_unknown_error(
+ message, "error performing TDLS setup");
+ }
+
+ return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_tdls_status - Return TDLS session status
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A string representing the state of the link to this TDLS peer
+ *
+ * Handler function for "TDLSStatus" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ u8 peer[ETH_ALEN];
+ DBusMessage *reply;
+ char *tdls_status;
+
+ reply = get_peer_hwaddr_helper(message, __func__, peer);
+ if (reply)
+ return reply;
+
+ wpa_printf(MSG_DEBUG, "DBUS TDLS_STATUS " MACSTR,
+ MAC2STR(peer));
+
+ tdls_status = wpa_tdls_get_link_status(wpa_s->wpa, peer);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING,
+ &tdls_status, DBUS_TYPE_INVALID);
+ return reply;
+}
+
+
+/*
+ * wpas_dbus_handler_tdls_teardown - Teardown TDLS session
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL
+ *
+ * Handler function for "TDLSTeardown" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ u8 peer[ETH_ALEN];
+ DBusMessage *error_reply;
+ int ret;
+
+ error_reply = get_peer_hwaddr_helper(message, __func__, peer);
+ if (error_reply)
+ return error_reply;
+
+ wpa_printf(MSG_DEBUG, "DBUS TDLS_TEARDOWN " MACSTR,
+ MAC2STR(peer));
+
+ if (wpa_tdls_is_external_setup(wpa_s->wpa))
+ ret = wpa_tdls_teardown_link(
+ wpa_s->wpa, peer,
+ WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
+ else
+ ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
+
+ if (ret)
+ return wpas_dbus_error_unknown_error(
+ message, "error performing TDLS teardown");
+
+ return NULL;
+}
+
+#endif /* CONFIG_TDLS */
+
/**
* wpas_dbus_getter_capabilities - Return interface capabilities
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index fbc8358..aa3316b 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -278,6 +278,15 @@ dbus_bool_t wpas_dbus_setter_process_credentials(DBusMessageIter *iter,
DBusError *error,
void *user_data);
+DBusMessage * wpas_dbus_handler_tdls_discover(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_tdls_setup(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
+ struct wpa_supplicant *wpa_s);
+
DBusMessage * wpas_dbus_error_invalid_args(DBusMessage *message,
const char *arg);
DBusMessage * wpas_dbus_error_unknown_error(DBusMessage *message,
--
1.8.4.1
More information about the Hostap
mailing list