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
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to