diff --git a/src/network.c b/src/network.c index 9f26368e..fb447212 100644 --- a/src/network.c +++ b/src/network.c @@ -47,6 +47,7 @@ struct network_info { char ssid[33]; uint32_t type; struct timespec connected_time; /* Time last connected */ + struct timespec seen_time; /* Time last seen */ }; struct network { @@ -101,7 +102,7 @@ static bool network_info_match(const void *a, const void *b) return true; } -bool network_seen(struct network *network) +bool network_seen(struct network *network, struct timespec *when) { struct timespec mtim; int err; @@ -115,7 +116,7 @@ bool network_seen(struct network *network) info = l_queue_find(networks, network_info_match, &search); if (info) - return true; + goto update; strtype = security_to_str(network->security); if (!strtype) @@ -133,6 +134,15 @@ bool network_seen(struct network *network) l_queue_insert(networks, info, timespec_compare, NULL); +update: + /* + * Update the last seen time. Note this is not preserved across + * the network going out of range and back, or program restarts. + * It may be desirable for it to be preserved in some way but + * without too frequent filesystem writes. + */ + memcpy(&info->seen_time, when, sizeof(struct timespec)); + return true; } diff --git a/src/network.h b/src/network.h index c65c224f..20c34a5c 100644 --- a/src/network.h +++ b/src/network.h @@ -25,7 +25,7 @@ struct device; struct network; -bool network_seen(struct network *network); +bool network_seen(struct network *network, struct timespec *when); bool network_connected(struct network *network); void network_disconnected(struct network *network); bool network_rankmod(const struct network *network, double *rankmod); diff --git a/src/wiphy.c b/src/wiphy.c index 1fbccae9..baf9ef37 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -1234,7 +1235,8 @@ static int autoconnect_rank_compare(const void *a, const void *b, void *user) return ae->rank - new_ae->rank; } -static void process_bss(struct device *device, struct scan_bss *bss) +static void process_bss(struct device *device, struct scan_bss *bss, + struct timespec *timestamp) { struct network *network; enum security security; @@ -1306,10 +1308,11 @@ static void process_bss(struct device *device, struct scan_bss *bss) network_get_path(network), network); l_debug("Added new Network \"%s\" security %s", network_get_ssid(network), security_to_str(security)); - - network_seen(network); } + if (network_bss_list_isempty(network)) + network_seen(network, timestamp); + network_bss_add(network, bss); /* See if network is autoconnectable (is a known network) */ @@ -1330,6 +1333,9 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, struct device *device = userdata; struct network *network; const struct l_queue_entry *bss_entry; + struct timespec now; + + clock_gettime(CLOCK_REALTIME, &now); device->old_bss_list = device->bss_list; device->bss_list = bss_list; @@ -1344,7 +1350,7 @@ static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, bss_entry = bss_entry->next) { struct scan_bss *bss = bss_entry->data; - process_bss(device, bss); + process_bss(device, bss, &now); } l_hashmap_foreach_remove(device->networks, process_network, device);