User is able to change autoconnect value for a provisioned service.
This user modification must be preserved across ConnMan restarts.
This is done by loading the necessary minimal service settings
when provisioning a service via .config file. We also do not load
the service settings if we could provision the service so that
the options in .config file are not overwritten.
---
src/config.c | 59 ++++++++++++++++++++++++++++++++++++-----------------------
src/service.c | 10 +++++++---
2 files changed, 43 insertions(+), 26 deletions(-)
diff --git a/src/config.c b/src/config.c
index d7f98f0..a74409d 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1055,11 +1055,10 @@ static gboolean remove_virtual_config(gpointer
user_data)
return FALSE;
}
-static void provision_service(gpointer key, gpointer value,
- gpointer user_data)
+static int try_provision_service(gpointer key,
+ struct connman_config_service *config,
+ struct connman_service *service)
{
- struct connman_service *service = user_data;
- struct connman_config_service *config = value;
struct connman_network *network;
const void *service_id;
enum connman_service_type type;
@@ -1069,15 +1068,15 @@ static void provision_service(gpointer key, gpointer
value,
type = connman_service_get_type(service);
if (type == CONNMAN_SERVICE_TYPE_WIFI &&
g_strcmp0(config->type, "wifi") != 0)
- return;
+ return -ENOENT;
if (type == CONNMAN_SERVICE_TYPE_ETHERNET &&
g_strcmp0(config->type, "ethernet") != 0)
- return;
+ return -ENOENT;
if (type == CONNMAN_SERVICE_TYPE_GADGET &&
g_strcmp0(config->type, "gadget") != 0)
- return;
+ return -ENOENT;
DBG("service %p ident %s", service,
__connman_service_get_ident(service));
@@ -1085,7 +1084,7 @@ static void provision_service(gpointer key, gpointer
value,
network = __connman_service_get_network(service);
if (!network) {
connman_error("Service has no network set");
- return;
+ return -EINVAL;
}
DBG("network %p ident %s", network,
@@ -1098,7 +1097,7 @@ static void provision_service(gpointer key, gpointer
value,
device = connman_network_get_device(network);
if (!device) {
connman_error("Network device is missing");
- return;
+ return -ENODEV;
}
device_addr = connman_device_get_string(device, "Address");
@@ -1106,7 +1105,7 @@ static void provision_service(gpointer key, gpointer
value,
DBG("wants %s has %s", config->mac, device_addr);
if (g_ascii_strcasecmp(device_addr, config->mac) != 0)
- return;
+ return -ENOENT;
}
if (g_strcmp0(config->type, "wifi") == 0 &&
@@ -1115,14 +1114,14 @@ static void provision_service(gpointer key, gpointer
value,
&ssid_len);
if (!ssid) {
connman_error("Network SSID not set");
- return;
+ return -EINVAL;
}
if (!config->ssid || ssid_len != config->ssid_len)
- return;
+ return -ENOENT;
if (memcmp(config->ssid, ssid, ssid_len) != 0)
- return;
+ return -ENOENT;
}
if (!config->ipv6_address) {
@@ -1140,12 +1139,12 @@ static void provision_service(gpointer key, gpointer
value,
if (config->ipv6_prefix_length == 0) {
DBG("IPv6 prefix missing");
- return;
+ return -EINVAL;
}
address = connman_ipaddress_alloc(AF_INET6);
if (!address)
- return;
+ return -ENOENT;
connman_ipaddress_set_ipv6(address, config->ipv6_address,
config->ipv6_prefix_length,
@@ -1185,12 +1184,12 @@ static void provision_service(gpointer key, gpointer
value,
if (!config->ipv4_netmask) {
DBG("IPv4 netmask missing");
- return;
+ return -EINVAL;
}
address = connman_ipaddress_alloc(AF_INET);
if (!address)
- return;
+ return -ENOENT;
connman_ipaddress_set_ipv4(address, config->ipv4_address,
config->ipv4_netmask,
@@ -1253,7 +1252,7 @@ static void provision_service(gpointer key, gpointer
value,
__connman_service_mark_dirty();
- __connman_service_save(service);
+ __connman_service_load_minimal(service);
if (config->virtual) {
struct connect_virtual *virtual;
@@ -1265,13 +1264,21 @@ static void provision_service(gpointer key, gpointer
value,
g_timeout_add(0, remove_virtual_config, virtual);
} else
__connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+
+ return 0;
+}
+
+static void provision_service(gpointer key, gpointer value, gpointer user_data)
+{
+ try_provision_service(key, value, user_data);
}
int __connman_config_provision_service(struct connman_service *service)
{
enum connman_service_type type;
- GHashTableIter iter;
- gpointer value, key;
+ GHashTableIter iter, iter_service;
+ gpointer value, key, value_service, key_service;
+ int ret = -ENOENT;
/* For now only WiFi, Gadget and Ethernet services are supported */
type = connman_service_get_type(service);
@@ -1288,11 +1295,17 @@ int __connman_config_provision_service(struct
connman_service *service)
while (g_hash_table_iter_next(&iter, &key, &value)) {
struct connman_config *config = value;
- g_hash_table_foreach(config->service_table,
- provision_service, service);
+ g_hash_table_iter_init(&iter_service, config->service_table);
+ while (g_hash_table_iter_next(&iter_service, &key_service,
+ &value_service)) {
+ if (!(ret = try_provision_service(key_service,
+ value_service, service)))
+ goto out;
+ }
}
- return 0;
+out:
+ return ret;
}
int __connman_config_provision_service_ident(struct connman_service *service,
diff --git a/src/service.c b/src/service.c
index 48b0609..c871234 100644
--- a/src/service.c
+++ b/src/service.c
@@ -6241,9 +6241,13 @@ static int service_register(struct connman_service
*service)
DBG("path %s", service->path);
- __connman_config_provision_service(service);
-
- service_load(service);
+ /*
+ * We only load the service data if we could not provision
+ * the service. This way the provisioned service is not overwritten
+ * when loading the service from the settings file.
+ */
+ if (__connman_config_provision_service(service) < 0)
+ service_load(service);
g_dbus_register_interface(connection, service->path,
CONNMAN_SERVICE_INTERFACE,
--
1.8.3.1
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman