The point here is to create a virtual configuration, which does not come
from a real file. This is a handy way for plugins to be able to provision
services without creating any file on the FS.

In case of a wifi configuration type and if connect is requested, it will
trigger a scan, thus leading to a possible service being provisioned by
such virtual configuration. If so and if connect was requested: the service
will be asked to connect.
---
 include/provision.h |  2 ++
 src/config.c        | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/include/provision.h b/include/provision.h
index d6d7c72..3e5f294 100644
--- a/include/provision.h
+++ b/include/provision.h
@@ -42,6 +42,8 @@ struct connman_config_entry {
        connman_bool_t hidden;
 };
 
+int connman_config_provision_mutable_service(GKeyFile *keyfile,
+                                               connman_bool_t connect);
 struct connman_config_entry **connman_config_get_entries(const char *type);
 void connman_config_free_entries(struct connman_config_entry **entries);
 
diff --git a/src/config.c b/src/config.c
index 098ef61..daeada2 100644
--- a/src/config.c
+++ b/src/config.c
@@ -56,6 +56,8 @@ struct connman_config_service {
        char *config_ident; /* file prefix */
        char *config_entry; /* entry name */
        connman_bool_t hidden;
+       connman_bool_t virtual;
+       connman_bool_t connect;
        char *ipv4_address;
        char *ipv4_netmask;
        char *ipv4_gateway;
@@ -173,6 +175,9 @@ static void unregister_service(gpointer data)
        protected_services = g_slist_remove(protected_services,
                                                config_service);
 
+       if (config_service->virtual == TRUE)
+               goto free_only;
+
        for (list = config_service->service_identifiers; list != NULL;
                                                        list = list->next) {
                service_id = list->data;
@@ -1157,7 +1162,8 @@ static void provision_service(gpointer key, gpointer 
value,
                g_slist_prepend(config->service_identifiers,
                                g_strdup(service_id));
 
-       __connman_service_set_immutable(service, TRUE);
+       if (config->virtual == FALSE)
+               __connman_service_set_immutable(service, TRUE);
 
        __connman_service_set_favorite_delayed(service, TRUE, TRUE);
 
@@ -1197,7 +1203,10 @@ static void provision_service(gpointer key, gpointer 
value,
 
        __connman_service_save(service);
 
-       __connman_service_auto_connect();
+       if (config->connect == TRUE)
+               __connman_service_connect(service);
+       else
+               __connman_service_auto_connect();
 }
 
 int __connman_config_provision_service(struct connman_service *service)
@@ -1294,6 +1303,49 @@ int __connman_config_provision_service_ident(struct 
connman_service *service,
        return ret;
 }
 
+int connman_config_provision_mutable_service(GKeyFile *keyfile,
+                                               connman_bool_t connect)
+{
+       const char *vfile = "service_virtual_and_mutable.config";
+       struct connman_config_service *service_config;
+       struct connman_config *config;
+       char *group;
+
+       if (g_hash_table_lookup(config_table, vfile) != NULL)
+               g_hash_table_remove(config_table, vfile);
+
+       config = create_config(vfile);
+       if (config == NULL)
+               return -ENOMEM;
+
+       if (load_service_from_keyfile(keyfile, config) == FALSE)
+               goto error;
+
+       group = g_key_file_get_start_group(keyfile);
+
+       service_config = g_hash_table_lookup(config->service_table, group+8);
+       if (service_config == NULL)
+               goto error;
+
+       /* Specific to non file based config: */
+       g_free(service_config->config_ident);
+       service_config->config_ident = NULL;
+       g_free(service_config->config_entry);
+       service_config->config_entry = NULL;
+
+       service_config->virtual = TRUE;
+       service_config->connect = connect;
+
+       if (connect == TRUE && g_strcmp0(service_config->type, "wifi") == 0)
+               __connman_device_request_scan(CONNMAN_SERVICE_TYPE_WIFI);
+
+       return 0;
+
+error:
+       g_hash_table_remove(config_table, vfile);
+       return -EINVAL;
+}
+
 struct connman_config_entry **connman_config_get_entries(const char *type)
 {
        GHashTableIter iter_file, iter_config;
-- 
1.8.1.2

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to