3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-20 04:19:25 +01:00

client: add station diagnostic information to 'show'

The information requested with GetDiagnostics will now appear in
the "station <iface> show" command. If IWD is not connected, or
there is no diagnostic interface (older IWD version) 'show' will
behave as it always has, only showing scanning/connected.
This commit is contained in:
James Prestwood 2021-01-19 09:14:45 -08:00 committed by Denis Kenzior
parent c15cdbe753
commit 1f8f209c04

View File

@ -130,6 +130,10 @@ static struct proxy_interface_type station_interface_type = {
.ops = &station_ops, .ops = &station_ops,
}; };
static struct proxy_interface_type station_diagnostic_interface = {
.interface = IWD_STATION_DIAGNOSTIC_INTERFACE,
};
static void check_errors_method_callback(struct l_dbus_message *message, static void check_errors_method_callback(struct l_dbus_message *message,
void *user_data) void *user_data)
{ {
@ -137,7 +141,8 @@ static void check_errors_method_callback(struct l_dbus_message *message,
} }
static void display_station(const char *device_name, static void display_station(const char *device_name,
const struct proxy_interface *proxy) const struct proxy_interface *proxy,
bool *connected)
{ {
const struct station *station = proxy_interface_get_data(proxy); const struct station *station = proxy_interface_get_data(proxy);
char *caption = l_strdup_printf("%s: %s", "Station", device_name); char *caption = l_strdup_printf("%s: %s", "Station", device_name);
@ -145,10 +150,15 @@ static void display_station(const char *device_name,
proxy_properties_display(proxy, caption, MARGIN, 20, 47); proxy_properties_display(proxy, caption, MARGIN, 20, 47);
l_free(caption); l_free(caption);
if (station->connected_network) if (station->connected_network) {
display("%s%*s %-*s%-*s\n", MARGIN, 8, "", 20, display("%s%*s %-*s%-*s\n", MARGIN, 8, "", 20,
"Connected network", 47, "Connected network", 47,
network_get_name(station->connected_network)); network_get_name(station->connected_network));
*connected = true;
return;
}
*connected = false;
display_table_footer(); display_table_footer();
} }
@ -583,20 +593,106 @@ static enum cmd_status cmd_scan(const char *device_name,
return CMD_STATUS_TRIGGERED; return CMD_STATUS_TRIGGERED;
} }
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;
if (!l_dbus_message_get_arguments(message, "a{sv}", &iter)) {
l_error("Failed to parse GetDiagnostics 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);
}
}
done:
/* Finish the table started by cmd_show */
display_table_footer();
display_refresh_reset();
}
static enum cmd_status cmd_show(const char *device_name, static enum cmd_status cmd_show(const char *device_name,
char **argv, int argc) char **argv, int argc)
{ {
const struct proxy_interface *station = const struct proxy_interface *station =
device_proxy_find(device_name, IWD_STATION_INTERFACE); device_proxy_find(device_name, IWD_STATION_INTERFACE);
const struct proxy_interface *diagnostic =
device_proxy_find(device_name,
IWD_STATION_DIAGNOSTIC_INTERFACE);
bool connected;
if (!station) { if (!station) {
display("No station on device: '%s'\n", device_name); display("No station on device: '%s'\n", device_name);
return CMD_STATUS_INVALID_VALUE; return CMD_STATUS_INVALID_VALUE;
} }
display_station(device_name, station); display_station(device_name, station, &connected);
return CMD_STATUS_DONE; /*
* No need to query additional diagnostic information if not connected,
* or IWD has no diagnostic interface.
*/
if (!connected || !diagnostic) {
display_table_footer();
display_refresh_reset();
return CMD_STATUS_DONE;
}
proxy_interface_method_call(diagnostic, "GetDiagnostics", "",
get_diagnostics_callback);
/* Don't display table footer, this will be done in the callback */
return CMD_STATUS_TRIGGERED;
} }
static const struct command station_commands[] = { static const struct command station_commands[] = {
@ -663,6 +759,7 @@ COMMAND_FAMILY(station_command_family, station_command_family_init,
static int station_interface_init(void) static int station_interface_init(void)
{ {
proxy_interface_type_register(&station_interface_type); proxy_interface_type_register(&station_interface_type);
proxy_interface_type_register(&station_diagnostic_interface);
return 0; return 0;
} }
@ -670,6 +767,7 @@ static int station_interface_init(void)
static void station_interface_exit(void) static void station_interface_exit(void)
{ {
proxy_interface_type_unregister(&station_interface_type); proxy_interface_type_unregister(&station_interface_type);
proxy_interface_type_unregister(&station_diagnostic_interface);
} }
INTERFACE_TYPE(station_interface_type, INTERFACE_TYPE(station_interface_type,