All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/7] dbus: add helper for appending a dictionary
@ 2021-01-11 21:34 James Prestwood
  2021-01-11 21:34 ` [PATCH v2 2/7] netdev: add netdev_get_station/current_station James Prestwood
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:34 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1765 bytes --]

Arrays of dictionaries are quite common, and for basic
types this API makes things much more convenient by
putting all the enter/append/leave calls in one place.
---
 src/dbus.c | 24 ++++++++++++++++++++++++
 src/dbus.h |  3 +++
 2 files changed, 27 insertions(+)

diff --git a/src/dbus.c b/src/dbus.c
index ceede5c8..d6bfc52d 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -202,6 +202,30 @@ void dbus_pending_reply(struct l_dbus_message **msg,
 	*msg = NULL;
 }
 
+/*
+ * Convenience helper for appending a dictionary "{sv}". This only works when
+ * the variant is a basic type.
+ */
+bool dbus_append_dict_basic(struct l_dbus_message_builder *builder,
+				const char *name, const char *type,
+				const void *data)
+{
+	if (!l_dbus_message_builder_enter_dict(builder, "sv"))
+		return false;
+	if (!l_dbus_message_builder_append_basic(builder, 's', name))
+		return false;
+	if (!l_dbus_message_builder_enter_variant(builder, type))
+		return false;
+	if (!l_dbus_message_builder_append_basic(builder, type[0], data))
+		return false;
+	if (!l_dbus_message_builder_leave_variant(builder))
+		return false;
+	if (!l_dbus_message_builder_leave_dict(builder))
+		return false;
+
+	return true;
+}
+
 struct l_dbus *dbus_get_bus(void)
 {
 	return g_dbus;
diff --git a/src/dbus.h b/src/dbus.h
index 3e2018d8..3a055482 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -51,6 +51,9 @@ struct l_dbus *dbus_get_bus(void);
 
 void dbus_pending_reply(struct l_dbus_message **msg,
 				struct l_dbus_message *reply);
+bool dbus_append_dict_basic(struct l_dbus_message_builder *builder,
+				const char *name, const char *type,
+				const void *data);
 
 const char *dbus_iftype_to_string(unsigned int iftype);
 
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/7] netdev: add netdev_get_station/current_station
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
@ 2021-01-11 21:34 ` James Prestwood
  2021-01-11 21:34 ` [PATCH v2 3/7] netdev: update RSSI polling to use netdev_get_station James Prestwood
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:34 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 5693 bytes --]

This adds a generalized API for GET_STATION. This API handles
calling and parsing the results into a new structure,
netdev_station_info. This results structure will hold any
data needed by consumers of netdev_get_station. A helper API
(netdev_get_current_station) was added as a convenience which
automatically passes handshake->aa as the MAC.

For now only the RSSI is parsed as this is already being
done for RSSI polling/events. Looking further more info will
be added such as rx/tx rates and estimated throughput.
---
 src/netdev.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/netdev.h |  14 +++++++
 2 files changed, 127 insertions(+)

v2:
 * Fixed some minor cleanup problems
 * Added netdev_get_current_station helper
 * Removed netdev from netdev_get_station_cb_t. Internally the RSSI
   polling can pass netdev as user_data to access that way.

diff --git a/src/netdev.c b/src/netdev.c
index 3f78afbf..7777869f 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -132,6 +132,11 @@ struct netdev {
 	void *set_powered_user_data;
 	netdev_destroy_func_t set_powered_destroy;
 
+	uint32_t get_station_cmd_id;
+	netdev_get_station_cb_t get_station_cb;
+	void *get_station_data;
+	netdev_destroy_func_t get_station_destroy;
+
 	struct watchlist station_watches;
 
 	struct l_io *pae_io;  /* for drivers without EAPoL over NL80211 */
@@ -636,6 +641,11 @@ static void netdev_free(void *data)
 		netdev->mac_change_cmd_id = 0;
 	}
 
+	if (netdev->get_station_cmd_id) {
+		l_genl_family_cancel(nl80211, netdev->get_station_cmd_id);
+		netdev->get_station_cmd_id = 0;
+	}
+
 	if (netdev->events_ready)
 		WATCHLIST_NOTIFY(&netdev_watches, netdev_watch_func_t,
 					netdev, NETDEV_WATCH_EVENT_DEL);
@@ -4022,6 +4032,109 @@ done:
 	return 0;
 }
 
+static bool netdev_parse_sta_info(struct l_genl_attr *attr,
+					struct netdev_station_info *info)
+{
+	uint16_t type, len;
+	const void *data;
+
+	while (l_genl_attr_next(attr, &type, &len, &data)) {
+		switch (type) {
+		case NL80211_STA_INFO_SIGNAL_AVG:
+			if (len != 1)
+				return false;
+
+			info->cur_rssi = *(const int8_t *) data;
+
+			break;
+		}
+	}
+
+	return true;
+}
+
+static void netdev_get_station_cb(struct l_genl_msg *msg, void *user_data)
+{
+	struct netdev *netdev = user_data;
+	struct l_genl_attr attr, nested;
+	uint16_t type, len;
+	const void *data;
+	struct netdev_station_info info;
+
+	netdev->get_station_cmd_id = 0;
+
+	if (!l_genl_attr_init(&attr, msg))
+		goto parse_error;
+
+	while (l_genl_attr_next(&attr, &type, &len, &data)) {
+		switch (type) {
+		case NL80211_ATTR_STA_INFO:
+			if (!l_genl_attr_recurse(&attr, &nested))
+				goto parse_error;
+
+			if (!netdev_parse_sta_info(&nested, &info))
+				goto parse_error;
+
+			break;
+		}
+	}
+
+	if (netdev->get_station_cb)
+		netdev->get_station_cb(&info, netdev->get_station_data);
+
+	return;
+
+parse_error:
+	if (netdev->get_station_cb)
+		netdev->get_station_cb(NULL, netdev->get_station_data);
+}
+
+static void netdev_get_station_destroy(void *user_data)
+{
+	struct netdev *netdev = user_data;
+
+	netdev->get_station_cmd_id = 0;
+
+	if (netdev->get_station_destroy)
+		netdev->get_station_destroy(netdev->get_station_data);
+}
+
+int netdev_get_station(struct netdev *netdev, const uint8_t *mac,
+			netdev_get_station_cb_t cb, void *user_data,
+			netdev_destroy_func_t destroy)
+{
+	struct l_genl_msg *msg;
+
+	if (netdev->get_station_cmd_id)
+		return -EBUSY;
+
+	msg = l_genl_msg_new_sized(NL80211_CMD_GET_STATION, 64);
+	l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
+	l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN, mac);
+
+	netdev->get_station_cmd_id = l_genl_family_send(nl80211, msg,
+						netdev_get_station_cb, netdev,
+						netdev_get_station_destroy);
+	if (!netdev->get_station_cmd_id) {
+		l_genl_msg_unref(msg);
+		return -EIO;
+	}
+
+	netdev->get_station_cb = cb;
+	netdev->get_station_data = user_data;
+	netdev->get_station_destroy = destroy;
+
+	return 0;
+}
+
+int netdev_get_current_station(struct netdev *netdev,
+			netdev_get_station_cb_t cb, void *user_data,
+			netdev_destroy_func_t destroy)
+{
+	return netdev_get_station(netdev, netdev->handshake->aa, cb,
+					user_data, destroy);
+}
+
 static int netdev_cqm_rssi_update(struct netdev *netdev)
 {
 	struct l_genl_msg *msg;
diff --git a/src/netdev.h b/src/netdev.h
index 65fdbaaf..a12a26ff 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -114,6 +114,13 @@ typedef void (*netdev_station_watch_func_t)(struct netdev *netdev,
 					const uint8_t *mac, bool added,
 					void *user_data);
 
+struct netdev_station_info {
+	int8_t cur_rssi;
+};
+
+typedef void (*netdev_get_station_cb_t)(struct netdev_station_info *info,
+					void *user_data);
+
 struct wiphy *netdev_get_wiphy(struct netdev *netdev);
 const uint8_t *netdev_get_address(struct netdev *netdev);
 uint32_t netdev_get_ifindex(struct netdev *netdev);
@@ -174,6 +181,13 @@ int netdev_neighbor_report_req(struct netdev *netdev,
 int netdev_set_rssi_report_levels(struct netdev *netdev, const int8_t *levels,
 					size_t levels_num);
 
+int netdev_get_station(struct netdev *netdev, const uint8_t *mac,
+			netdev_get_station_cb_t cb, void *user_data,
+			netdev_destroy_func_t destroy);
+int netdev_get_current_station(struct netdev *netdev,
+			netdev_get_station_cb_t cb, void *user_data,
+			netdev_destroy_func_t destroy);
+
 void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code);
 
 struct netdev *netdev_find(int ifindex);
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 3/7] netdev: update RSSI polling to use netdev_get_station
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
  2021-01-11 21:34 ` [PATCH v2 2/7] netdev: add netdev_get_station/current_station James Prestwood
@ 2021-01-11 21:34 ` James Prestwood
  2021-01-11 21:34 ` [PATCH v2 4/7] netdev: parse rates in netdev_get_station James Prestwood
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:34 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]

---
 src/netdev.c | 59 ++++++++--------------------------------------------
 1 file changed, 9 insertions(+), 50 deletions(-)

diff --git a/src/netdev.c b/src/netdev.c
index 7777869f..fa31b06a 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -124,7 +124,6 @@ struct netdev {
 	uint8_t cur_rssi_level_idx;
 	int8_t cur_rssi;
 	struct l_timeout *rssi_poll_timeout;
-	uint32_t rssi_poll_cmd_id;
 	uint8_t set_mac_once[6];
 
 	uint32_t set_powered_cmd_id;
@@ -379,47 +378,16 @@ static void netdev_set_rssi_level_idx(struct netdev *netdev)
 	netdev->cur_rssi_level_idx = new_level;
 }
 
-static void netdev_rssi_poll_cb(struct l_genl_msg *msg, void *user_data)
+static void netdev_rssi_poll_cb(struct netdev_station_info *info,
+				void *user_data)
 {
 	struct netdev *netdev = user_data;
-	struct l_genl_attr attr, nested;
-	uint16_t type, len;
-	const void *data;
-	bool found;
 	uint8_t prev_rssi_level_idx = netdev->cur_rssi_level_idx;
 
-	netdev->rssi_poll_cmd_id = 0;
-
-	if (!l_genl_attr_init(&attr, msg))
-		goto done;
-
-	found = false;
-	while (l_genl_attr_next(&attr, &type, &len, &data)) {
-		if (type != NL80211_ATTR_STA_INFO)
-			continue;
-
-		found = true;
-		break;
-	}
-
-	if (!found || !l_genl_attr_recurse(&attr, &nested))
+	if (!info)
 		goto done;
 
-	found = false;
-	while (l_genl_attr_next(&nested, &type, &len, &data)) {
-		if (type != NL80211_STA_INFO_SIGNAL_AVG)
-			continue;
-
-		if (len != 1)
-			continue;
-
-		found = true;
-		netdev->cur_rssi = *(const int8_t *) data;
-		break;
-	}
-
-	if (!found)
-		goto done;
+	netdev->cur_rssi =  info->cur_rssi;
 
 	/*
 	 * Note we don't have to handle LOW_SIGNAL_THRESHOLD here.  The
@@ -441,16 +409,12 @@ done:
 static void netdev_rssi_poll(struct l_timeout *timeout, void *user_data)
 {
 	struct netdev *netdev = user_data;
-	struct l_genl_msg *msg;
 
-	msg = l_genl_msg_new_sized(NL80211_CMD_GET_STATION, 64);
-	l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &netdev->index);
-	l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, ETH_ALEN,
-							netdev->handshake->aa);
-
-	netdev->rssi_poll_cmd_id = l_genl_family_send(nl80211, msg,
-							netdev_rssi_poll_cb,
-							netdev, NULL);
+	if (netdev_get_current_station(netdev, netdev_rssi_poll_cb,
+					NULL, NULL) < 0) {
+		/* Some problem occurred, rearm timer and try again */
+		l_timeout_modify(netdev->rssi_poll_timeout, 6);
+	}
 }
 
 /* To be called whenever operational or rssi_levels_num are updated */
@@ -472,11 +436,6 @@ static void netdev_rssi_polling_update(struct netdev *netdev)
 
 		l_timeout_remove(netdev->rssi_poll_timeout);
 		netdev->rssi_poll_timeout = NULL;
-
-		if (netdev->rssi_poll_cmd_id) {
-			l_genl_family_cancel(nl80211, netdev->rssi_poll_cmd_id);
-			netdev->rssi_poll_cmd_id = 0;
-		}
 	}
 }
 
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 4/7] netdev: parse rates in netdev_get_station
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
  2021-01-11 21:34 ` [PATCH v2 2/7] netdev: add netdev_get_station/current_station James Prestwood
  2021-01-11 21:34 ` [PATCH v2 3/7] netdev: update RSSI polling to use netdev_get_station James Prestwood
@ 2021-01-11 21:34 ` James Prestwood
  2021-01-11 21:35 ` [PATCH v2 5/7] netdev: parse expected throughput " James Prestwood
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:34 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2314 bytes --]

---
 src/netdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/netdev.h |  4 ++++
 2 files changed, 62 insertions(+)

diff --git a/src/netdev.c b/src/netdev.c
index fa31b06a..51d0da3d 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -3991,11 +3991,50 @@ done:
 	return 0;
 }
 
+static bool netdev_parse_bitrate(struct l_genl_attr *attr, uint32_t *rate_out,
+					uint8_t *mcs_out)
+{
+	uint16_t type, len;
+	const void *data;
+	uint32_t rate = 0;
+	uint8_t mcs = 0;
+
+	while (l_genl_attr_next(attr, &type, &len, &data)) {
+		switch (type) {
+		case NL80211_RATE_INFO_BITRATE32:
+			if (len != 4)
+				return false;
+
+			l_debug("parsing bitrate");
+			rate = *(const uint32_t *) data;
+
+			break;
+
+		case NL80211_RATE_INFO_MCS:
+			if (len != 1)
+				return false;
+
+			mcs = *(const uint8_t *) data;
+
+			break;
+		}
+	}
+
+	if (!rate || !mcs)
+		return false;
+
+	*rate_out = rate;
+	*mcs_out = mcs;
+
+	return true;
+}
+
 static bool netdev_parse_sta_info(struct l_genl_attr *attr,
 					struct netdev_station_info *info)
 {
 	uint16_t type, len;
 	const void *data;
+	struct l_genl_attr nested;
 
 	while (l_genl_attr_next(attr, &type, &len, &data)) {
 		switch (type) {
@@ -4005,6 +4044,25 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
 
 			info->cur_rssi = *(const int8_t *) data;
 
+			break;
+		case NL80211_STA_INFO_RX_BITRATE:
+			if (!l_genl_attr_recurse(attr, &nested))
+				return false;
+
+			if (!netdev_parse_bitrate(&nested, &info->rx_bitrate,
+							&info->rx_mcs))
+				return false;
+
+			break;
+
+		case NL80211_STA_INFO_TX_BITRATE:
+			if (!l_genl_attr_recurse(attr, &nested))
+				return false;
+
+			if (!netdev_parse_bitrate(&nested, &info->tx_bitrate,
+							&info->tx_mcs))
+				return false;
+
 			break;
 		}
 	}
diff --git a/src/netdev.h b/src/netdev.h
index a12a26ff..f47b2bd8 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -116,6 +116,10 @@ typedef void (*netdev_station_watch_func_t)(struct netdev *netdev,
 
 struct netdev_station_info {
 	int8_t cur_rssi;
+	uint32_t rx_bitrate;
+	uint8_t rx_mcs;
+	uint32_t tx_bitrate;
+	uint8_t tx_mcs;
 };
 
 typedef void (*netdev_get_station_cb_t)(struct netdev_station_info *info,
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 5/7] netdev: parse expected throughput in netdev_get_station
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
                   ` (2 preceding siblings ...)
  2021-01-11 21:34 ` [PATCH v2 4/7] netdev: parse rates in netdev_get_station James Prestwood
@ 2021-01-11 21:35 ` James Prestwood
  2021-01-11 21:35 ` [PATCH v2 6/7] station: create StationDiagnostic interface James Prestwood
  2021-01-11 21:35 ` [PATCH v2 7/7] test: add a script for GetDiagnostics James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 861 bytes --]

---
 src/netdev.c | 8 ++++++++
 src/netdev.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/src/netdev.c b/src/netdev.c
index 51d0da3d..dbcb769a 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -4064,6 +4064,14 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
 				return false;
 
 			break;
+
+		case NL80211_STA_INFO_EXPECTED_THROUGHPUT:
+			if (len != 4)
+				return false;
+
+			info->expected_throughput = *(const uint32_t *)data;
+
+			break;
 		}
 	}
 
diff --git a/src/netdev.h b/src/netdev.h
index f47b2bd8..8524e05e 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -120,6 +120,7 @@ struct netdev_station_info {
 	uint8_t rx_mcs;
 	uint32_t tx_bitrate;
 	uint8_t tx_mcs;
+	uint32_t expected_throughput;
 };
 
 typedef void (*netdev_get_station_cb_t)(struct netdev_station_info *info,
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 6/7] station: create StationDiagnostic interface
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
                   ` (3 preceding siblings ...)
  2021-01-11 21:35 ` [PATCH v2 5/7] netdev: parse expected throughput " James Prestwood
@ 2021-01-11 21:35 ` James Prestwood
  2021-01-11 21:35 ` [PATCH v2 7/7] test: add a script for GetDiagnostics James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 4869 bytes --]

This interface sits aside the regular station interface but
provides low level connection details for diagnostic and
testing purposes.
---
 src/station.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

v2:
 * Moved the dbus dict append to its own API in dbus.c
 * Fixed returning empty message on error

diff --git a/src/station.c b/src/station.c
index 1e3706af..f6255a32 100644
--- a/src/station.c
+++ b/src/station.c
@@ -77,6 +77,7 @@ struct station {
 	struct l_dbus_message *hidden_pending;
 	struct l_dbus_message *disconnect_pending;
 	struct l_dbus_message *scan_pending;
+	struct l_dbus_message *get_station_pending;
 	struct signal_agent *signal_agent;
 	uint32_t dbus_scan_id;
 	uint32_t quick_scan_id;
@@ -3333,6 +3334,9 @@ static struct station *station_create(struct netdev *netdev)
 
 	l_dbus_object_add_interface(dbus, netdev_get_path(netdev),
 					IWD_STATION_INTERFACE, station);
+	l_dbus_object_add_interface(dbus, netdev_get_path(netdev),
+					IWD_STATION_DIAGNOSTIC_INTERFACE,
+					station);
 
 	if (netconfig_enabled)
 		station->netconfig = netconfig_new(netdev_get_ifindex(netdev));
@@ -3455,6 +3459,94 @@ static void station_destroy_interface(void *user_data)
 	station_free(station);
 }
 
+static void station_get_diagnostic_cb(struct netdev_station_info *info,
+					void *user_data)
+{
+	struct station *station = user_data;
+	struct l_dbus_message *reply;
+	struct l_dbus_message_builder *builder;
+	int16_t rssi;
+
+
+	if (!info) {
+		reply = dbus_error_aborted(station->get_station_pending);
+		goto done;
+	}
+
+	reply = l_dbus_message_new_method_return(station->get_station_pending);
+
+	rssi = (int16_t)info->cur_rssi;
+
+	builder = l_dbus_message_builder_new(reply);
+
+	l_dbus_message_builder_enter_array(builder, "{sv}");
+
+	dbus_append_dict_basic(builder, "ConnectedBss", "s",
+						util_address_to_string(
+						station->connected_bss->addr));
+	dbus_append_dict_basic(builder, "RSSI", "n", &rssi);
+	dbus_append_dict_basic(builder, "TxBitrate", "u", &info->tx_bitrate);
+	dbus_append_dict_basic(builder, "TxMCS", "y", &info->tx_mcs);
+	dbus_append_dict_basic(builder, "RxBitrate", "u", &info->rx_bitrate);
+	dbus_append_dict_basic(builder, "RxMCS", "y", &info->rx_mcs);
+	dbus_append_dict_basic(builder, "ExpectedThroughput", "u",
+				&info->expected_throughput);
+
+	l_dbus_message_builder_leave_array(builder);
+	l_dbus_message_builder_finalize(builder);
+	l_dbus_message_builder_destroy(builder);
+
+done:
+	dbus_pending_reply(&station->get_station_pending, reply);
+}
+
+static void station_get_diagnostic_destroy(void *user_data)
+{
+	struct station *station = user_data;
+	struct l_dbus_message *reply;
+
+	if (station->get_station_pending) {
+		reply = dbus_error_aborted(station->get_station_pending);
+		dbus_pending_reply(&station->get_station_pending, reply);
+	}
+}
+
+static struct l_dbus_message *station_get_diagnostics(struct l_dbus *dbus,
+						struct l_dbus_message *message,
+						void *user_data)
+{
+	struct station *station = user_data;
+	int ret;
+
+	/*
+	 * At this time all values depend on a connected state.
+	 */
+	if (station->state != STATION_STATE_CONNECTED)
+		return dbus_error_not_connected(message);
+
+	ret = netdev_get_current_station(station->netdev,
+				station_get_diagnostic_cb, station,
+				station_get_diagnostic_destroy);
+	if (ret < 0)
+		return dbus_error_from_errno(ret, message);
+
+	station->get_station_pending = l_dbus_message_ref(message);
+
+	return NULL;
+}
+
+static void station_setup_diagnostic_interface(
+					struct l_dbus_interface *interface)
+{
+	l_dbus_interface_method(interface, "GetDiagnostics", 0,
+				station_get_diagnostics, "a{sv}", "",
+				"diagnostics");
+}
+
+static void station_destroy_diagnostic_interface(void *user_data)
+{
+}
+
 static void station_netdev_watch(struct netdev *netdev,
 				enum netdev_watch_event event, void *userdata)
 {
@@ -3483,6 +3575,11 @@ static int station_init(void)
 	l_dbus_register_interface(dbus_get_bus(), IWD_STATION_INTERFACE,
 					station_setup_interface,
 					station_destroy_interface, false);
+	l_dbus_register_interface(dbus_get_bus(),
+					IWD_STATION_DIAGNOSTIC_INTERFACE,
+					station_setup_diagnostic_interface,
+					station_destroy_diagnostic_interface,
+					false);
 
 	if (!l_settings_get_uint(iwd_get_config(), "General",
 					"ManagementFrameProtection",
@@ -3521,6 +3618,8 @@ static int station_init(void)
 
 static void station_exit(void)
 {
+	l_dbus_unregister_interface(dbus_get_bus(),
+					IWD_STATION_DIAGNOSTIC_INTERFACE);
 	l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_INTERFACE);
 	netdev_watch_remove(netdev_watch);
 	l_queue_destroy(station_list, NULL);
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 7/7] test: add a script for GetDiagnostics
  2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
                   ` (4 preceding siblings ...)
  2021-01-11 21:35 ` [PATCH v2 6/7] station: create StationDiagnostic interface James Prestwood
@ 2021-01-11 21:35 ` James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-11 21:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1434 bytes --]

---
 test/get-diagnostics | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100755 test/get-diagnostics

diff --git a/test/get-diagnostics b/test/get-diagnostics
new file mode 100755
index 00000000..c508c58c
--- /dev/null
+++ b/test/get-diagnostics
@@ -0,0 +1,37 @@
+#!/usr/bin/python3
+
+import sys
+import dbus
+
+# Map dict keys to units. Units can be a function/lambda which should return the
+# entire value with units as a string.
+unit_map = {
+    "ConnectedBss" : None,
+    "RSSI" : "dBm",
+    "RxBitrate" : lambda k : str(100 * int(k)) + ' Kbps',
+    "RxMCS" : lambda i : str(int(i)),
+    "TxBitrate" : lambda k : str(100 * int(k)) + ' Kbps',
+    "TxMCS" : lambda i : str(int(i)),
+    "ExpectedThroughput" : "Kbps"
+}
+
+if (len(sys.argv) != 2):
+    print("Usage: %s <device>" % (sys.argv[0]))
+    sys.exit(1)
+
+bus = dbus.SystemBus()
+device = dbus.Interface(bus.get_object("net.connman.iwd", sys.argv[1]),
+                                    "net.connman.iwd.StationDiagnostic")
+diagnostics = device.GetDiagnostics()
+
+for key, value in diagnostics.items():
+    if key in unit_map:
+        units = unit_map[key]
+        if units is None:
+            units = ''
+        elif callable(units):
+            value = units(value)
+            units = ''
+
+        print('%s : %s %s' % (key, value, units))
+
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-01-11 21:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-11 21:34 [PATCH v2 1/7] dbus: add helper for appending a dictionary James Prestwood
2021-01-11 21:34 ` [PATCH v2 2/7] netdev: add netdev_get_station/current_station James Prestwood
2021-01-11 21:34 ` [PATCH v2 3/7] netdev: update RSSI polling to use netdev_get_station James Prestwood
2021-01-11 21:34 ` [PATCH v2 4/7] netdev: parse rates in netdev_get_station James Prestwood
2021-01-11 21:35 ` [PATCH v2 5/7] netdev: parse expected throughput " James Prestwood
2021-01-11 21:35 ` [PATCH v2 6/7] station: create StationDiagnostic interface James Prestwood
2021-01-11 21:35 ` [PATCH v2 7/7] test: add a script for GetDiagnostics James Prestwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.