From 28f484ddb87eb9fab15885e0a1541e517ffc31ea Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Thu, 15 Aug 2019 13:15:13 -0700 Subject: [PATCH] network: knownnetworks: introduce network_info_ops The known network APIs all revolved around the ssid/security matching to do any operations on the provisioning file. In the near future hotspot provisioning files (managed by hotspot.c) will be incorporated into the known network list. Since these hotspot files do not use the ssid as the file name hotspot.c will need other ways of matching. This patch adds network_info_ops to the network object. This ops structure will hold function pointers which operate on network_info rather than ssid/security. This will allow hotspot and known networks to both register their own operation routines. For now open, touch, sync, remove, free, and get_path were added. Wrappers were added for accessing these operations outside of knownnetworks.c. --- src/knownnetworks.c | 61 +++++++++++++++++++++++++++++++++++++++++---- src/knownnetworks.h | 17 +++++++++++-- src/network.c | 30 ++++++++-------------- 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/src/knownnetworks.c b/src/knownnetworks.c index 655cb806..407c77f5 100644 --- a/src/knownnetworks.c +++ b/src/knownnetworks.c @@ -54,7 +54,7 @@ static void network_info_free(void *data) l_queue_destroy(network->known_frequencies, l_free); - l_free(network); + network->ops->free(network); } static int connected_time_compare(const void *a, const void *b, void *user_data) @@ -66,7 +66,7 @@ static int connected_time_compare(const void *a, const void *b, void *user_data) &ni_b->connected_time); } -const char *known_network_get_path(const struct network_info *network) +static const char *known_network_get_path(const struct network_info *network) { static char path[256]; unsigned int pos = 0, i; @@ -137,6 +137,56 @@ static void known_network_set_autoconnect(struct network_info *network, IWD_KNOWN_NETWORK_INTERFACE, "Autoconnect"); } +static int known_network_touch(struct network_info *info) +{ + return storage_network_touch(info->type, info->ssid); +} + +static struct l_settings *known_network_open(struct network_info *info) +{ + return storage_network_open(info->type, info->ssid); +} + +static void known_network_sync(struct network_info *info, + struct l_settings *settings) +{ + storage_network_sync(info->type, info->ssid, settings); +} + +static void known_network_remove(struct network_info *info) +{ + storage_network_remove(info->type, info->ssid); +} + +static void known_network_free(struct network_info *info) +{ + l_free(info); +} + +static struct network_info_ops known_network_ops = { + .open = known_network_open, + .touch = known_network_touch, + .sync = known_network_sync, + .remove = known_network_remove, + .free = known_network_free, + .get_path = known_network_get_path, +}; + +struct l_settings *network_info_open_settings(struct network_info *info) +{ + return info->ops->open(info); +} + +int network_info_touch(struct network_info *info) +{ + return info->ops->touch(info); +} + +const char *network_info_get_path(const struct network_info *info) +{ + return info->ops->get_path(info); +} + static void known_network_update(struct network_info *orig_network, const char *ssid, enum security security, @@ -153,6 +203,7 @@ static void known_network_update(struct network_info *orig_network, network = l_new(struct network_info, 1); strcpy(network->ssid, ssid); network->type = security; + network->ops = &known_network_ops; } if (util_timespec_compare(&network->connected_time, connected_time) && @@ -323,7 +374,7 @@ static struct l_dbus_message *known_network_forget(struct l_dbus *dbus, struct l_dbus_message *reply; /* Other actions taken care of by the filesystem watch callback */ - storage_network_remove(network->type, network->ssid); + network->ops->remove(network); reply = l_dbus_message_new_method_return(message); l_dbus_message_set_arguments(reply, ""); @@ -399,13 +450,13 @@ static struct l_dbus_message *known_network_property_set_autoconnect( if (network->is_autoconnectable == autoconnect) return l_dbus_message_new_method_return(message); - settings = storage_network_open(network->type, network->ssid); + settings = network->ops->open(network); if (!settings) return dbus_error_failed(message); l_settings_set_bool(settings, "Settings", "Autoconnect", autoconnect); - storage_network_sync(network->type, network->ssid, settings); + network->ops->sync(network, settings); l_settings_free(settings); return l_dbus_message_new_method_return(message); diff --git a/src/knownnetworks.h b/src/knownnetworks.h index 45153a53..df54f99b 100644 --- a/src/knownnetworks.h +++ b/src/knownnetworks.h @@ -22,13 +22,24 @@ enum security; struct scan_freq_set; +struct network_info; enum known_networks_event { KNOWN_NETWORKS_EVENT_ADDED, KNOWN_NETWORKS_EVENT_REMOVED, }; +struct network_info_ops { + struct l_settings *(*open)(struct network_info *info); + int (*touch)(struct network_info *info); + void (*sync)(struct network_info *info, struct l_settings *settings); + void (*remove)(struct network_info *info); + void (*free)(struct network_info *info); + const char *(*get_path)(const struct network_info *info); +}; + struct network_info { + const struct network_info_ops *ops; char ssid[33]; enum security type; struct l_queue *known_frequencies; @@ -57,8 +68,6 @@ bool known_networks_has_hidden(void); struct network_info *known_networks_find(const char *ssid, enum security security); -const char *known_network_get_path(const struct network_info *network); - struct scan_freq_set *known_networks_get_recent_frequencies( uint8_t num_networks_tosearch); int known_network_add_frequency(struct network_info *info, uint32_t frequency); @@ -67,3 +76,7 @@ uint32_t known_networks_watch_add(known_networks_watch_func_t func, void *user_data, known_networks_destroy_func_t destroy); void known_networks_watch_remove(uint32_t id); + +struct l_settings *network_info_open_settings(struct network_info *info); +int network_info_touch(struct network_info *info); +const char *network_info_get_path(const struct network_info *info); diff --git a/src/network.c b/src/network.c index 6a3742d2..8b060512 100644 --- a/src/network.c +++ b/src/network.c @@ -94,10 +94,8 @@ static bool network_settings_load(struct network *network) l_settings_free(network->settings); network->settings = NULL; } - } else - network->settings = storage_network_open( - network_get_security(network), - network_get_ssid(network)); + } else if (network->info) + network->settings = network_info_open_settings(network->info); return network->settings != NULL; } @@ -147,18 +145,11 @@ static bool network_secret_check_cacheable(void *data, void *user_data) void network_connected(struct network *network) { + enum security security = network_get_security(network); const char *ssid = network_get_ssid(network); int err; - /* - * This triggers an update to network->info->connected_time and - * other possible actions in knownnetworks.c. - */ - err = storage_network_touch(network_get_security(network), ssid); - switch (err) { - case 0: - break; - case -ENOENT: + if (!network->info) { /* * This is an open network seen for the first time: * @@ -169,12 +160,11 @@ void network_connected(struct network *network) if (!network->settings) network->settings = l_settings_new(); - storage_network_sync(network_get_security(network), ssid, - network->settings); - break; - default: - l_error("Error %i touching network config", err); - break; + storage_network_sync(security, ssid, network->settings); + } else { + err = network_info_touch(network->info); + if (err < 0) + l_error("Error %i touching network config", err); } l_queue_foreach_remove(network->secrets, @@ -1221,7 +1211,7 @@ static bool network_property_get_known_network(struct l_dbus *dbus, return false; l_dbus_message_builder_append_basic(builder, 'o', - known_network_get_path(network->info)); + network_info_get_path(network->info)); return true; }