---
 plugins/supplicant.c |    3 +-
 src/service.c        |  121 +++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 116 insertions(+), 8 deletions(-)

diff --git a/plugins/supplicant.c b/plugins/supplicant.c
index 0fe931e..666d12d 100644
--- a/plugins/supplicant.c
+++ b/plugins/supplicant.c
@@ -1352,8 +1352,7 @@ static void properties_reply(DBusPendingCall *call, void 
*user_data)
        connman_network_set_uint16(network, "WiFi.Channel", channel);
        connman_network_set_string(network, "WiFi.Security", security);
 
-       if (result.ssid != NULL)
-               connman_network_set_group(network, group);
+       connman_network_set_group(network, group);
 
 done:
        g_free(group);
diff --git a/src/service.c b/src/service.c
index 09d2534..d8ac4e2 100644
--- a/src/service.c
+++ b/src/service.c
@@ -56,6 +56,7 @@ struct connman_service {
        struct connman_ipconfig *ipconfig;
        struct connman_device *device;
        struct connman_network *network;
+       GList *network_list;
        DBusMessage *pending;
        guint timeout;
 };
@@ -927,6 +928,7 @@ static void service_free(gpointer user_data)
 {
        struct connman_service *service = user_data;
        char *path = service->path;
+       GList *list;
 
        DBG("service %p", service);
 
@@ -947,6 +949,16 @@ static void service_free(gpointer user_data)
        if (service->network != NULL)
                connman_network_unref(service->network);
 
+       for (list = service->network_list; list; list = list->next) {
+               struct connman_network *network = list->data;
+
+               connman_network_unref(network);
+
+               list->data = NULL;
+       }
+
+       g_list_free(service->network_list);
+
        if (service->ipconfig != NULL) {
                connman_ipconfig_unref(service->ipconfig);
                service->ipconfig = NULL;
@@ -1589,12 +1601,24 @@ static struct connman_service 
*__connman_service_get(const char *identifier)
 
        __connman_storage_load_service(service);
 
-       iter = g_sequence_insert_sorted(service_list, service,
-                                               service_compare, NULL);
+       return service;
+}
 
-       g_hash_table_insert(service_hash, service->identifier, iter);
+static connman_bool_t is_hidden_wifi_service(struct connman_service *service)
+{
+       const unsigned char *ssid;
+       unsigned int ssid_len = 0;
 
-       return service;
+       if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+               return FALSE;
+
+       ssid = connman_network_get_blob(service->network,
+                                       "WiFi.SSID", &ssid_len);
+
+       if (ssid != NULL && ssid_len > 0 && ssid[0] != '\0')
+               return FALSE;
+
+       return TRUE;
 }
 
 static int service_register(struct connman_service *service)
@@ -1607,6 +1631,16 @@ static int service_register(struct connman_service 
*service)
        if (service->path != NULL)
                return -EALREADY;
 
+       if (is_hidden_wifi_service(service) == TRUE) {
+               __connman_storage_save_service(service);
+               return -EINVAL;
+       }
+
+       iter = g_sequence_insert_sorted(service_list, service,
+                                               service_compare, NULL);
+
+       g_hash_table_insert(service_hash, service->identifier, iter);
+
        service->path = g_strdup_printf("%s/%s", path, service->identifier);
 
        DBG("path %s", service->path);
@@ -1662,6 +1696,7 @@ struct connman_service 
*__connman_service_create_from_device(struct connman_devi
        struct connman_service *service;
        const char *ident;
        char *name;
+       int err;
 
        ident = __connman_device_get_ident(device);
        if (ident == NULL)
@@ -1686,7 +1721,11 @@ struct connman_service 
*__connman_service_create_from_device(struct connman_devi
 
        service->device = device;
 
-       service_register(service);
+       err = service_register(service);
+       if (err == -EINVAL) {
+               __connman_service_put(service);
+               return NULL;
+       }
 
        __connman_profile_changed(TRUE);
 
@@ -1819,6 +1858,22 @@ static enum connman_service_mode 
convert_wifi_security(const char *security)
                return CONNMAN_SERVICE_SECURITY_UNKNOWN;
 }
 
+static void add_network(struct connman_service *service,
+                               struct connman_network *network)
+{
+       struct connman_network *data = connman_network_ref(network);
+
+       service->network_list = g_list_append(service->network_list, data);
+}
+
+static void remove_network(struct connman_service *service,
+                               struct connman_network *network)
+{
+       service->network_list = g_list_remove(service->network_list, network);
+
+       connman_network_unref(network);
+}
+
 static void update_from_network(struct connman_service *service,
                                        struct connman_network *network)
 {
@@ -1877,6 +1932,7 @@ struct connman_service 
*__connman_service_create_from_network(struct connman_net
        struct connman_service *service;
        const char *ident, *group;
        char *name;
+       int err;
 
        ident = __connman_network_get_ident(network);
        if (ident == NULL)
@@ -1894,6 +1950,8 @@ struct connman_service 
*__connman_service_create_from_network(struct connman_net
        if (service == NULL)
                return NULL;
 
+       add_network(service, network);
+
        if (__connman_network_get_weakness(network) == TRUE)
                return service;
 
@@ -1922,7 +1980,11 @@ struct connman_service 
*__connman_service_create_from_network(struct connman_net
 
        update_from_network(service, network);
 
-       service_register(service);
+       err = service_register(service);
+       if (err == -EINVAL) {
+               __connman_service_put(service);
+               return NULL;
+       }
 
        __connman_profile_changed(TRUE);
 
@@ -1961,6 +2023,8 @@ void __connman_service_remove_from_network(struct 
connman_network *network)
        if (service == NULL)
                return;
 
+       remove_network(service, network);
+
        __connman_service_put(service);
 }
 
@@ -2096,6 +2160,49 @@ done:
        return err;
 }
 
+static char *get_hidden_service_identifier(struct connman_network *network)
+{
+       const char *device_ident, *type, *ident, *mode, *security;
+       char *identifier;
+
+       device_ident = __connman_network_get_ident(network);
+
+       ident = connman_network_get_identifier(network);
+
+       type = __connman_network_get_type(network);
+
+       mode = connman_network_get_string(network, "WiFi.Mode");
+
+       security = connman_network_get_string(network, "WiFi.Security");
+
+       identifier = g_strdup_printf("%s_%s_hidden_%s_%s_%s",
+                               type, device_ident, ident, mode, security);
+
+       return identifier;
+}
+
+static void store_hidden_networks_group(struct connman_service *service,
+                                                       GKeyFile *keyfile)
+{
+       char *identifier;
+       const char *group;
+       GList *list;
+
+       for (list = service->network_list; list; list = list->next) {
+               struct connman_network *network = list->data;
+
+               identifier = get_hidden_service_identifier(network);
+
+               group = connman_network_get_group(network);
+
+               if (g_key_file_has_group(keyfile, identifier) == TRUE)
+                       g_key_file_set_string(keyfile, identifier,
+                                                       "Group", group);
+
+               g_free(identifier);
+       }
+}
+
 static int service_save(struct connman_service *service)
 {
        const char *ident = service->profile;
@@ -2163,6 +2270,8 @@ update:
                                                        "SSID", str->str);
 
                                g_string_free(str, TRUE);
+
+                               store_hidden_networks_group(service, keyfile);
                        }
                }
                /* fall through */
-- 
1.6.1.3

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

Reply via email to