* [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface
@ 2024-08-12 15:46 James Prestwood
2024-08-12 15:46 ` [PATCH v3 02/13] network: Add BasicServiceSet object James Prestwood
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/dbus.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/dbus.h b/src/dbus.h
index b43412d7..14814b5d 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -48,6 +48,7 @@
#define IWD_NETCONFIG_AGENT_INTERFACE \
"net.connman.iwd.NetworkConfigurationAgent"
#define IWD_SHARED_CODE_AGENT_INTERFACE "net.connman.iwd.SharedCodeAgent"
+#define IWD_BSS_INTERFACE "net.connman.iwd.BasicServiceSet"
#define IWD_BASE_PATH "/net/connman/iwd"
#define IWD_AGENT_MANAGER_PATH IWD_BASE_PATH
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 02/13] network: Add BasicServiceSet object
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 03/13] station: use network_bss_{start,stop}_update James Prestwood
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This adds a new DBus object/interface for tracking BSS's for
a given network. Since scanning replaces scan_bss objects some
new APIs were added to avoid tearing down the associated DBus
object for each BSS.
network_bss_start_update() should be called before any new BSS's
are added to the network object. This will keep track of the old
list and create a new network->bss_list where more entries can
be added. This is effectively replacing network_bss_list_clear,
except it keeps the old list around until...
network_bss_stop_update() is called when all BSS's have been
added to the network object. This will then iterate the old list
and lookup if any BSS DBus objects need to be destroyed. Once
completed the old list is destroyed.
---
src/network.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/network.h | 6 +++
2 files changed, 137 insertions(+), 1 deletion(-)
v3:
* Pass the scan frequencies to stop_update() to avoid removing
BSS's that weren't on the frequencies scanned.
diff --git a/src/network.c b/src/network.c
index 09099fac..8c16d9a6 100644
--- a/src/network.c
+++ b/src/network.c
@@ -75,6 +75,7 @@ struct network {
struct l_ecc_point *sae_pt_20; /* SAE PT for Group 20 */
unsigned int agent_request;
struct l_queue *bss_list;
+ struct l_queue *old_bss_list;
struct l_settings *settings;
struct l_queue *secrets;
struct l_queue *blacklist; /* temporary blacklist for BSS's */
@@ -1129,12 +1130,107 @@ bool network_update_known_frequencies(struct network *network)
return true;
}
+const char *network_bss_get_path(const struct network *network,
+ const struct scan_bss *bss)
+{
+ static char path[256];
+
+ snprintf(path, sizeof(path), "%s/%02x%02x%02x%02x%02x%02x",
+ network->object_path, MAC_STR(bss->addr));
+
+ return path;
+}
+
+static bool network_unregister_bss(void *a, void *user_data)
+{
+ struct scan_bss *bss = a;
+ struct network *network = user_data;
+
+ l_dbus_unregister_object(dbus_get_bus(),
+ network_bss_get_path(network, bss));
+
+ return true;
+}
+
+static bool network_register_bss(struct network *network, struct scan_bss *bss)
+{
+ const char *path = network_bss_get_path(network, bss);
+ struct scan_bss *old;
+
+ /*
+ * If we find this path in the object tree update the data to the new
+ * scan_bss pointer, as this one will be freed soon.
+ */
+ old = l_dbus_object_get_data(dbus_get_bus(), path, IWD_BSS_INTERFACE);
+ if (old)
+ return l_dbus_object_set_data(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE, bss);
+
+ if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE, bss))
+ return false;
+
+ if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+ L_DBUS_INTERFACE_PROPERTIES, bss))
+ return false;
+
+ return true;
+}
+
+void network_bss_start_update(struct network *network)
+{
+ network->old_bss_list = network->bss_list;
+ network->bss_list = l_queue_new();
+}
+
+void network_bss_stop_update(struct network *network,
+ const struct scan_freq_set *limit_freqs)
+{
+ const struct l_queue_entry *e;
+
+ /*
+ * Update has finished, clean up any BSS's from the old list that have
+ * been registered on DBus.
+ */
+ for (e = l_queue_get_entries(network->old_bss_list); e; e = e->next) {
+ const struct scan_bss *old = e->data;
+ const struct scan_bss *bss;
+ const char *path = network_bss_get_path(network, old);
+
+ bss = l_dbus_object_get_data(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE);
+
+ /*
+ * Don't remove BSS's who's frequencies were not in the set.
+ * This happens due to scan subsets (i.e. from station) so some
+ * BSS's won't be seen since the frequency is not being scanned.
+ * These BSS's will get cleared out eventually if they have
+ * actually disappeared.
+ */
+ if (!scan_freq_set_contains(limit_freqs, bss->frequency))
+ continue;
+
+ /*
+ * The lookup matched the user data of an old BSS. This should
+ * be unregistered from DBus
+ */
+ if (bss && bss == old)
+ l_dbus_object_remove_interface(dbus_get_bus(), path,
+ IWD_BSS_INTERFACE);
+ }
+
+ l_queue_destroy(network->old_bss_list, NULL);
+ network->old_bss_list = NULL;
+}
+
bool network_bss_add(struct network *network, struct scan_bss *bss)
{
if (!l_queue_insert(network->bss_list, bss, scan_bss_rank_compare,
NULL))
return false;
+ network_register_bss(network, bss);
+
/* Done if BSS is not HS20 or we already have network_info set */
if (!bss->hs20_capable)
return true;
@@ -1168,6 +1264,8 @@ bool network_bss_update(struct network *network, struct scan_bss *bss)
l_queue_insert(network->bss_list, bss, scan_bss_rank_compare, NULL);
+ network_register_bss(network, bss);
+
/* Sync frequency for already known networks */
if (network->info) {
known_network_add_frequency(network->info, bss->frequency);
@@ -1190,7 +1288,12 @@ void network_bss_list_clear(struct network *network)
struct scan_bss *network_bss_list_pop(struct network *network)
{
- return l_queue_pop_head(network->bss_list);
+ struct scan_bss *bss = l_queue_pop_head(network->bss_list);
+
+ if (bss)
+ network_unregister_bss(bss, network);
+
+ return bss;
}
struct scan_bss *network_bss_find_by_addr(struct network *network,
@@ -1899,6 +2002,9 @@ static void network_unregister(struct network *network, int reason)
void network_remove(struct network *network, int reason)
{
+ l_queue_foreach_remove(network->bss_list,
+ network_unregister_bss, network);
+
if (network->object_path)
network_unregister(network, reason);
@@ -2155,6 +2261,24 @@ static void setup_network_interface(struct l_dbus_interface *interface)
network_property_get_known_network, NULL);
}
+static bool network_bss_property_get_address(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ void *user_data)
+{
+ struct scan_bss *bss = user_data;
+
+ l_dbus_message_builder_append_basic(builder, 's',
+ util_address_to_string(bss->addr));
+ return true;
+}
+
+static void setup_bss_interface(struct l_dbus_interface *interface)
+{
+ l_dbus_interface_property(interface, "Address", 0, "s",
+ network_bss_property_get_address, NULL);
+}
+
static int network_init(void)
{
if (!l_dbus_register_interface(dbus_get_bus(), IWD_NETWORK_INTERFACE,
@@ -2162,6 +2286,11 @@ static int network_init(void)
l_error("Unable to register %s interface",
IWD_NETWORK_INTERFACE);
+ if (!l_dbus_register_interface(dbus_get_bus(), IWD_BSS_INTERFACE,
+ setup_bss_interface, NULL, false))
+ l_error("Unable to register %s interface",
+ IWD_BSS_INTERFACE);
+
known_networks_watch =
known_networks_watch_add(known_networks_changed, NULL, NULL);
@@ -2179,6 +2308,7 @@ static void network_exit(void)
event_watch = 0;
l_dbus_unregister_interface(dbus_get_bus(), IWD_NETWORK_INTERFACE);
+ l_dbus_unregister_interface(dbus_get_bus(), IWD_BSS_INTERFACE);
}
IWD_MODULE(network, network_init, network_exit)
diff --git a/src/network.h b/src/network.h
index 17dfcca8..b27158ee 100644
--- a/src/network.h
+++ b/src/network.h
@@ -30,6 +30,7 @@ struct network;
struct scan_bss;
struct handshake_state;
struct erp_cache_entry;
+struct scan_freq_set;
void network_connected(struct network *network);
void network_disconnected(struct network *network);
@@ -67,8 +68,13 @@ int network_can_connect_bss(struct network *network,
const struct scan_bss *bss);
int network_autoconnect(struct network *network, struct scan_bss *bss);
void network_connect_failed(struct network *network, bool in_handshake);
+void network_bss_start_update(struct network *network);
+void network_bss_stop_update(struct network *network,
+ const struct scan_freq_set *freqs);
bool network_bss_add(struct network *network, struct scan_bss *bss);
bool network_bss_update(struct network *network, struct scan_bss *bss);
+const char *network_bss_get_path(const struct network *network,
+ const struct scan_bss *bss);
bool network_bss_list_isempty(struct network *network);
void network_bss_list_clear(struct network *network);
struct scan_bss *network_bss_list_pop(struct network *network);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 03/13] station: use network_bss_{start,stop}_update
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 02/13] network: Add BasicServiceSet object James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 04/13] network: add ExtendedServiceSet DBus property James Prestwood
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This will tell network the BSS list is being updated and it can
act accordingly as far as the BSS DBus registrations/unregistration.
In addition any scan_bss object needing to be freed has to wait
until after network_bss_stop_update() because network has to be able
to iterate its old list and unregister any BSS's that were not seen
in the scan results. This is done by pushing each BSS needing to be
freed into a queue, then destroying them after the BSS's are all
added.
---
src/station.c | 37 ++++++++++++++++++++++++++++++-------
1 file changed, 30 insertions(+), 7 deletions(-)
v3:
* Update use of stop_update() to provide the scan_freq_set. This
also required using a new struct to pass to process_network()
diff --git a/src/station.c b/src/station.c
index e373b03b..c45b849b 100644
--- a/src/station.c
+++ b/src/station.c
@@ -339,10 +339,18 @@ static void network_free(void *data)
network_remove(network, -ESHUTDOWN);
}
+struct process_network_data {
+ struct station *station;
+ const struct scan_freq_set *freqs;
+};
+
static bool process_network(const void *key, void *data, void *user_data)
{
struct network *network = data;
- struct station *station = user_data;
+ struct process_network_data *process_data = user_data;
+ struct station *station = process_data->station;
+
+ network_bss_stop_update(network, process_data->freqs);
if (!network_bss_list_isempty(network)) {
bool connected = network == station->connected_network;
@@ -532,6 +540,7 @@ struct bss_expiration_data {
struct scan_bss *connected_bss;
uint64_t now;
const struct scan_freq_set *freqs;
+ struct l_queue *free_list;
};
#define SCAN_RESULT_BSS_RETENTION_TIME (30 * 1000000)
@@ -553,18 +562,20 @@ static bool bss_free_if_expired(void *data, void *user_data)
bss->time_stamp + SCAN_RESULT_BSS_RETENTION_TIME))
return false;
- bss_free(bss);
+ l_queue_push_head(expiration_data->free_list, bss);
return true;
}
static void station_bss_list_remove_expired_bsses(struct station *station,
- const struct scan_freq_set *freqs)
+ const struct scan_freq_set *freqs,
+ struct l_queue *free_list)
{
struct bss_expiration_data data = {
.now = l_time_now(),
.connected_bss = station->connected_bss,
.freqs = freqs,
+ .free_list = free_list,
};
l_queue_foreach_remove(station->bss_list, bss_free_if_expired, &data);
@@ -939,18 +950,20 @@ void station_set_scan_results(struct station *station,
{
const struct l_queue_entry *bss_entry;
struct network *network;
+ struct process_network_data data;
+ struct l_queue *free_list = l_queue_new();
l_queue_foreach_remove(new_bss_list, bss_free_if_ssid_not_utf8, NULL);
while ((network = l_queue_pop_head(station->networks_sorted)))
- network_bss_list_clear(network);
+ network_bss_start_update(network);
l_queue_clear(station->hidden_bss_list_sorted, NULL);
l_queue_destroy(station->autoconnect_list, NULL);
station->autoconnect_list = NULL;
- station_bss_list_remove_expired_bsses(station, freqs);
+ station_bss_list_remove_expired_bsses(station, freqs, free_list);
for (bss_entry = l_queue_get_entries(station->bss_list); bss_entry;
bss_entry = bss_entry->next) {
@@ -962,7 +975,12 @@ void station_set_scan_results(struct station *station,
if (old_bss == station->connected_bss)
station->connected_bss = new_bss;
- bss_free(old_bss);
+ /*
+ * The network object is still holding a reference to
+ * the BSS. Until we tell network to replace the BSS
+ * with a new object, don't free it.
+ */
+ l_queue_push_head(free_list, old_bss);
continue;
}
@@ -994,7 +1012,12 @@ void station_set_scan_results(struct station *station,
station->bss_list = new_bss_list;
- l_hashmap_foreach_remove(station->networks, process_network, station);
+ data.station = station;
+ data.freqs = freqs;
+
+ l_hashmap_foreach_remove(station->networks, process_network, &data);
+
+ l_queue_destroy(free_list, bss_free);
station->autoconnect_can_start = trigger_autoconnect;
station_autoconnect_start(station);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 04/13] network: add ExtendedServiceSet DBus property
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 02/13] network: Add BasicServiceSet object James Prestwood
2024-08-12 15:46 ` [PATCH v3 03/13] station: use network_bss_{start,stop}_update James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 05/13] network: remove network_bss_list_clear James Prestwood
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This contains a list of all BasicServiceSet objects (paths) that
exist for a network.
---
src/network.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/src/network.c b/src/network.c
index 8c16d9a6..76238e56 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1149,6 +1149,9 @@ static bool network_unregister_bss(void *a, void *user_data)
l_dbus_unregister_object(dbus_get_bus(),
network_bss_get_path(network, bss));
+ l_dbus_property_changed(dbus_get_bus(), network->object_path,
+ IWD_NETWORK_INTERFACE, "ExtendedServiceSet");
+
return true;
}
@@ -1174,6 +1177,9 @@ static bool network_register_bss(struct network *network, struct scan_bss *bss)
L_DBUS_INTERFACE_PROPERTIES, bss))
return false;
+ l_dbus_property_changed(dbus_get_bus(), network->object_path,
+ IWD_NETWORK_INTERFACE, "ExtendedServiceSet");
+
return true;
}
@@ -1960,6 +1966,28 @@ static bool network_property_get_known_network(struct l_dbus *dbus,
return true;
}
+static bool network_property_get_extended_service_set(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ void *user_data)
+{
+ struct network *network = user_data;
+ const struct l_queue_entry *e;
+
+ l_dbus_message_builder_enter_array(builder, "o");
+
+ for (e = l_queue_get_entries(network->bss_list); e; e = e->next) {
+ struct scan_bss *bss = e->data;
+ const char *path = network_bss_get_path(network, bss);
+
+ l_dbus_message_builder_append_basic(builder, 'o', path);
+ }
+
+ l_dbus_message_builder_leave_array(builder);
+
+ return true;
+}
+
bool network_register(struct network *network, const char *path)
{
if (!l_dbus_object_add_interface(dbus_get_bus(), path,
@@ -2259,6 +2287,9 @@ static void setup_network_interface(struct l_dbus_interface *interface)
l_dbus_interface_property(interface, "KnownNetwork", 0, "o",
network_property_get_known_network, NULL);
+
+ l_dbus_interface_property(interface, "ExtendedServiceSet", 0, "ao",
+ network_property_get_extended_service_set, NULL);
}
static bool network_bss_property_get_address(struct l_dbus *dbus,
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 05/13] network: remove network_bss_list_clear
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (2 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 04/13] network: add ExtendedServiceSet DBus property James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 06/13] station: add ConnectedAccessPoint property James Prestwood
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/network.c | 6 ------
src/network.h | 2 +-
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/network.c b/src/network.c
index 76238e56..85d2a983 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1286,12 +1286,6 @@ bool network_bss_list_isempty(struct network *network)
return l_queue_isempty(network->bss_list);
}
-void network_bss_list_clear(struct network *network)
-{
- l_queue_destroy(network->bss_list, NULL);
- network->bss_list = l_queue_new();
-}
-
struct scan_bss *network_bss_list_pop(struct network *network)
{
struct scan_bss *bss = l_queue_pop_head(network->bss_list);
diff --git a/src/network.h b/src/network.h
index b27158ee..78ced99d 100644
--- a/src/network.h
+++ b/src/network.h
@@ -76,7 +76,7 @@ bool network_bss_update(struct network *network, struct scan_bss *bss);
const char *network_bss_get_path(const struct network *network,
const struct scan_bss *bss);
bool network_bss_list_isempty(struct network *network);
-void network_bss_list_clear(struct network *network);
+
struct scan_bss *network_bss_list_pop(struct network *network);
struct scan_bss *network_bss_find_by_addr(struct network *network,
const uint8_t *addr);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 06/13] station: add ConnectedAccessPoint property
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (3 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 05/13] network: remove network_bss_list_clear James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 07/13] doc: document BasicServiceSet API James Prestwood
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This property is a path that corresponds to a BasicServiceSet
object, the one the station is currently connected to.
---
src/station.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/station.c b/src/station.c
index c45b849b..06b19db3 100644
--- a/src/station.c
+++ b/src/station.c
@@ -4386,6 +4386,23 @@ static bool station_property_get_connected_network(struct l_dbus *dbus,
return true;
}
+static bool station_property_get_connected_ap(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ struct l_dbus_message_builder *builder,
+ void *user_data)
+{
+ struct station *station = user_data;
+
+ if (!station->connected_network)
+ return false;
+
+ l_dbus_message_builder_append_basic(builder, 'o',
+ network_bss_get_path(station->connected_network,
+ station->connected_bss));
+
+ return true;
+}
+
static bool station_property_get_scanning(struct l_dbus *dbus,
struct l_dbus_message *message,
struct l_dbus_message_builder *builder,
@@ -4793,6 +4810,9 @@ static void station_setup_interface(struct l_dbus_interface *interface)
l_dbus_interface_property(interface, "ConnectedNetwork", 0, "o",
station_property_get_connected_network,
NULL);
+ l_dbus_interface_property(interface, "ConnectedAccessPoint", 0, "o",
+ station_property_get_connected_ap,
+ NULL);
l_dbus_interface_property(interface, "Scanning", 0, "b",
station_property_get_scanning, NULL);
l_dbus_interface_property(interface, "State", 0, "s",
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 07/13] doc: document BasicServiceSet API
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (4 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 06/13] station: add ConnectedAccessPoint property James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 08/13] client: separate property header and values into two functions James Prestwood
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
doc/basic-service-set.txt | 10 ++++++++++
doc/network-api.txt | 5 +++++
doc/station-api.txt | 6 ++++++
3 files changed, 21 insertions(+)
create mode 100644 doc/basic-service-set.txt
diff --git a/doc/basic-service-set.txt b/doc/basic-service-set.txt
new file mode 100644
index 00000000..f827ca02
--- /dev/null
+++ b/doc/basic-service-set.txt
@@ -0,0 +1,10 @@
+Basic service set hierarchy
+=================
+
+Service net.connman.iwd
+Interface net.connman.iwd.BasicServiceSet
+Object path /net/connman/iwd/{phy0,phy1,...}/{1,2,...}/Xxx
+
+Properties string Address [readonly]
+
+ MAC address of BSS
diff --git a/doc/network-api.txt b/doc/network-api.txt
index e4a34411..8bc6eea6 100644
--- a/doc/network-api.txt
+++ b/doc/network-api.txt
@@ -50,3 +50,8 @@ Properties string Name [readonly]
corresponding to this Network. If the network
is not provisioned or has not been connected to
before, the property is omitted.
+
+ array(object) ExtendedServiceSet [readonly]
+
+ Contains a list of paths of each individual
+ BasicServiceSet object.
diff --git a/doc/station-api.txt b/doc/station-api.txt
index 05dd137e..84f1b7bf 100644
--- a/doc/station-api.txt
+++ b/doc/station-api.txt
@@ -164,6 +164,12 @@ Properties string State [readonly]
for networks. net.connman.iwd.Network objects are
updated when this property goes from true to false.
+ object ConnectedAccessPoint [readonly, optional]
+
+ net.connman.iwd.BasicServiceSet object represeting the
+ BSS the device is currently connected to or to which
+ a connection is in progress.
+
SignalLevelAgent hierarchy
==========================
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 08/13] client: separate property header and values into two functions
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (5 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 07/13] doc: document BasicServiceSet API James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 09/13] client: add net.connman.iwd.BasicServiceSet definition James Prestwood
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
There are certain cases where we may not want to display the entire
header for a given set of properties. For example displaying a list
of proxy interfaces. Add finer control by separating out the header
and the prop/value display into two functions.
---
client/dbus-proxy.c | 38 +++++++++++++++++++++++++++++---------
client/dbus-proxy.h | 7 +++++++
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/client/dbus-proxy.c b/client/dbus-proxy.c
index 42b8427f..1e50d902 100644
--- a/client/dbus-proxy.c
+++ b/client/dbus-proxy.c
@@ -47,10 +47,10 @@ static struct l_dbus *dbus;
static struct l_queue *proxy_interfaces;
static struct l_queue *proxy_interface_types;
-void proxy_properties_display(const struct proxy_interface *proxy,
- const char *caption, const char *margin,
- unsigned int name_column_width,
- unsigned int value_column_width)
+void proxy_properties_display_inline(const struct proxy_interface *proxy,
+ const char *margin,
+ unsigned int name_column_width,
+ unsigned int value_column_width)
{
const void *data;
const struct proxy_interface_property *properties;
@@ -59,11 +59,6 @@ void proxy_properties_display(const struct proxy_interface *proxy,
if (!proxy->type->properties)
return;
- display_table_header(caption, "%s%-*s %-*s %-*s", margin,
- 8, "Settable",
- name_column_width, "Property",
- value_column_width, "Value");
-
data = proxy_interface_get_data(proxy);
properties = proxy->type->properties;
@@ -82,6 +77,31 @@ void proxy_properties_display(const struct proxy_interface *proxy,
}
}
+void proxy_properties_display_header(const char *caption, const char *margin,
+ unsigned int name_column_width,
+ unsigned int value_column_width)
+{
+ display_table_header(caption, "%s%-*s %-*s %-*s", margin,
+ 8, "Settable",
+ name_column_width, "Property",
+ value_column_width, "Value");
+}
+
+void proxy_properties_display(const struct proxy_interface *proxy,
+ const char *caption, const char *margin,
+ unsigned int name_column_width,
+ unsigned int value_column_width)
+{
+ if (!proxy->type->properties)
+ return;
+
+ proxy_properties_display_header(caption, margin, name_column_width,
+ value_column_width);
+
+ proxy_properties_display_inline(proxy, margin, name_column_width,
+ value_column_width);
+}
+
static const void *proxy_interface_property_tostr(
const struct proxy_interface *proxy,
const char *name)
diff --git a/client/dbus-proxy.h b/client/dbus-proxy.h
index 98b0a2a4..f0a5d38a 100644
--- a/client/dbus-proxy.h
+++ b/client/dbus-proxy.h
@@ -95,6 +95,13 @@ void proxy_properties_display(const struct proxy_interface *proxy,
const char *caption, const char *margin,
unsigned int name_column_width,
unsigned int value_column_width);
+void proxy_properties_display_inline(const struct proxy_interface *proxy,
+ const char *margin,
+ unsigned int name_column_width,
+ unsigned int value_column_width);
+void proxy_properties_display_header(const char *caption, const char *margin,
+ unsigned int name_column_width,
+ unsigned int value_column_width);
char *proxy_property_str_completion(const struct proxy_interface_type *type,
proxy_property_match_func_t function,
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 09/13] client: add net.connman.iwd.BasicServiceSet definition
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (6 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 08/13] client: separate property header and values into two functions James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 10/13] client: Add BasicServiceSets property to network James Prestwood
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
client/dbus-proxy.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/client/dbus-proxy.h b/client/dbus-proxy.h
index f0a5d38a..32300f41 100644
--- a/client/dbus-proxy.h
+++ b/client/dbus-proxy.h
@@ -41,6 +41,7 @@ struct proxy_interface;
#define IWD_DPP_INTERFACE "net.connman.iwd.DeviceProvisioning"
#define IWD_DPP_PKEX_INTERFACE \
"net.connman.iwd.SharedCodeDeviceProvisioning"
+#define IWD_BSS_INTERFACE "net.connman.iwd.BasicServiceSet"
typedef bool (*proxy_property_match_func_t) (const void *a, const void *b);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 10/13] client: Add BasicServiceSets property to network
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (7 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 09/13] client: add net.connman.iwd.BasicServiceSet definition James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 11/13] client: add BasicServiceSet interface James Prestwood
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
The property itself is an array of paths, but this is difficult
to fit nicely within a terminal. Instead just display the count
of BSS's. Displaying a detailed list of BSS's will be done via
a separate command.
---
client/network.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
client/network.h | 2 ++
2 files changed, 51 insertions(+)
diff --git a/client/network.c b/client/network.c
index 6b79bcd1..7431183b 100644
--- a/client/network.c
+++ b/client/network.c
@@ -35,6 +35,7 @@ struct network {
char *identity;
char *name;
char *type;
+ struct l_queue *bss_list;
const struct proxy_interface *device;
};
@@ -146,11 +147,58 @@ static void update_type(void *data, struct l_dbus_message_iter *variant)
network->type = l_strdup(value);
}
+static bool match_path(const void *a, const void *user_data)
+{
+ const char *path1 = a;
+ const char *path2 = user_data;
+
+ return !strcmp(path1, path2);
+}
+
+static void update_ess(void *data, struct l_dbus_message_iter *variant)
+{
+ struct network *network = data;
+ struct l_dbus_message_iter array;
+ const char *path;
+
+ if (!network->bss_list)
+ network->bss_list = l_queue_new();
+
+ if (!l_dbus_message_iter_get_variant(variant, "ao", &array))
+ return;
+
+ while (l_dbus_message_iter_next_entry(&array, &path)) {
+ l_free(l_queue_remove_if(network->bss_list, match_path, path));
+ l_queue_push_head(network->bss_list, l_strdup(path));
+ }
+}
+
+static const char *get_ess(const void *data)
+{
+ const struct network *network = data;
+ static char count[10];
+
+ snprintf(count, 10, "Count %u", l_queue_length(network->bss_list));
+
+ return count;
+}
+
+struct l_queue *network_get_bss_list(
+ const struct proxy_interface *network_proxy)
+{
+ const struct network *network = proxy_interface_get_data(network_proxy);
+ if (!network)
+ return NULL;
+
+ return network->bss_list;
+}
+
static const struct proxy_interface_property network_properties[] = {
{ "Name", "s", update_name, get_name },
{ "Connected", "b", update_connected},
{ "Device", "o", update_device},
{ "Type", "s", update_type},
+ { "ExtendedServiceSet", "ao", update_ess, get_ess },
{ }
};
@@ -186,6 +234,7 @@ static void network_destroy(void *data)
l_free(network->name);
l_free(network->type);
l_free(network->identity);
+ l_queue_destroy(network->bss_list, l_free);
network->device = NULL;
diff --git a/client/network.h b/client/network.h
index 41624749..56d74e3f 100644
--- a/client/network.h
+++ b/client/network.h
@@ -37,3 +37,5 @@ char *network_name_completion(const struct proxy_interface *device,
struct l_queue *network_match_by_device_and_args(
const struct proxy_interface *device,
const struct network_args *args);
+struct l_queue *network_get_bss_list(
+ const struct proxy_interface *network_proxy);
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 11/13] client: add BasicServiceSet interface
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (8 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 10/13] client: Add BasicServiceSets property to network James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 12/13] client: refactor cmd_connect() and add find_network() James Prestwood
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
Makefile.am | 1 +
client/bss.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
create mode 100644 client/bss.c
diff --git a/Makefile.am b/Makefile.am
index 0c152216..d438a5ba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -319,6 +319,7 @@ client_iwctl_SOURCES = client/main.c \
client/daemon.c client/daemon.h \
client/dpp.c client/dpp-pkex.c \
client/station-debug.c \
+ client/bss.c \
src/util.c src/util.h \
src/band.c src/band.h
diff --git a/client/bss.c b/client/bss.c
new file mode 100644
index 00000000..def4de7f
--- /dev/null
+++ b/client/bss.c
@@ -0,0 +1,109 @@
+/*
+ *
+ * Wireless daemon for Linux
+ *
+ * Copyright (C) 2024, Locus Robotics
+ *
+ * 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 "ell/useful.h"
+
+#include "client/dbus-proxy.h"
+#include "client/display.h"
+
+struct bss {
+ char *address;
+};
+
+static const char *get_address(const void *data)
+{
+ const struct bss *bss = data;
+
+ return bss->address;
+}
+
+static void update_address(void *data, struct l_dbus_message_iter *variant)
+{
+ struct bss *bss = data;
+ const char *value;
+
+ l_free(bss->address);
+
+ if (!l_dbus_message_iter_get_variant(variant, "s", &value)) {
+ bss->address = NULL;
+
+ return;
+ }
+
+ bss->address = l_strdup(value);
+}
+
+static const struct proxy_interface_property bss_properties[] = {
+ { "Address", "s", update_address, get_address },
+ { }
+};
+
+static void *bss_create(void)
+{
+ return l_new(struct bss, 1);
+}
+
+static void bss_destroy(void *data)
+{
+ struct bss *bss = data;
+
+ l_free(bss->address);
+ l_free(bss);
+}
+
+static void bss_display_inline(const char *margin, const void *data)
+{
+ const struct bss *bss = data;
+
+ display("%s%s\n", margin, bss->address);
+}
+
+static const struct proxy_interface_type_ops ops = {
+ .create = bss_create,
+ .destroy = bss_destroy,
+ .display = bss_display_inline,
+};
+
+static struct proxy_interface_type bss_interface_type = {
+ .interface = IWD_BSS_INTERFACE,
+ .properties = bss_properties,
+ .ops = &ops,
+};
+
+static int bss_interface_init(void)
+{
+ proxy_interface_type_register(&bss_interface_type);
+
+ return 0;
+}
+
+static void bss_interface_exit(void)
+{
+ proxy_interface_type_unregister(&bss_interface_type);
+}
+
+INTERFACE_TYPE(bss_interface_type, bss_interface_init, bss_interface_exit)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 12/13] client: refactor cmd_connect() and add find_network()
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (9 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 11/13] client: add BasicServiceSet interface James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 15:46 ` [PATCH v3 13/13] client: add station command "get-bsses" James Prestwood
2024-08-12 17:11 ` [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface Denis Kenzior
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This will do all the lookup/searching needed to find a network
proxy object.
---
client/station.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/client/station.c b/client/station.c
index affb7f15..58aac29e 100644
--- a/client/station.c
+++ b/client/station.c
@@ -283,28 +283,26 @@ static char *connect_cmd_arg_completion(const char *text, int state,
return network_name_completion(device, text, state);
}
-static enum cmd_status cmd_connect(const char *device_name,
- char **argv, int argc)
+static const struct proxy_interface *find_network(const char *device_name,
+ const char *name,
+ const char *type)
{
struct network_args network_args;
struct l_queue *match;
const struct proxy_interface *network_proxy;
const struct proxy_interface *device_proxy;
- if (argc < 1)
- return CMD_STATUS_INVALID_ARGS;
-
device_proxy = device_proxy_find_by_name(device_name);
if (!device_proxy)
- return CMD_STATUS_INVALID_VALUE;
+ return NULL;
- network_args.name = argv[0];
- network_args.type = argc >= 2 ? argv[1] : NULL;
+ network_args.name = name;
+ network_args.type = type;
match = network_match_by_device_and_args(device_proxy, &network_args);
if (!match) {
display("Invalid network name '%s'\n", network_args.name);
- return CMD_STATUS_INVALID_VALUE;
+ return NULL;
}
if (l_queue_length(match) > 1) {
@@ -315,11 +313,28 @@ static enum cmd_status cmd_connect(const char *device_name,
l_queue_destroy(match, NULL);
- return CMD_STATUS_INVALID_VALUE;
+ return NULL;
}
network_proxy = l_queue_pop_head(match);
l_queue_destroy(match, NULL);
+
+ return network_proxy;
+}
+
+static enum cmd_status cmd_connect(const char *device_name,
+ char **argv, int argc)
+{
+ const struct proxy_interface *network_proxy;
+
+ if (argc < 1)
+ return CMD_STATUS_INVALID_ARGS;
+
+ network_proxy = find_network(device_name, argv[0],
+ argc >= 2 ? argv[1] : NULL);
+ if (!network_proxy)
+ return CMD_STATUS_INVALID_VALUE;
+
network_connect(network_proxy);
return CMD_STATUS_TRIGGERED;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v3 13/13] client: add station command "get-bsses"
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (10 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 12/13] client: refactor cmd_connect() and add find_network() James Prestwood
@ 2024-08-12 15:46 ` James Prestwood
2024-08-12 17:11 ` [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface Denis Kenzior
12 siblings, 0 replies; 14+ messages in thread
From: James Prestwood @ 2024-08-12 15:46 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This command will get the BasicServiceSet list for a given network.
If no network is supplied, its assumed to be the current network.
---
client/station.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/client/station.c b/client/station.c
index 58aac29e..5066a9f1 100644
--- a/client/station.c
+++ b/client/station.c
@@ -723,6 +723,55 @@ static enum cmd_status cmd_show(const char *device_name,
return CMD_STATUS_TRIGGERED;
}
+
+static enum cmd_status cmd_get_bsses(const char *device_name,
+ char **argv, int argc)
+{
+ const struct proxy_interface *station_i =
+ device_proxy_find(device_name, IWD_STATION_INTERFACE);
+ const struct station *station = proxy_interface_get_data(station_i);
+ struct l_queue *bss_list;
+ const struct l_queue_entry *e;
+ const struct proxy_interface *network_proxy;
+ char header[256];
+
+ if (argc > 0)
+ network_proxy = find_network(device_name, argv[0],
+ argc >= 2 ? argv[1] : NULL);
+ else
+ network_proxy = station->connected_network;
+
+ if (!network_proxy) {
+ display_error("Can't find network");
+ return CMD_STATUS_INVALID_ARGS;
+ }
+
+ bss_list = network_get_bss_list(network_proxy);
+ if (!bss_list) {
+ display_error("No BSS list for network");
+ return CMD_STATUS_FAILED;
+ }
+
+ sprintf(header, "%s BasicServiceSets", network_get_name(network_proxy));
+
+ proxy_properties_display_header(header, MARGIN, 10, 18);
+
+ for (e = l_queue_get_entries(bss_list); e; e = e->next) {
+ const char *path = e->data;
+ const struct proxy_interface *bss_i = proxy_interface_find(
+ IWD_BSS_INTERFACE, path);
+
+ if (!bss_i)
+ continue;
+
+ display_table_row(MARGIN, 1, strlen(path), path);
+ proxy_properties_display_inline(bss_i, MARGIN, 10, 18);
+ display_table_row(MARGIN, 1, 1, "");
+ }
+
+ return CMD_STATUS_DONE;
+}
+
static const struct command station_commands[] = {
{ NULL, "list", NULL, cmd_list, "List devices in Station mode", true },
{ "<wlan>", "connect",
@@ -747,6 +796,8 @@ static const struct command station_commands[] = {
"Get hidden APs", true },
{ "<wlan>", "scan", NULL, cmd_scan, "Scan for networks" },
{ "<wlan>", "show", NULL, cmd_show, "Show station info", true },
+ { "<wlan>", "get-bsses", "[network] [security]", cmd_get_bsses,
+ "Get BSS's for a network", true },
{ }
};
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
` (11 preceding siblings ...)
2024-08-12 15:46 ` [PATCH v3 13/13] client: add station command "get-bsses" James Prestwood
@ 2024-08-12 17:11 ` Denis Kenzior
12 siblings, 0 replies; 14+ messages in thread
From: Denis Kenzior @ 2024-08-12 17:11 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 8/12/24 10:46 AM, James Prestwood wrote:
> ---
> src/dbus.h | 1 +
> 1 file changed, 1 insertion(+)
>
All applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2024-08-12 17:11 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-12 15:46 [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 02/13] network: Add BasicServiceSet object James Prestwood
2024-08-12 15:46 ` [PATCH v3 03/13] station: use network_bss_{start,stop}_update James Prestwood
2024-08-12 15:46 ` [PATCH v3 04/13] network: add ExtendedServiceSet DBus property James Prestwood
2024-08-12 15:46 ` [PATCH v3 05/13] network: remove network_bss_list_clear James Prestwood
2024-08-12 15:46 ` [PATCH v3 06/13] station: add ConnectedAccessPoint property James Prestwood
2024-08-12 15:46 ` [PATCH v3 07/13] doc: document BasicServiceSet API James Prestwood
2024-08-12 15:46 ` [PATCH v3 08/13] client: separate property header and values into two functions James Prestwood
2024-08-12 15:46 ` [PATCH v3 09/13] client: add net.connman.iwd.BasicServiceSet definition James Prestwood
2024-08-12 15:46 ` [PATCH v3 10/13] client: Add BasicServiceSets property to network James Prestwood
2024-08-12 15:46 ` [PATCH v3 11/13] client: add BasicServiceSet interface James Prestwood
2024-08-12 15:46 ` [PATCH v3 12/13] client: refactor cmd_connect() and add find_network() James Prestwood
2024-08-12 15:46 ` [PATCH v3 13/13] client: add station command "get-bsses" James Prestwood
2024-08-12 17:11 ` [PATCH v3 01/13] dbus: Add net.connman.iwd.BasicServiceSet interface Denis Kenzior
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox