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 | 78 ++++++++++++++++++++++++++++++++---------------------------
src/service.c | 5 ++--
2 files changed, 45 insertions(+), 38 deletions(-)
diff --git a/src/config.c b/src/config.c
index d7f98f0..330ae81 100644
--- a/src/config.c
+++ b/src/config.c
@@ -977,8 +977,7 @@ static char *config_pem_fsid(const char *pem_file)
return g_strdup_printf("%llx", fsid64);
}
-static void provision_service_wifi(gpointer key,
- struct connman_config_service *config,
+static void provision_service_wifi(struct connman_config_service *config,
struct connman_service *service,
struct connman_network *network,
const void *ssid, unsigned int ssid_len)
@@ -1055,11 +1054,9 @@ 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(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 +1066,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 +1082,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 +1095,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 +1103,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 +1112,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 +1137,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 +1182,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,
@@ -1245,7 +1242,7 @@ static void provision_service(gpointer key, gpointer
value,
if (g_strcmp0(config->type, "wifi") == 0 &&
type == CONNMAN_SERVICE_TYPE_WIFI) {
- provision_service_wifi(key, config, service, network,
+ provision_service_wifi(config, service, network,
ssid, ssid_len);
} else
__connman_service_connect(service,
@@ -1253,7 +1250,7 @@ static void provision_service(gpointer key, gpointer
value,
__connman_service_mark_dirty();
- __connman_service_save(service);
+ __connman_service_load_modifiable(service);
if (config->virtual) {
struct connect_virtual *virtual;
@@ -1265,13 +1262,34 @@ 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 int find_and_provision_service(struct connman_service *service)
+{
+ GHashTableIter iter, iter_service;
+ gpointer value, key, value_service, key_service;
+
+ g_hash_table_iter_init(&iter, config_table);
+
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ struct connman_config *config = value;
+
+ g_hash_table_iter_init(&iter_service, config->service_table);
+ while (g_hash_table_iter_next(&iter_service, &key_service,
+ &value_service)) {
+ if (!try_provision_service(value_service, service))
+ return 0;
+ }
+ }
+
+ return -ENOENT;
}
int __connman_config_provision_service(struct connman_service *service)
{
enum connman_service_type type;
- GHashTableIter iter;
- gpointer value, key;
/* For now only WiFi, Gadget and Ethernet services are supported */
type = connman_service_get_type(service);
@@ -1283,16 +1301,7 @@ int __connman_config_provision_service(struct
connman_service *service)
type != CONNMAN_SERVICE_TYPE_GADGET)
return -ENOSYS;
- g_hash_table_iter_init(&iter, config_table);
-
- while (g_hash_table_iter_next(&iter, &key, &value)) {
- struct connman_config *config = value;
-
- g_hash_table_foreach(config->service_table,
- provision_service, service);
- }
-
- return 0;
+ return find_and_provision_service(service);
}
int __connman_config_provision_service_ident(struct connman_service *service,
@@ -1356,8 +1365,7 @@ int __connman_config_provision_service_ident(struct
connman_service *service,
}
}
- g_hash_table_foreach(config->service_table,
- provision_service, service);
+ find_and_provision_service(service);
}
return ret;
diff --git a/src/service.c b/src/service.c
index 1a65efd..0905063 100644
--- a/src/service.c
+++ b/src/service.c
@@ -6241,9 +6241,8 @@ static int service_register(struct connman_service
*service)
DBG("path %s", service->path);
- __connman_config_provision_service(service);
-
- service_load(service);
+ 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