All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h
@ 2021-01-22 18:14 James Prestwood
  2021-01-22 18:14 ` [PATCH v3 2/7] diagnostic: commonize the building of diagnostic dict James Prestwood
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

With AP now getting its own diagnostic interface it made sense
to move the netdev_station_info struct definition into its own
header which eventually can be accompanied by utilities in
diagnostic.c. These utilities can then be shared with AP and
station as needed.
---
 src/diagnostic.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/netdev.c     | 23 ++++++++++++-----------
 src/netdev.h     | 34 ++++-----------------------------
 src/station.c    |  6 ++++--
 4 files changed, 69 insertions(+), 43 deletions(-)
 create mode 100644 src/diagnostic.h

diff --git a/src/diagnostic.h b/src/diagnostic.h
new file mode 100644
index 00000000..8292d192
--- /dev/null
+++ b/src/diagnostic.h
@@ -0,0 +1,49 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2020  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+enum diagnostic_mcs_type {
+	DIAGNOSTIC_MCS_TYPE_NONE,
+	DIAGNOSTIC_MCS_TYPE_HT,
+	DIAGNOSTIC_MCS_TYPE_VHT,
+	DIAGNOSTIC_MCS_TYPE_HE,
+};
+
+struct diagnostic_station_info {
+	uint8_t addr[6];
+	int8_t cur_rssi;
+
+	enum diagnostic_mcs_type rx_mcs_type;
+	uint32_t rx_bitrate;
+	uint8_t rx_mcs;
+	enum diagnostic_mcs_type tx_mcs_type;
+	uint32_t tx_bitrate;
+	uint8_t tx_mcs;
+
+	uint32_t expected_throughput;
+
+	bool have_cur_rssi : 1;
+	bool have_rx_mcs : 1;
+	bool have_tx_mcs : 1;
+	bool have_rx_bitrate : 1;
+	bool have_tx_bitrate : 1;
+	bool have_expected_throughput : 1;
+};
diff --git a/src/netdev.c b/src/netdev.c
index e3ce270a..a19270c0 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -61,6 +61,7 @@
 #include "src/fils.h"
 #include "src/auth-proto.h"
 #include "src/frame-xchg.h"
+#include "src/diagnostic.h"
 
 #ifndef ENOTSUPP
 #define ENOTSUPP 524
@@ -369,7 +370,7 @@ int netdev_set_powered(struct netdev *netdev, bool powered,
 }
 
 static bool netdev_parse_bitrate(struct l_genl_attr *attr,
-					enum netdev_mcs_type *type_out,
+					enum diagnostic_mcs_type *type_out,
 					uint32_t *rate_out,
 					uint8_t *mcs_out)
 {
@@ -377,7 +378,7 @@ static bool netdev_parse_bitrate(struct l_genl_attr *attr,
 	const void *data;
 	uint32_t rate = 0;
 	uint8_t mcs = 0;
-	enum netdev_mcs_type mcs_type = NETDEV_MCS_TYPE_NONE;
+	enum diagnostic_mcs_type mcs_type = DIAGNOSTIC_MCS_TYPE_NONE;
 
 	while (l_genl_attr_next(attr, &type, &len, &data)) {
 		switch (type) {
@@ -394,7 +395,7 @@ static bool netdev_parse_bitrate(struct l_genl_attr *attr,
 				return false;
 
 			mcs = l_get_u8(data);
-			mcs_type = NETDEV_MCS_TYPE_HT;
+			mcs_type = DIAGNOSTIC_MCS_TYPE_HT;
 
 			break;
 
@@ -403,7 +404,7 @@ static bool netdev_parse_bitrate(struct l_genl_attr *attr,
 				return false;
 
 			mcs = l_get_u8(data);
-			mcs_type = NETDEV_MCS_TYPE_VHT;
+			mcs_type = DIAGNOSTIC_MCS_TYPE_VHT;
 
 			break;
 
@@ -412,7 +413,7 @@ static bool netdev_parse_bitrate(struct l_genl_attr *attr,
 				return false;
 
 			mcs = l_get_u8(data);
-			mcs_type = NETDEV_MCS_TYPE_HE;
+			mcs_type = DIAGNOSTIC_MCS_TYPE_HE;
 
 			break;
 		}
@@ -424,14 +425,14 @@ static bool netdev_parse_bitrate(struct l_genl_attr *attr,
 	*type_out = mcs_type;
 	*rate_out = rate;
 
-	if (mcs_type != NETDEV_MCS_TYPE_NONE)
+	if (mcs_type != DIAGNOSTIC_MCS_TYPE_NONE)
 		*mcs_out = mcs;
 
 	return true;
 }
 
 static bool netdev_parse_sta_info(struct l_genl_attr *attr,
-					struct netdev_station_info *info)
+					struct diagnostic_station_info *info)
 {
 	uint16_t type, len;
 	const void *data;
@@ -458,7 +459,7 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
 
 			info->have_rx_bitrate = true;
 
-			if (info->rx_mcs_type != NETDEV_MCS_TYPE_NONE)
+			if (info->rx_mcs_type != DIAGNOSTIC_MCS_TYPE_NONE)
 				info->have_rx_mcs = true;
 
 			break;
@@ -474,7 +475,7 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
 
 			info->have_tx_bitrate = true;
 
-			if (info->tx_mcs_type != NETDEV_MCS_TYPE_NONE)
+			if (info->tx_mcs_type != DIAGNOSTIC_MCS_TYPE_NONE)
 				info->have_tx_mcs = true;
 
 			break;
@@ -511,7 +512,7 @@ static void netdev_rssi_poll_cb(struct l_genl_msg *msg, void *user_data)
 	uint16_t type, len;
 	const void *data;
 	bool found;
-	struct netdev_station_info info;
+	struct diagnostic_station_info info;
 	uint8_t prev_rssi_level_idx = netdev->cur_rssi_level_idx;
 
 	netdev->rssi_poll_cmd_id = 0;
@@ -4156,7 +4157,7 @@ static void netdev_get_station_cb(struct l_genl_msg *msg, void *user_data)
 	struct l_genl_attr attr, nested;
 	uint16_t type, len;
 	const void *data;
-	struct netdev_station_info info;
+	struct diagnostic_station_info info;
 
 	netdev->get_station_cmd_id = 0;
 
diff --git a/src/netdev.h b/src/netdev.h
index e7a1c060..d5adcf09 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -27,6 +27,7 @@ struct scan_bss;
 struct handshake_state;
 struct eapol_sm;
 struct mmpdu_header;
+struct diagnostic_station_info;
 
 enum netdev_result {
 	NETDEV_RESULT_OK,
@@ -114,36 +115,9 @@ typedef void (*netdev_station_watch_func_t)(struct netdev *netdev,
 					const uint8_t *mac, bool added,
 					void *user_data);
 
-enum netdev_mcs_type {
-	NETDEV_MCS_TYPE_NONE,
-	NETDEV_MCS_TYPE_HT,
-	NETDEV_MCS_TYPE_VHT,
-	NETDEV_MCS_TYPE_HE,
-};
-
-struct netdev_station_info {
-	uint8_t addr[6];
-	int8_t cur_rssi;
-
-	enum netdev_mcs_type rx_mcs_type;
-	uint32_t rx_bitrate;
-	uint8_t rx_mcs;
-	enum netdev_mcs_type tx_mcs_type;
-	uint32_t tx_bitrate;
-	uint8_t tx_mcs;
-
-	uint32_t expected_throughput;
-
-	bool have_cur_rssi : 1;
-	bool have_rx_mcs : 1;
-	bool have_tx_mcs : 1;
-	bool have_rx_bitrate : 1;
-	bool have_tx_bitrate : 1;
-	bool have_expected_throughput : 1;
-};
-
-typedef void (*netdev_get_station_cb_t)(const struct netdev_station_info *info,
-					void *user_data);
+typedef void (*netdev_get_station_cb_t)(
+				const struct diagnostic_station_info *info,
+				void *user_data);
 
 struct wiphy *netdev_get_wiphy(struct netdev *netdev);
 const uint8_t *netdev_get_address(struct netdev *netdev);
diff --git a/src/station.c b/src/station.c
index c65fc0cc..41f19b09 100644
--- a/src/station.c
+++ b/src/station.c
@@ -53,6 +53,7 @@
 #include "src/netconfig.h"
 #include "src/anqp.h"
 #include "src/anqputil.h"
+#include "src/diagnostic.h"
 
 static struct l_queue *station_list;
 static uint32_t netdev_watch;
@@ -3455,8 +3456,9 @@ static void station_destroy_interface(void *user_data)
 	station_free(station);
 }
 
-static void station_get_diagnostic_cb(const struct netdev_station_info *info,
-					void *user_data)
+static void station_get_diagnostic_cb(
+				const struct diagnostic_station_info *info,
+				void *user_data)
 {
 	struct station *station = user_data;
 	struct l_dbus_message *reply;
-- 
2.26.2

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

* [PATCH v3 2/7] diagnostic: commonize the building of diagnostic dict
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  2021-01-22 18:14 ` [PATCH v3 3/7] station: refactor to use diagnostic_info_to_dict James Prestwood
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

AP mode will use the same structure for its diagnostic interface
and mostly the same dictionary keys. Apart from ConnectedBss and
Address being different, the remainder are the same so the
diagnostic_station_info to DBus dictionary conversion has been made
common so both station and AP can use it to build its diagnostic
dictionaries.
---
 Makefile.am      |   1 +
 src/diagnostic.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++
 src/diagnostic.h |   3 ++
 3 files changed, 113 insertions(+)
 create mode 100644 src/diagnostic.c

v3:
 * Moved this into its own file/module

diff --git a/Makefile.am b/Makefile.am
index b1771bc8..a0701c97 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -239,6 +239,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
 					src/frame-xchg.h src/frame-xchg.c \
 					src/eap-wsc.c src/eap-wsc.h \
 					src/wscutil.h src/wscutil.c \
+					src/diagnostic.h src/diagnostic.c \
 					$(eap_sources) \
 					$(builtin_sources)
 
diff --git a/src/diagnostic.c b/src/diagnostic.c
new file mode 100644
index 00000000..1c2d6d18
--- /dev/null
+++ b/src/diagnostic.c
@@ -0,0 +1,109 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2020  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ell/ell.h>
+
+#include "src/diagnostic.h"
+#include "src/dbus.h"
+
+/*
+ * Appends values from diagnostic_station_info into a DBus dictionary. This
+ * assumes the DBus dictionary array has already been 'entered', and expects the
+ * caller to 'leave' once called. This does not append the station address
+ * since the dictionary key name may be different depending on the caller.
+ */
+bool diagnostic_info_to_dict(const struct diagnostic_station_info *info,
+				struct l_dbus_message_builder *builder)
+{
+	int16_t rssi = (int16_t)info->cur_rssi;
+
+	if (info->have_cur_rssi)
+		dbus_append_dict_basic(builder, "RSSI", 'n', &rssi);
+
+	if (info->have_rx_mcs) {
+		switch (info->rx_mcs_type) {
+		case DIAGNOSTIC_MCS_TYPE_HT:
+			dbus_append_dict_basic(builder, "RxMode", 's',
+						"802.11n");
+			dbus_append_dict_basic(builder, "RxMCS", 'y',
+						&info->rx_mcs);
+			break;
+		case DIAGNOSTIC_MCS_TYPE_VHT:
+			dbus_append_dict_basic(builder, "RxMode", 's',
+						"802.11ac");
+			dbus_append_dict_basic(builder, "RxMCS", 'y',
+						&info->rx_mcs);
+			break;
+		case DIAGNOSTIC_MCS_TYPE_HE:
+			dbus_append_dict_basic(builder, "RxMode", 's',
+						"802.11ax");
+			dbus_append_dict_basic(builder, "RxMCS", 'y',
+						&info->rx_mcs);
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (info->have_tx_mcs) {
+		switch (info->tx_mcs_type) {
+		case DIAGNOSTIC_MCS_TYPE_HT:
+			dbus_append_dict_basic(builder, "TxMode", 's',
+						"802.11n");
+			dbus_append_dict_basic(builder, "TxMCS", 'y',
+						&info->tx_mcs);
+			break;
+		case DIAGNOSTIC_MCS_TYPE_VHT:
+			dbus_append_dict_basic(builder, "TxMode", 's',
+						"802.11ac");
+			dbus_append_dict_basic(builder, "TxMCS", 'y',
+						&info->tx_mcs);
+			break;
+		case DIAGNOSTIC_MCS_TYPE_HE:
+			dbus_append_dict_basic(builder, "TxMode", 's',
+						"802.11ax");
+			dbus_append_dict_basic(builder, "TxMCS", 'y',
+						&info->tx_mcs);
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (info->have_tx_bitrate)
+		dbus_append_dict_basic(builder, "TxBitrate", 'u',
+					&info->tx_bitrate);
+
+	if (info->have_rx_bitrate)
+		dbus_append_dict_basic(builder, "RxBitrate", 'u',
+					&info->rx_bitrate);
+
+	if (info->have_expected_throughput)
+		dbus_append_dict_basic(builder, "ExpectedThroughput", 'u',
+					&info->expected_throughput);
+
+	return true;
+}
diff --git a/src/diagnostic.h b/src/diagnostic.h
index 8292d192..e66dd782 100644
--- a/src/diagnostic.h
+++ b/src/diagnostic.h
@@ -47,3 +47,6 @@ struct diagnostic_station_info {
 	bool have_tx_bitrate : 1;
 	bool have_expected_throughput : 1;
 };
+
+bool diagnostic_info_to_dict(const struct diagnostic_station_info *info,
+				struct l_dbus_message_builder *builder);
-- 
2.26.2

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

* [PATCH v3 3/7] station: refactor to use diagnostic_info_to_dict
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
  2021-01-22 18:14 ` [PATCH v3 2/7] diagnostic: commonize the building of diagnostic dict James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  2021-01-22 18:14 ` [PATCH v3 4/7] ap: add AP diagnostic interface James Prestwood
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

---
 src/station.c | 68 +--------------------------------------------------
 1 file changed, 1 insertion(+), 67 deletions(-)

diff --git a/src/station.c b/src/station.c
index 41f19b09..c71d8e6c 100644
--- a/src/station.c
+++ b/src/station.c
@@ -3463,7 +3463,6 @@ static void station_get_diagnostic_cb(
 	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);
@@ -3472,8 +3471,6 @@ static void station_get_diagnostic_cb(
 
 	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}");
@@ -3481,70 +3478,7 @@ static void station_get_diagnostic_cb(
 	dbus_append_dict_basic(builder, "ConnectedBss", 's',
 					util_address_to_string(info->addr));
 
-	if (info->have_cur_rssi)
-		dbus_append_dict_basic(builder, "RSSI", 'n', &rssi);
-
-	if (info->have_rx_mcs) {
-		switch (info->rx_mcs_type) {
-		case NETDEV_MCS_TYPE_HT:
-			dbus_append_dict_basic(builder, "RxMode", 's',
-						"802.11n");
-			dbus_append_dict_basic(builder, "RxMCS", 'y',
-						&info->rx_mcs);
-			break;
-		case NETDEV_MCS_TYPE_VHT:
-			dbus_append_dict_basic(builder, "RxMode", 's',
-						"802.11ac");
-			dbus_append_dict_basic(builder, "RxMCS", 'y',
-						&info->rx_mcs);
-			break;
-		case NETDEV_MCS_TYPE_HE:
-			dbus_append_dict_basic(builder, "RxMode", 's',
-						"802.11ax");
-			dbus_append_dict_basic(builder, "RxMCS", 'y',
-						&info->rx_mcs);
-			break;
-		default:
-			break;
-		}
-	}
-
-	if (info->have_tx_mcs) {
-		switch (info->tx_mcs_type) {
-		case NETDEV_MCS_TYPE_HT:
-			dbus_append_dict_basic(builder, "TxMode", 's',
-						"802.11n");
-			dbus_append_dict_basic(builder, "TxMCS", 'y',
-						&info->tx_mcs);
-			break;
-		case NETDEV_MCS_TYPE_VHT:
-			dbus_append_dict_basic(builder, "TxMode", 's',
-						"802.11ac");
-			dbus_append_dict_basic(builder, "TxMCS", 'y',
-						&info->tx_mcs);
-			break;
-		case NETDEV_MCS_TYPE_HE:
-			dbus_append_dict_basic(builder, "TxMode", 's',
-						"802.11ax");
-			dbus_append_dict_basic(builder, "TxMCS", 'y',
-						&info->tx_mcs);
-			break;
-		default:
-			break;
-		}
-	}
-
-	if (info->have_tx_bitrate)
-		dbus_append_dict_basic(builder, "TxBitrate", 'u',
-					&info->tx_bitrate);
-
-	if (info->have_rx_bitrate)
-		dbus_append_dict_basic(builder, "RxBitrate", 'u',
-					&info->rx_bitrate);
-
-	if (info->have_expected_throughput)
-		dbus_append_dict_basic(builder, "ExpectedThroughput", 'u',
-					&info->expected_throughput);
+	diagnostic_info_to_dict(info, builder);
 
 	l_dbus_message_builder_leave_array(builder);
 	l_dbus_message_builder_finalize(builder);
-- 
2.26.2

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

* [PATCH v3 4/7] ap: add AP diagnostic interface
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
  2021-01-22 18:14 ` [PATCH v3 2/7] diagnostic: commonize the building of diagnostic dict James Prestwood
  2021-01-22 18:14 ` [PATCH v3 3/7] station: refactor to use diagnostic_info_to_dict James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  2021-01-22 18:14 ` [PATCH v3 5/7] client: implement diagnostic module James Prestwood
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

This adds a new AccessPointDiagnostic interface. This interface
provides similar low level functionality as StationDiagnostic, but
for when IWD is in AP mode. This uses netdev_get_all_stations
which will dump all stations, parse, and return each station in
an individual callback. Once the dump is complete the destroy is
called and all data is packaged as an array of dictionaries.
---
 src/ap.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/src/ap.c b/src/ap.c
index d9e7e404..cef28327 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -52,6 +52,7 @@
 #include "src/eap-wsc.h"
 #include "src/ap.h"
 #include "src/storage.h"
+#include "src/diagnostic.h"
 
 struct ap_state {
 	struct netdev *netdev;
@@ -2963,6 +2964,89 @@ static void ap_destroy_interface(void *user_data)
 	l_free(ap_if);
 }
 
+struct diagnostic_data {
+	struct l_dbus_message *pending;
+	struct l_dbus_message_builder *builder;
+};
+
+static void ap_get_station_cb(const struct diagnostic_station_info *info,
+				void *user_data)
+{
+	struct diagnostic_data *data = user_data;
+
+	/* First station info */
+	if (!data->builder) {
+		struct l_dbus_message *reply =
+				l_dbus_message_new_method_return(data->pending);
+
+		data->builder = l_dbus_message_builder_new(reply);
+
+		l_dbus_message_builder_enter_array(data->builder, "a{sv}");
+	}
+
+	l_dbus_message_builder_enter_array(data->builder, "{sv}");
+	dbus_append_dict_basic(data->builder, "Address", 's',
+					util_address_to_string(info->addr));
+
+	diagnostic_info_to_dict(info, data->builder);
+
+	l_dbus_message_builder_leave_array(data->builder);
+}
+
+static void ap_get_station_destroy(void *user_data)
+{
+	struct diagnostic_data *data = user_data;
+	struct l_dbus_message *reply;
+
+	if (!data->builder) {
+		reply = l_dbus_message_new_method_return(data->pending);
+
+		data->builder = l_dbus_message_builder_new(reply);
+
+		l_dbus_message_builder_enter_array(data->builder, "a{sv}");
+	}
+
+	l_dbus_message_builder_leave_array(data->builder);
+	reply = l_dbus_message_builder_finalize(data->builder);
+	l_dbus_message_builder_destroy(data->builder);
+
+	dbus_pending_reply(&data->pending, reply);
+
+	l_free(data);
+}
+
+static struct l_dbus_message *ap_dbus_get_diagnostics(struct l_dbus *dbus,
+		struct l_dbus_message *message, void *user_data)
+{
+	struct ap_if_data *ap_if = user_data;
+	struct diagnostic_data *data;
+	int ret;
+
+	data = l_new(struct diagnostic_data, 1);
+	data->pending = l_dbus_message_ref(message);
+
+	ret = netdev_get_all_stations(ap_if->ap->netdev, ap_get_station_cb,
+					data, ap_get_station_destroy);
+
+	if (ret < 0) {
+		l_dbus_message_unref(data->pending);
+		l_free(data);
+		return dbus_error_from_errno(ret, message);
+	}
+
+	return NULL;
+}
+
+static void ap_setup_diagnostic_interface(struct l_dbus_interface *interface)
+{
+	l_dbus_interface_method(interface, "GetDiagnostics", 0,
+				ap_dbus_get_diagnostics, "aa{sv}", "", "diagnostic");
+}
+
+static void ap_diagnostic_interface_destroy(void *user_data)
+{
+}
+
 static void ap_add_interface(struct netdev *netdev)
 {
 	struct ap_if_data *ap_if;
@@ -2978,12 +3062,16 @@ static void ap_add_interface(struct netdev *netdev)
 	/* setup ap dbus interface */
 	l_dbus_object_add_interface(dbus_get_bus(),
 			netdev_get_path(netdev), IWD_AP_INTERFACE, ap_if);
+	l_dbus_object_add_interface(dbus_get_bus(), netdev_get_path(netdev),
+			IWD_AP_DIAGNOSTIC_INTERFACE, ap_if);
 }
 
 static void ap_remove_interface(struct netdev *netdev)
 {
 	l_dbus_object_remove_interface(dbus_get_bus(),
 			netdev_get_path(netdev), IWD_AP_INTERFACE);
+	l_dbus_object_remove_interface(dbus_get_bus(), netdev_get_path(netdev),
+			IWD_AP_DIAGNOSTIC_INTERFACE);
 }
 
 static void ap_netdev_watch(struct netdev *netdev,
@@ -3014,6 +3102,9 @@ static int ap_init(void)
 
 	l_dbus_register_interface(dbus_get_bus(), IWD_AP_INTERFACE,
 			ap_setup_interface, ap_destroy_interface, false);
+	l_dbus_register_interface(dbus_get_bus(), IWD_AP_DIAGNOSTIC_INTERFACE,
+			ap_setup_diagnostic_interface,
+			ap_diagnostic_interface_destroy, false);
 
 	/*
 	 * Reusing [General].EnableNetworkConfiguration as a switch to enable
-- 
2.26.2

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

* [PATCH v3 5/7] client: implement diagnostic module
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
                   ` (2 preceding siblings ...)
  2021-01-22 18:14 ` [PATCH v3 4/7] ap: add AP diagnostic interface James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  2021-01-22 18:14 ` [PATCH v3 6/7] client: implement "ap <wlan> show" James Prestwood
  2021-01-22 18:14 ` [PATCH v3 7/7] client: update station to use diagnostic_display James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

For now this module serves as a helper for printing diagnostic
dictionary values. The new API (diagnostic_display) takes a
Dbus iterator which has been entered into a dictionary and
prints out each key and value. A mapping struct was defined
which maps keys to types and units. For simple cases the mapping
will consist of a dbus type character and a units string,
e.g. dBm, Kbit/s etc. For more complex printing which requires
processing the value the 'units' void* cant be set to a
function which can be custom written to handle the value.
---
 Makefile.am         |   3 +-
 client/diagnostic.c | 166 ++++++++++++++++++++++++++++++++++++++++++++
 client/diagnostic.h |  26 +++++++
 3 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 client/diagnostic.c
 create mode 100644 client/diagnostic.h

v3:
 * Moved this into its own file/module

diff --git a/Makefile.am b/Makefile.am
index a0701c97..0cbadb09 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -286,7 +286,8 @@ client_iwctl_SOURCES = client/main.c \
 			client/known-networks.c \
 			client/network.h client/network.c \
 			client/properties.h client/properties.c \
-			client/wsc.c client/station.c
+			client/wsc.c client/station.c \
+			client/diagnostic.c client/diagnostic.h
 client_iwctl_LDADD = $(ell_ldadd) $(READLINE_LIBS)
 
 if MANUAL_PAGES
diff --git a/client/diagnostic.c b/client/diagnostic.c
new file mode 100644
index 00000000..73f71563
--- /dev/null
+++ b/client/diagnostic.c
@@ -0,0 +1,166 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2020  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <ell/ell.h>
+
+#include "client/diagnostic.h"
+#include "client/display.h"
+
+typedef void (*display_dict_custom_func_t)(struct l_dbus_message_iter *variant,
+				const char *key, const char *margin,
+				int name_column_width, int value_column_width);
+
+/*
+ * Maps dictionary keys to types/units. 'type' should be a valid DBus type, or
+ * zero for displaying in a custom fashion. When the display needs to be
+ * customized 'units' should point to a custom display function of the form
+ * display_dict_custom_func_t which should display the entire value as well
+ * as any units required.
+ */
+struct display_dict_mapping {
+	const char *key;
+	char type;
+	const char *units;
+	display_dict_custom_func_t custom;
+};
+
+static const struct display_dict_mapping *find_mapping(const char *key,
+				const struct display_dict_mapping *mapping)
+{
+	int idx = 0;
+
+	while (mapping[idx].key) {
+		if (!strcmp(mapping[idx].key, key))
+			return &mapping[idx];
+
+		idx++;
+	}
+
+	return NULL;
+}
+
+static void display_bitrate_100kbps(struct l_dbus_message_iter *variant,
+				const char *key, const char *margin,
+				int name_column_width, int value_column_width)
+{
+	uint32_t rate;
+
+	l_dbus_message_iter_get_variant(variant, "u", &rate);
+
+	display("%s%-*s%-*u Kbit/s\n", margin, name_column_width, key,
+			value_column_width, rate * 100);
+}
+
+static const struct display_dict_mapping diagnostic_mapping[] = {
+	{ "Address", 's' },
+	{ "ConnectedBss", 's' },
+	{ "RxMode", 's' },
+	{ "TxMode", 's' },
+	{ "RxBitrate", 0, NULL, display_bitrate_100kbps },
+	{ "TxBitrate", 0, NULL, display_bitrate_100kbps },
+	{ "ExpectedThroughput", 'u', "Kbit/s" },
+	{ "RSSI", 'n', "dBm" },
+	{ "RxMCS", 'y' },
+	{ "TxMCS", 'y' },
+	{ NULL }
+};
+
+void diagnostic_display(struct l_dbus_message_iter *dict,
+			const char *margin, int name_column_width,
+			int value_column_width)
+{
+	struct l_dbus_message_iter variant;
+	const char *key;
+	const struct display_dict_mapping *map;
+	char display_text[160];
+
+	while (l_dbus_message_iter_next_entry(dict, &key, &variant)) {
+		const char *s_value;
+		uint32_t u_value;
+		int16_t n_value;
+		uint8_t y_value;
+
+		map = find_mapping(key, diagnostic_mapping);
+		if (!map)
+			continue;
+
+		switch (map->type) {
+		case 0:
+			if (!map->custom)
+				continue;
+
+			map->custom(&variant, key, margin, name_column_width,
+					value_column_width);
+
+			/* custom should handle any units, so continue */
+			continue;
+
+		case 's':
+			l_dbus_message_iter_get_variant(&variant, "s",
+							&s_value);
+			sprintf(display_text, "%s%-*s%-*s", margin,
+					name_column_width, key,
+					value_column_width, s_value);
+			break;
+
+		case 'u':
+			l_dbus_message_iter_get_variant(&variant, "u",
+							&u_value);
+			sprintf(display_text, "%s%-*s%-*u", margin,
+						name_column_width, key,
+						value_column_width, u_value);
+			break;
+
+		case 'n':
+			l_dbus_message_iter_get_variant(&variant, "n",
+							&n_value);
+			sprintf(display_text, "%s%-*s%-*i", margin,
+						name_column_width, key,
+						value_column_width, n_value);
+			break;
+
+		case 'y':
+			l_dbus_message_iter_get_variant(&variant, "y",
+							&y_value);
+			sprintf(display_text, "%s%-*s%-*u", margin,
+						name_column_width, key,
+						value_column_width, y_value);
+			break;
+
+		default:
+			display("type %c not handled", map->type);
+			continue;
+		}
+
+		if (map->units)
+			display("%s %s\n", display_text,
+					(const char *)map->units);
+		else
+			display("%s\n", display_text);
+	}
+}
diff --git a/client/diagnostic.h b/client/diagnostic.h
new file mode 100644
index 00000000..004bbe85
--- /dev/null
+++ b/client/diagnostic.h
@@ -0,0 +1,26 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2020  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+struct l_dbus_message_iter;
+
+void diagnostic_display(struct l_dbus_message_iter *dict, const char *margin,
+			int name_column_width, int value_column_width);
-- 
2.26.2

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

* [PATCH v3 6/7] client: implement "ap <wlan> show"
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
                   ` (3 preceding siblings ...)
  2021-01-22 18:14 ` [PATCH v3 5/7] client: implement diagnostic module James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  2021-01-22 18:14 ` [PATCH v3 7/7] client: update station to use diagnostic_display James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

This command uses GetDiagnostics to show a list of connected
clients and some information about them. The information
contained for each connected station nearly maps 1:1 with the
station diagnostics information shown in "station <wlan> show"
apart from "ConnectedBss" which is now "Address".
---
 client/ap.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/client/ap.c b/client/ap.c
index a6a2681b..81baa3fc 100644
--- a/client/ap.c
+++ b/client/ap.c
@@ -30,6 +30,7 @@
 #include "client/dbus-proxy.h"
 #include "client/device.h"
 #include "client/display.h"
+#include "client/diagnostic.h"
 
 struct ap {
 	bool started;
@@ -189,6 +190,51 @@ static enum cmd_status cmd_stop(const char *device_name, char **argv, int argc)
 	return CMD_STATUS_TRIGGERED;
 }
 
+static struct proxy_interface_type ap_diagnostic_interface_type = {
+	.interface = IWD_AP_DIAGNOSTIC_INTERFACE,
+};
+
+static void ap_get_diagnostics_callback(struct l_dbus_message *message,
+					void *user_data)
+{
+	struct l_dbus_message_iter array;
+	struct l_dbus_message_iter iter;
+	uint16_t idx = 0;
+	char client_num[15];
+
+	if (dbus_message_has_error(message))
+		return;
+
+	if (!l_dbus_message_get_arguments(message, "aa{sv}", &array)) {
+		display("Failed to parse GetDiagnostics message");
+		return;
+	}
+
+	while (l_dbus_message_iter_next_entry(&array, &iter)) {
+		sprintf(client_num, "Client %u", idx++);
+		display_table_header(client_num, "%-*s%-*s",
+					20, "Property", 20, "Value");
+		diagnostic_display(&iter, "", 20, 20);
+		display_table_footer();
+	}
+}
+
+static enum cmd_status cmd_show(const char *device_name, char **argv, int argc)
+{
+	const struct proxy_interface *ap_diagnostic =
+		device_proxy_find(device_name, IWD_AP_DIAGNOSTIC_INTERFACE);
+
+	if (!ap_diagnostic) {
+		display("No ap on device: '%s'\n", device_name);
+		return CMD_STATUS_INVALID_VALUE;
+	}
+
+	proxy_interface_method_call(ap_diagnostic, "GetDiagnostics", "",
+					ap_get_diagnostics_callback);
+
+	return CMD_STATUS_TRIGGERED;
+}
+
 static const struct command ap_commands[] = {
 	{ NULL, "list", NULL, cmd_list, "List devices in AP mode", true },
 	{ "<wlan>", "start", "<\"network name\"> <passphrase>", cmd_start,
@@ -196,6 +242,7 @@ static const struct command ap_commands[] = {
 		"name\" with\n\t\t\t\t\t\t    a passphrase" },
 	{ "<wlan>", "stop", NULL,   cmd_stop, "Stop a started access\n"
 		"\t\t\t\t\t\t    point" },
+	{ "<wlan", "show", NULL, cmd_show, "Show AP info", false },
 	{ }
 };
 
@@ -236,6 +283,7 @@ COMMAND_FAMILY(ap_command_family, ap_command_family_init,
 static int ap_interface_init(void)
 {
 	proxy_interface_type_register(&ap_interface_type);
+	proxy_interface_type_register(&ap_diagnostic_interface_type);
 
 	return 0;
 }
@@ -243,6 +291,7 @@ static int ap_interface_init(void)
 static void ap_interface_exit(void)
 {
 	proxy_interface_type_unregister(&ap_interface_type);
+	proxy_interface_type_unregister(&ap_diagnostic_interface_type);
 }
 
 INTERFACE_TYPE(ap_interface_type, ap_interface_init, ap_interface_exit)
-- 
2.26.2

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

* [PATCH v3 7/7] client: update station to use diagnostic_display
  2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
                   ` (4 preceding siblings ...)
  2021-01-22 18:14 ` [PATCH v3 6/7] client: implement "ap <wlan> show" James Prestwood
@ 2021-01-22 18:14 ` James Prestwood
  5 siblings, 0 replies; 7+ messages in thread
From: James Prestwood @ 2021-01-22 18:14 UTC (permalink / raw)
  To: iwd

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

---
 client/station.c | 50 ++----------------------------------------------
 1 file changed, 2 insertions(+), 48 deletions(-)

diff --git a/client/station.c b/client/station.c
index 93b1a4da..0bda604c 100644
--- a/client/station.c
+++ b/client/station.c
@@ -31,6 +31,7 @@
 #include "client/device.h"
 #include "client/network.h"
 #include "client/display.h"
+#include "client/diagnostic.h"
 
 struct station {
 	bool scanning;
@@ -597,8 +598,6 @@ static void get_diagnostics_callback(struct l_dbus_message *message,
 					void *user_data)
 {
 	struct l_dbus_message_iter iter;
-	struct l_dbus_message_iter variant;
-	const char *key;
 
 	if (dbus_message_has_error(message))
 		return;
@@ -608,52 +607,7 @@ static void get_diagnostics_callback(struct l_dbus_message *message,
 		goto done;
 	}
 
-	while (l_dbus_message_iter_next_entry(&iter, &key, &variant)) {
-		const char *s_value;
-		uint32_t u_value;
-		int16_t i_value;
-		uint8_t y_value;
-
-		if (!strcmp(key, "ConnectedBss") || !strcmp(key, "RxMode") ||
-				!strcmp(key, "TxMode")) {
-			/* String variants with no special handling */
-
-			l_dbus_message_iter_get_variant(&variant, "s",
-							&s_value);
-
-			display("%s%*s  %-*s%-*s\n", MARGIN, 8, "", 20,
-				key, 47, s_value);
-		} else if (!strcmp(key, "RxBitrate") ||
-				!strcmp(key, "TxBitrate")) {
-			/* Bitrates expressed in 100Kbit/s */
-
-			l_dbus_message_iter_get_variant(&variant, "u",
-							&u_value);
-			display("%s%*s  %-*s%u Kbit/s\n", MARGIN, 8, "", 20,
-				key, u_value * 100);
-		} else if (!strcmp(key, "ExpectedThroughput")) {
-			/* ExpectedThroughput expressed in Kbit/s */
-
-			l_dbus_message_iter_get_variant(&variant, "u",
-							&u_value);
-			display("%s%*s  %-*s%u Kbit/s\n", MARGIN, 8, "", 20,
-				key, u_value);
-		} else if (!strcmp(key, "RSSI")) {
-			/* RSSI expressed in dBm */
-
-			l_dbus_message_iter_get_variant(&variant, "n",
-							&i_value);
-			display("%s%*s  %-*s%i dBm\n", MARGIN, 8, "", 20,
-				key, i_value);
-		} else if (!strcmp(key, "RxMCS") || !strcmp(key, "TxMCS")) {
-			/* MCS index's are single byte integers */
-
-			l_dbus_message_iter_get_variant(&variant, "y",
-							&y_value);
-			display("%s%*s  %-*s%u\n", MARGIN, 8, "", 20,
-				key, y_value);
-		}
-	}
+	diagnostic_display(&iter, "            ", 20, 20);
 
 done:
 	/* Finish the table started by cmd_show */
-- 
2.26.2

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

end of thread, other threads:[~2021-01-22 18:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-22 18:14 [PATCH v3 1/7] netdev: move netdev_station_info to diagnostic.h James Prestwood
2021-01-22 18:14 ` [PATCH v3 2/7] diagnostic: commonize the building of diagnostic dict James Prestwood
2021-01-22 18:14 ` [PATCH v3 3/7] station: refactor to use diagnostic_info_to_dict James Prestwood
2021-01-22 18:14 ` [PATCH v3 4/7] ap: add AP diagnostic interface James Prestwood
2021-01-22 18:14 ` [PATCH v3 5/7] client: implement diagnostic module James Prestwood
2021-01-22 18:14 ` [PATCH v3 6/7] client: implement "ap <wlan> show" James Prestwood
2021-01-22 18:14 ` [PATCH v3 7/7] client: update station to use diagnostic_display 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.