From: Samuel Ortiz <[email protected]>

In service_load(), if we get a nameless service, we try to search for a
matching BSSID from the saved services, and we update the service accordingly.
Getting a nameless service means the corresponding network's name could not be
set due to a missing SSID, which basically means it's a hidden network.
---
 plugins/supplicant.c |    5 ++-
 src/service.c        |   95 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/plugins/supplicant.c b/plugins/supplicant.c
index 5a68231..350325c 100644
--- a/plugins/supplicant.c
+++ b/plugins/supplicant.c
@@ -1193,8 +1193,9 @@ static void properties_reply(DBusPendingCall *call, void 
*user_data)
        if (result.name != NULL && result.name[0] != '\0')
                connman_network_set_name(network, result.name);
 
-       connman_network_set_blob(network, "WiFi.SSID",
-                                               result.ssid, result.ssid_len);
+       if (result.ssid)
+               connman_network_set_blob(network, "WiFi.SSID",
+                                        result.ssid, result.ssid_len);
 
        connman_network_set_string(network, "WiFi.Mode", mode);
 
diff --git a/src/service.c b/src/service.c
index 24ee710..46ee0f7 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1140,6 +1140,8 @@ static int service_register(struct connman_service 
*service)
        if (service->path != NULL)
                return -EALREADY;
 
+       __connman_storage_load_service(service);
+
        service->path = g_strdup_printf("%s/%s", path, service->identifier);
 
        DBG("path %s", service->path);
@@ -1149,8 +1151,6 @@ static int service_register(struct connman_service 
*service)
                                        service_methods, service_signals,
                                                        NULL, service, NULL);
 
-       __connman_storage_load_service(service);
-
        iter = g_hash_table_lookup(service_hash, service->identifier);
        if (iter != NULL)
                g_sequence_sort_changed(iter, service_compare, NULL);
@@ -1445,15 +1445,52 @@ done:
        return service;
 }
 
+static void __connman_service_set_wifi(struct connman_service *service,
+                                      char *group, GKeyFile *keyfile)
+{
+       void *ssid;
+       int ssid_len;
+       gchar *security, *passphrase;
+
+       ssid = g_key_file_get_value(keyfile, group,
+                                   "SSID", NULL);
+       ssid_len = g_key_file_get_integer(keyfile, group,
+                                         "SSID_len", NULL);
+       security = g_key_file_get_string(keyfile, group,
+                                        "Security", NULL);
+       passphrase = g_key_file_get_string(keyfile, group,
+                                          "Passphrase", NULL);
+
+       if (ssid)
+               connman_network_set_blob(service->network, "WiFi.SSID",
+                                        ssid, ssid_len);
+
+       if (security)
+               connman_network_set_string(service->network, "WiFi.Security",
+                                          security);
+
+       if (passphrase)
+               connman_network_set_string(service->network, "WiFi.Passphrase",
+                                          passphrase);
+
+       g_free(ssid);
+       g_free(passphrase);
+       g_free(security);
+}
+
 static int service_load(struct connman_service *service)
 {
        GKeyFile *keyfile;
        gchar *pathname, *data = NULL;
        gsize length;
        gchar *str;
+       const char *addr;
 
        DBG("service %p", service);
 
+       if (service->network)
+               addr = connman_network_get_string(service->network, "Address");
+
        if (service->profile == NULL)
                return -EINVAL;
 
@@ -1483,6 +1520,60 @@ static int service_load(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_ETHERNET:
                break;
        case CONNMAN_SERVICE_TYPE_WIFI:
+               if (addr && !service->name) {
+                       gchar **groups;
+                       gchar *bssid, *name;
+                       gsize length;
+                       int i = 0;
+
+                       /*
+                        * This service is nameless, it's most likely a hidden
+                        * network. We're going to search for a saved matching
+                        * BSSID, and if found, set the service name
+                        * appropriately.
+                        */
+                       groups = g_key_file_get_groups(keyfile, &length);
+                       while (groups[i]) {
+                               bssid = g_key_file_get_string(keyfile,
+                                                             groups[i],
+                                                             "BSSID", NULL);
+
+                               if (!bssid || g_strcmp0(bssid, addr)) {
+                                       i++;
+                                       g_free(bssid);
+                                       continue;
+                               }
+
+                               g_free(bssid);
+
+                               name = g_key_file_get_string(keyfile, groups[i],
+                                                            "Name", NULL);
+
+                               if (!name)
+                                       break;
+                               /*
+                                * We have found a name for this BSSID, so
+                                * we can safely set the corresponding service
+                                * and network name to it.
+                                */
+                               g_free(service->identifier);
+                               service->identifier = g_strdup(groups[i]);
+
+                               g_free(service->name);
+                               service->name = g_strdup(name);
+                               connman_network_set_name(service->network,
+                                                        name);
+
+                               __connman_service_set_wifi(service, groups[i],
+                                                          keyfile);
+
+                               update_from_network(service, service->network);
+
+                               g_free(name);
+                               break;
+                       }
+               }
+
        case CONNMAN_SERVICE_TYPE_WIMAX:
        case CONNMAN_SERVICE_TYPE_BLUETOOTH:
        case CONNMAN_SERVICE_TYPE_CELLULAR:
-- 
1.6.3.1

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to