From: Daniel Wagner <[email protected]>

---
 include/element.h   |    2 -
 include/network.h   |    3 +
 plugins/bluetooth.c |    3 +
 plugins/ethernet.c  |    3 +
 plugins/fake.c      |    2 +
 plugins/iwmx.c      |    3 +
 plugins/ofono.c     |    5 +
 plugins/wifi.c      |   10 ++-
 src/device.c        |   14 +--
 src/element.c       |    6 -
 src/network.c       |  378 ++++++++++++++++++++++++++++-----------------------
 src/service.c       |   17 ++-
 12 files changed, 251 insertions(+), 195 deletions(-)

diff --git a/include/element.h b/include/element.h
index 57a7632..3499cdf 100644
--- a/include/element.h
+++ b/include/element.h
@@ -42,7 +42,6 @@ extern "C" {
 enum connman_element_type {
        CONNMAN_ELEMENT_TYPE_UNKNOWN    = 0,
        CONNMAN_ELEMENT_TYPE_ROOT       = 1,
-       CONNMAN_ELEMENT_TYPE_NETWORK    = 4,
 };
 
 enum connman_element_state {
@@ -80,7 +79,6 @@ struct connman_element {
 
        union {
                void *private;
-               struct connman_network *network;
        };
 
        GHashTable *properties;
diff --git a/include/network.h b/include/network.h
index d6cc27b..de7235b 100644
--- a/include/network.h
+++ b/include/network.h
@@ -157,6 +157,9 @@ void connman_network_set_data(struct connman_network 
*network, void *data);
 
 void connman_network_update(struct connman_network *network);
 
+int connman_network_register(struct connman_network *network);
+void connman_network_unregister(struct connman_network *network);
+
 struct connman_network_driver {
        const char *name;
        enum connman_network_type type;
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index f67e9ec..8d8a0dd 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -215,6 +215,7 @@ done:
 
        dbus_pending_call_unref(call);
 
+       connman_network_unregister(network);
        connman_network_unref(network);
 }
 
@@ -438,6 +439,8 @@ static void network_properties_reply(DBusPendingCall *call, 
void *user_data)
        if (network == NULL)
                goto done;
 
+       connman_network_register(network);
+
        connman_network_set_path(network, path);
 
        connman_network_set_name(network, name);
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 2ccd498..4829a33 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -92,12 +92,15 @@ static void add_network(struct connman_device *device)
        if (network == NULL)
                return;
 
+       connman_network_register(network);
+
        index = connman_device_get_index(device);
        connman_network_set_index(network, index);
 
        connman_network_set_name(network, "Wired");
 
        if (connman_device_add_network(device, network) < 0) {
+               connman_network_unregister(network);
                connman_network_unref(network);
                return;
        }
diff --git a/plugins/fake.c b/plugins/fake.c
index a3aed22..6ec4ba5 100644
--- a/plugins/fake.c
+++ b/plugins/fake.c
@@ -38,6 +38,8 @@ static void create_network(struct connman_device *device, 
const char *name)
        if (network == NULL)
                return;
 
+       connman_network_register(network);
+
        connman_device_add_network(device, network);
        connman_network_unref(network);
 }
diff --git a/plugins/iwmx.c b/plugins/iwmx.c
index 419b3c9..e79c1af 100644
--- a/plugins/iwmx.c
+++ b/plugins/iwmx.c
@@ -132,6 +132,7 @@ struct connman_network *__iwmx_cm_network_available(
                DBG("new network %s", station_name);
                nw = connman_network_create(station_name,
                                            CONNMAN_NETWORK_TYPE_WIMAX);
+               connman_network_register(nw);
                connman_network_set_index(nw, connman_device_get_index(dev));
                connman_network_set_name(nw, station_name);
                connman_network_set_blob(nw, "WiMAX.NSP.name",
@@ -148,6 +149,7 @@ struct connman_network *__iwmx_cm_network_available(
                group[3 * cnt + 1] = 0;
                connman_network_set_group(nw, station_name);
                if (connman_device_add_network(dev, nw) < 0) {
+                       connman_network_unregister(nw);
                        connman_network_unref(nw);
                        goto error_add;
                }
@@ -255,6 +257,7 @@ static void __iwmx_cm_dev_disconnected(struct wmxsdk 
*wmxsdk)
                DBG("disconnected from network %s\n",
                                        connman_network_get_identifier(nw));
                connman_network_set_connected(nw, FALSE);
+               connman_network_unregister(nw);
                connman_network_unref(nw);
                wmxsdk->nw = NULL;
        } else
diff --git a/plugins/ofono.c b/plugins/ofono.c
index 2af54d6..01b2b8b 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -366,6 +366,7 @@ static void remove_network(gpointer data)
 {
        struct network_info *info = data;
 
+       connman_network_unregister(info->network);
        connman_network_unref(info->network);
 
        g_free(info);
@@ -830,8 +831,11 @@ static int add_network(struct connman_device *device,
        if (network == NULL)
                return -ENOMEM;
 
+       connman_network_register(network);
+
        info = g_try_new0(struct network_info, 1);
        if (info == NULL) {
+               connman_network_unregister(network);
                connman_network_unref(network);
                return -ENOMEM;
        }
@@ -896,6 +900,7 @@ static int add_network(struct connman_device *device,
        return 0;
 
 error:
+       connman_network_unregister(network);
        connman_network_unref(network);
        g_hash_table_remove(network_hash, path);
        return -EIO;
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 19f006b..cfafbd2 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -774,6 +774,8 @@ static void network_added(GSupplicantNetwork 
*supplicant_network)
                if (network == NULL)
                        return;
 
+               connman_network_register(network);
+
                connman_network_set_index(network, wifi->index);
 
                if (connman_device_add_network(wifi->device, network) < 0) {
@@ -802,6 +804,7 @@ static void network_removed(GSupplicantNetwork *network)
        GSupplicantInterface *interface;
        struct wifi_data *wifi;
        const char *name, *identifier;
+       struct connman_network *connman_network;
 
        interface = g_supplicant_network_get_interface(network);
        wifi = g_supplicant_interface_get_data(interface);
@@ -810,8 +813,13 @@ static void network_removed(GSupplicantNetwork *network)
 
        DBG("name %s", name);
 
-       if (wifi != NULL)
+       if (wifi != NULL) {
+               connman_network = connman_device_get_network(wifi->device, 
identifier);
+               if (connman_network != NULL)
+                       connman_network_unregister(connman_network);
+
                connman_device_remove_network(wifi->device, identifier);
+       }
 }
 
 static void debug(const char *str)
diff --git a/src/device.c b/src/device.c
index 43f0bcf..d1f1ad5 100644
--- a/src/device.c
+++ b/src/device.c
@@ -424,10 +424,9 @@ static void unregister_network(gpointer data)
 
        DBG("network %p", network);
 
-       connman_element_unregister((struct connman_element *) network);
-
        __connman_network_set_device(network, NULL);
 
+       connman_network_unregister(network);
        connman_network_unref(network);
 }
 
@@ -1067,7 +1066,6 @@ int connman_device_add_network(struct connman_device 
*device,
                                        struct connman_network *network)
 {
        const char *identifier = connman_network_get_identifier(network);
-       int err;
 
        DBG("device %p network %p", device, network);
 
@@ -1076,13 +1074,6 @@ int connman_device_add_network(struct connman_device 
*device,
 
        __connman_network_set_device(network, device);
 
-       err = connman_element_register((struct connman_element *) network,
-                               NULL);
-       if (err < 0) {
-               __connman_network_set_device(network, NULL);
-               return err;
-       }
-
        g_hash_table_insert(device->networks, g_strdup(identifier),
                                                                network);
 
@@ -1122,7 +1113,8 @@ int connman_device_remove_network(struct connman_device 
*device,
        if (network == NULL)
                return 0;
 
-       connman_element_unregister((struct connman_element *) network);
+       __connman_network_set_device(network, NULL);
+
        g_hash_table_remove(device->networks, identifier);
 
        return 0;
diff --git a/src/element.c b/src/element.c
index a9a643b..75d5126 100644
--- a/src/element.c
+++ b/src/element.c
@@ -46,8 +46,6 @@ static const char *type2string(enum connman_element_type type)
                return "unknown";
        case CONNMAN_ELEMENT_TYPE_ROOT:
                return "root";
-       case CONNMAN_ELEMENT_TYPE_NETWORK:
-               return "network";
        }
 
        return NULL;
@@ -119,10 +117,6 @@ static gboolean append_path(GNode *node, gpointer 
user_data)
                                        filter->type != element->type)
                return FALSE;
 
-       if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
-                       __connman_network_has_driver(element->network) == FALSE)
-               return FALSE;
-
        dbus_message_iter_append_basic(filter->iter,
                                DBUS_TYPE_OBJECT_PATH, &element->path);
 
diff --git a/src/network.c b/src/network.c
index 84256ee..e87ce19 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,10 +28,12 @@
 
 #include "connman.h"
 
+static GSList *network_list = NULL;
+static GSList *driver_list = NULL;
 static unsigned int hidden_counter = 0;
 
 struct connman_network {
-       struct connman_element element;
+       gint refcount;
        enum connman_network_type type;
        connman_bool_t available;
        connman_bool_t connected;
@@ -44,6 +46,7 @@ struct connman_network {
        char *node;
        char *group;
        char *path;
+       int index;
 
        struct connman_network_driver *driver;
        void *driver_data;
@@ -71,6 +74,11 @@ struct connman_network {
                connman_bool_t use_wps;
                char *pin_wps;
        } wifi;
+
+       struct {
+               char *nsp_name;
+               int nsp_name_len;
+       } wimax;
 };
 
 static const char *type2string(enum connman_network_type type)
@@ -103,7 +111,166 @@ connman_bool_t __connman_network_has_driver(struct 
connman_network *network)
        return TRUE;
 }
 
-static GSList *driver_list = NULL;
+static gboolean match_driver(struct connman_network *network,
+                                       struct connman_network_driver *driver)
+{
+       if (network->type == driver->type ||
+                       driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
+               return TRUE;
+
+       return FALSE;
+}
+
+static int network_probe(struct connman_network *network)
+{
+       GSList *list;
+       struct connman_network_driver *driver = NULL;
+
+       DBG("network %p name %s", network, network->name);
+
+       if (network->driver != NULL)
+               return -EALREADY;
+
+       for (list = driver_list; list; list = list->next) {
+               driver = list->data;
+
+               if (match_driver(network, driver) == FALSE)
+                       continue;
+
+               DBG("driver %p name %s", driver, driver->name);
+
+               if (driver->probe(network) == 0)
+                       break;
+
+               driver = NULL;
+       }
+
+       if (driver == NULL)
+               return -ENODEV;
+
+       if (network->group == NULL)
+               return -EINVAL;
+
+       switch (network->type) {
+       case CONNMAN_NETWORK_TYPE_UNKNOWN:
+       case CONNMAN_NETWORK_TYPE_VENDOR:
+               return 0;
+       case CONNMAN_NETWORK_TYPE_ETHERNET:
+       case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
+       case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
+       case CONNMAN_NETWORK_TYPE_CELLULAR:
+       case CONNMAN_NETWORK_TYPE_WIFI:
+       case CONNMAN_NETWORK_TYPE_WIMAX:
+               if (__connman_service_create_from_network(network) == NULL)
+                       return -EINVAL;
+       }
+
+       network->driver = driver;
+
+       return 0;
+}
+
+static void network_remove(struct connman_network *network)
+{
+       DBG("network %p name %s", network, network->name);
+
+       if (network->driver == NULL)
+               return;
+
+       switch (network->type) {
+       case CONNMAN_NETWORK_TYPE_UNKNOWN:
+       case CONNMAN_NETWORK_TYPE_VENDOR:
+               break;
+       case CONNMAN_NETWORK_TYPE_ETHERNET:
+       case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
+       case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
+       case CONNMAN_NETWORK_TYPE_CELLULAR:
+       case CONNMAN_NETWORK_TYPE_WIFI:
+       case CONNMAN_NETWORK_TYPE_WIMAX:
+               if (network->group != NULL) {
+                       __connman_service_remove_from_network(network);
+
+                       g_free(network->group);
+                       network->group = NULL;
+               }
+               break;
+       }
+
+       if (network->driver->remove)
+               network->driver->remove(network);
+
+       network->driver = NULL;
+}
+
+static void network_change(struct connman_network *network)
+{
+       DBG("network %p name %s", network, network->name);
+
+       if (network->connected == FALSE)
+               return;
+
+       connman_network_unref(network);
+
+       connman_device_set_disconnected(network->device, TRUE);
+
+       if (network->driver && network->driver->disconnect) {
+               network->driver->disconnect(network);
+               return;
+       }
+
+       network->connected = FALSE;
+}
+
+static void probe_driver(struct connman_network_driver *driver)
+{
+       GSList *list;
+
+       DBG("driver %p name %s", driver, driver->name);
+
+       for (list = network_list; list != NULL; list = list->next) {
+               struct connman_network *network = list->data;
+
+               if (network->driver != NULL)
+                       continue;
+
+               if (driver->type != network->type)
+                       continue;
+
+               if (driver->probe(network) < 0)
+                       continue;
+
+               network->driver = driver;
+       }
+}
+
+int connman_network_register(struct connman_network *network)
+{
+       network_list = g_slist_append(network_list, network);
+
+       return network_probe(network);
+}
+
+
+void connman_network_unregister(struct connman_network *network)
+{
+       network_list = g_slist_remove(network_list, network);
+
+       network_remove(network);
+}
+
+static void remove_driver(struct connman_network_driver *driver)
+{
+       GSList *list;
+
+       DBG("driver %p name %s", driver, driver->name);
+
+       for (list = network_list; list != NULL; list = list->next) {
+               struct connman_network *network = list->data;
+
+               if (network->driver == driver)
+                       network_remove(network);
+       }
+}
 
 static gint compare_priority(gconstpointer a, gconstpointer b)
 {
@@ -138,6 +305,8 @@ int connman_network_driver_register(struct 
connman_network_driver *driver)
        driver_list = g_slist_insert_sorted(driver_list, driver,
                                                        compare_priority);
 
+       probe_driver(driver);
+
        return 0;
 }
 
@@ -152,13 +321,13 @@ void connman_network_driver_unregister(struct 
connman_network_driver *driver)
        DBG("driver %p name %s", driver, driver->name);
 
        driver_list = g_slist_remove(driver_list, driver);
+
+       remove_driver(driver);
 }
 
-static void network_destruct(struct connman_element *element)
+static void network_destruct(struct connman_network *network)
 {
-       struct connman_network *network = element->network;
-
-       DBG("element %p name %s", element, element->name);
+       DBG("network %p name %s", network, network->name);
 
        g_free(network->wifi.ssid);
        g_free(network->wifi.mode);
@@ -178,8 +347,11 @@ static void network_destruct(struct connman_element 
*element)
        g_free(network->node);
        g_free(network->name);
        g_free(network->identifier);
+       g_free(network->path);
 
        network->device = NULL;
+
+       g_free(network);
 }
 
 /**
@@ -194,8 +366,6 @@ struct connman_network *connman_network_create(const char 
*identifier,
                                                enum connman_network_type type)
 {
        struct connman_network *network;
-       connman_uint8_t strength = 0;
-       const char *str;
        char *temp;
 
        DBG("identifier %s type %d", identifier, type);
@@ -206,7 +376,7 @@ struct connman_network *connman_network_create(const char 
*identifier,
 
        DBG("network %p", network);
 
-       __connman_element_initialize(&network->element);
+       network->refcount = 1;
 
        if (identifier == NULL) {
                temp = g_strdup_printf("hidden_%d", hidden_counter++);
@@ -219,18 +389,6 @@ struct connman_network *connman_network_create(const char 
*identifier,
                return NULL;
        }
 
-       network->element.name = temp;
-       network->element.type = CONNMAN_ELEMENT_TYPE_NETWORK;
-
-       network->element.network = network;
-       network->element.destruct = network_destruct;
-
-       str = type2string(type);
-       if (str != NULL)
-               connman_element_set_string(&network->element, "Type", str);
-
-       connman_element_set_uint8(&network->element, "Strength", strength);
-
        network->type       = type;
        network->identifier = g_strdup(temp);
 
@@ -245,8 +403,10 @@ struct connman_network *connman_network_create(const char 
*identifier,
  */
 struct connman_network *connman_network_ref(struct connman_network *network)
 {
-       if (connman_element_ref(&network->element) == NULL)
-               return NULL;
+       DBG("network %p name %s refcount %d", network, network->name,
+               g_atomic_int_get(&network->refcount) + 1);
+
+       g_atomic_int_inc(&network->refcount);
 
        return network;
 }
@@ -259,7 +419,13 @@ struct connman_network *connman_network_ref(struct 
connman_network *network)
  */
 void connman_network_unref(struct connman_network *network)
 {
-       connman_element_unref(&network->element);
+       DBG("network %p name %s refcount %d", network, network->name,
+               g_atomic_int_get(&network->refcount) - 1);
+
+       if (g_atomic_int_dec_and_test(&network->refcount) == FALSE)
+               return;
+
+       network_destruct(network);
 }
 
 const char *__connman_network_get_type(struct connman_network *network)
@@ -307,10 +473,10 @@ void connman_network_set_index(struct connman_network 
*network, int index)
 
        ipconfig = __connman_service_get_ip4config(service);
 
-       DBG("index %d service %p ip4config %p", network->element.index,
+       DBG("index %d service %p ip4config %p", network->index,
                service, ipconfig);
 
-       if (network->element.index < 0 && ipconfig == NULL) {
+       if (network->index < 0 && ipconfig == NULL) {
 
                ipconfig = __connman_service_get_ip4config(service);
                if (ipconfig == NULL)
@@ -332,7 +498,7 @@ void connman_network_set_index(struct connman_network 
*network, int index)
        }
 
 done:
-       network->element.index = index;
+       network->index = index;
 }
 
 /**
@@ -343,19 +509,7 @@ done:
  */
 int connman_network_get_index(struct connman_network *network)
 {
-       return network->element.index;
-}
-
-/**
- * connman_network_get_element:
- * @network: network structure
- *
- * Get connman_element of network
- */
-struct connman_element *connman_network_get_element(
-                               struct connman_network *network)
-{
-       return &network->element;
+       return network->index;
 }
 
 /**
@@ -396,7 +550,7 @@ void connman_network_set_group(struct connman_network 
*network,
        network->group = g_strdup(group);
 
        if (network->group != NULL)
-               __connman_service_create_from_network(network);
+               network_probe(network);
 }
 
 /**
@@ -614,6 +768,8 @@ void connman_network_set_error(struct connman_network 
*network,
                set_connect_error(network);
                break;
        }
+
+       network_change(network);
 }
 
 void connman_network_clear_error(struct connman_network *network)
@@ -911,8 +1067,6 @@ static gboolean set_connected(gpointer user_data)
        } else {
                struct connman_service *service;
 
-               connman_element_unregister_children(&network->element);
-
                __connman_device_set_network(network->device, NULL);
                network->hidden = FALSE;
 
@@ -1611,7 +1765,16 @@ const unsigned char 
*connman_network_get_wifi_ssid(struct connman_network *netwo
 void __connman_network_set_device(struct connman_network *network,
                                        struct connman_device *device)
 {
+       if (network->device == device)
+               return;
+
+       if (network->device != NULL)
+               network_remove(network);
+
        network->device = device;
+
+       if (network->device != NULL)
+               network_probe(network);
 }
 
 /**
@@ -1665,143 +1828,16 @@ void connman_network_update(struct connman_network 
*network)
 
        if (network->group != NULL)
                __connman_service_update_from_network(network);
-
-       return;
 }
 
-static gboolean match_driver(struct connman_network *network,
-                                       struct connman_network_driver *driver)
-{
-       if (network->type == driver->type ||
-                       driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
-               return TRUE;
-
-       return FALSE;
-}
-
-static int network_probe(struct connman_element *element)
-{
-       struct connman_network *network = element->network;
-       GSList *list;
-
-       DBG("element %p name %s", element, element->name);
-
-       if (network == NULL)
-               return -ENODEV;
-
-       for (list = driver_list; list; list = list->next) {
-               struct connman_network_driver *driver = list->data;
-
-               if (match_driver(network, driver) == FALSE)
-                       continue;
-
-               DBG("driver %p name %s", driver, driver->name);
-
-               if (driver->probe(network) == 0) {
-                       network->driver = driver;
-                       break;
-               }
-       }
-
-       if (network->driver == NULL)
-               return -ENODEV;
-
-       switch (network->type) {
-       case CONNMAN_NETWORK_TYPE_UNKNOWN:
-       case CONNMAN_NETWORK_TYPE_VENDOR:
-               break;
-       case CONNMAN_NETWORK_TYPE_ETHERNET:
-       case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
-       case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
-       case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_WIFI:
-       case CONNMAN_NETWORK_TYPE_WIMAX:
-               if (network->group != NULL &&
-                        __connman_service_create_from_network(network) == NULL)
-                               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static void network_remove(struct connman_element *element)
-{
-       struct connman_network *network = element->network;
-
-       DBG("element %p name %s", element, element->name);
-
-       if (network == NULL)
-               return;
-
-       if (network->driver == NULL)
-               return;
-
-       switch (network->type) {
-       case CONNMAN_NETWORK_TYPE_UNKNOWN:
-       case CONNMAN_NETWORK_TYPE_VENDOR:
-               break;
-       case CONNMAN_NETWORK_TYPE_ETHERNET:
-       case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
-       case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
-       case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_WIFI:
-       case CONNMAN_NETWORK_TYPE_WIMAX:
-               if (network->group != NULL) {
-                       __connman_service_remove_from_network(network);
-
-                       g_free(network->group);
-                       network->group = NULL;
-               }
-               break;
-       }
-
-       if (network->driver->remove)
-               network->driver->remove(network);
-}
-
-static void network_change(struct connman_element *element)
-{
-       struct connman_network *network = element->network;
-
-       DBG("element %p name %s", element, element->name);
-
-       if (element->state != CONNMAN_ELEMENT_STATE_ERROR)
-               return;
-
-       if (network->connected == FALSE)
-               return;
-
-       connman_element_unregister_children(element);
-
-       connman_device_set_disconnected(network->device, TRUE);
-
-       if (network->driver && network->driver->disconnect) {
-               network->driver->disconnect(network);
-               return;
-       }
-
-       network->connected = FALSE;
-}
-
-static struct connman_driver network_driver = {
-       .name           = "network",
-       .type           = CONNMAN_ELEMENT_TYPE_NETWORK,
-       .priority       = CONNMAN_DRIVER_PRIORITY_LOW,
-       .probe          = network_probe,
-       .remove         = network_remove,
-       .change         = network_change,
-};
-
 int __connman_network_init(void)
 {
        DBG("");
 
-       return connman_driver_register(&network_driver);
+       return 0;
 }
 
 void __connman_network_cleanup(void)
 {
        DBG("");
-
-       connman_driver_unregister(&network_driver);
 }
diff --git a/src/service.c b/src/service.c
index 567b3c6..b95d567 100644
--- a/src/service.c
+++ b/src/service.c
@@ -75,6 +75,7 @@ struct connman_service {
        char *profile;
        connman_bool_t roaming;
        connman_bool_t login_required;
+       connman_bool_t network_created;
        struct connman_ipconfig *ipconfig_ipv4;
        struct connman_ipconfig *ipconfig_ipv6;
        struct connman_network *network;
@@ -2920,8 +2921,11 @@ static void service_free(gpointer user_data)
 
        g_hash_table_destroy(service->counter_table);
 
-       if (service->network != NULL)
+       if (service->network != NULL) {
+               if (service->network_created == TRUE)
+                       connman_network_unregister(service->network);
                connman_network_unref(service->network);
+       }
 
        if (service->provider != NULL)
                connman_provider_unref(service->provider);
@@ -3012,6 +3016,8 @@ static void service_initialize(struct connman_service 
*service)
        service->refcount = 1;
        service->session_usage_count = 0;
 
+       service->network_created = FALSE;
+
        service->type     = CONNMAN_SERVICE_TYPE_UNKNOWN;
        service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
 
@@ -4042,6 +4048,8 @@ static struct connman_network *create_hidden_wifi(struct 
connman_device *device,
        if (network == NULL)
                return NULL;
 
+       connman_network_register(network);
+
        connman_network_set_wifi_ssid(network,
                                        (unsigned char *) ssid, ssid_len);
 
@@ -4050,6 +4058,7 @@ static struct connman_network *create_hidden_wifi(struct 
connman_device *device,
 
        name = g_try_malloc0(ssid_len + 1);
        if (name == NULL) {
+               connman_network_unregister(network);
                connman_network_unref(network);
                return NULL;
        }
@@ -4069,6 +4078,7 @@ static struct connman_network *create_hidden_wifi(struct 
connman_device *device,
        connman_network_set_index(network, index);
 
        if (connman_device_add_network(device, network) < 0) {
+               connman_network_unregister(network);
                connman_network_unref(network);
                return NULL;
        }
@@ -4089,7 +4099,6 @@ int __connman_service_create_and_connect(DBusMessage *msg)
        unsigned int ssid_len = 0;
        const char *ident;
        char *name, *group;
-       gboolean created = FALSE;
        int err;
 
        dbus_message_iter_init(msg, &iter);
@@ -4177,7 +4186,7 @@ int __connman_service_create_and_connect(DBusMessage *msg)
        network = create_hidden_wifi(device, ssid, mode, security);
        if (network != NULL) {
                connman_network_set_group(network, group);
-               created = TRUE;
+               service->network_created = TRUE;
        }
 
        service = lookup_by_identifier(name);
@@ -4221,7 +4230,7 @@ done:
        return 0;
 
 failed:
-       if (service != NULL && created == TRUE) {
+       if (service != NULL && service->network_created == TRUE) {
                struct connman_network *network = service->network;
 
                if (network != NULL) {
-- 
1.7.5.2

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

Reply via email to