From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH 4/8] ap: add AP diagnostic interface
Date: Wed, 20 Jan 2021 10:30:32 -0800 [thread overview]
Message-ID: <20210120183036.477287-4-prestwoj@gmail.com> (raw)
In-Reply-To: <20210120183036.477287-1-prestwoj@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 6047 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 | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 156 insertions(+)
diff --git a/src/ap.c b/src/ap.c
index d9e7e404..6b3fb129 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -2963,6 +2963,155 @@ 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 netdev_station_info *info,
+ void *user_data)
+{
+ struct diagnostic_data *data = user_data;
+ int16_t rssi;
+
+ /* 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));
+
+ rssi = (int16_t)info->cur_rssi;
+
+ if (info->have_cur_rssi)
+ dbus_append_dict_basic(data->builder, "RSSI", 'n', &rssi);
+
+ if (info->have_rx_mcs) {
+ switch (info->rx_mcs_type) {
+ case NETDEV_MCS_TYPE_HT:
+ dbus_append_dict_basic(data->builder, "RxMode", 's',
+ "802.11n");
+ dbus_append_dict_basic(data->builder, "RxMCS", 'y',
+ &info->rx_mcs);
+ break;
+ case NETDEV_MCS_TYPE_VHT:
+ dbus_append_dict_basic(data->builder, "RxMode", 's',
+ "802.11ac");
+ dbus_append_dict_basic(data->builder, "RxMCS", 'y',
+ &info->rx_mcs);
+ break;
+ case NETDEV_MCS_TYPE_HE:
+ dbus_append_dict_basic(data->builder, "RxMode", 's',
+ "802.11ax");
+ dbus_append_dict_basic(data->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(data->builder, "TxMode", 's',
+ "802.11n");
+ dbus_append_dict_basic(data->builder, "TxMCS", 'y',
+ &info->tx_mcs);
+ break;
+ case NETDEV_MCS_TYPE_VHT:
+ dbus_append_dict_basic(data->builder, "TxMode", 's',
+ "802.11ac");
+ dbus_append_dict_basic(data->builder, "TxMCS", 'y',
+ &info->tx_mcs);
+ break;
+ case NETDEV_MCS_TYPE_HE:
+ dbus_append_dict_basic(data->builder, "TxMode", 's',
+ "802.11ax");
+ dbus_append_dict_basic(data->builder, "TxMCS", 'y',
+ &info->tx_mcs);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (info->have_tx_bitrate)
+ dbus_append_dict_basic(data->builder, "TxBitrate", 'u',
+ &info->tx_bitrate);
+
+ if (info->have_rx_bitrate)
+ dbus_append_dict_basic(data->builder, "RxBitrate", 'u',
+ &info->rx_bitrate);
+
+ if (info->have_expected_throughput)
+ dbus_append_dict_basic(data->builder, "ExpectedThroughput", 'u',
+ &info->expected_throughput);
+
+ 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 +3127,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 +3167,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
next prev parent reply other threads:[~2021-01-20 18:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-20 18:30 [PATCH 1/8] doc: document AccessPointDiagnostic interface James Prestwood
2021-01-20 18:30 ` [PATCH 2/8] netdev: add netdev_get_all_stations James Prestwood
2021-01-20 20:06 ` Denis Kenzior
2021-01-20 18:30 ` [PATCH 3/8] dbus: add AccessPointDiagnostic interface James Prestwood
2021-01-20 18:30 ` James Prestwood [this message]
2021-01-20 20:11 ` [PATCH 4/8] ap: add AP diagnostic interface Denis Kenzior
2021-01-20 18:30 ` [PATCH 5/8] client: add AccessPointDiagnostic interface definition James Prestwood
2021-01-20 20:14 ` Denis Kenzior
2021-01-20 18:30 ` [PATCH 6/8] client: implement "ap <wlan> show" James Prestwood
2021-01-20 20:16 ` Denis Kenzior
2021-01-20 20:36 ` James Prestwood
2021-01-20 18:30 ` [PATCH 7/8] test: add AccessPointDiagnostics to monitor-iwd James Prestwood
2021-01-20 18:30 ` [PATCH 8/8] test: add StationDiagnostic interface " James Prestwood
2021-01-20 20:00 ` [PATCH 1/8] doc: document AccessPointDiagnostic interface Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210120183036.477287-4-prestwoj@gmail.com \
--to=prestwoj@gmail.com \
--cc=iwd@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox