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.
This commit is contained in:
James Prestwood 2019-08-15 13:15:13 -07:00 committed by Denis Kenzior
parent 5caf8796cd
commit 28f484ddb8
3 changed files with 81 additions and 27 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}