Add error message for network and device storing failures
[connman] / src / element.c
index f6742f2..7b24a98 100644 (file)
@@ -421,10 +421,7 @@ static void unregister_property(gpointer data)
 
        DBG("property %p", property);
 
-       if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
-               g_free(property->value);
-
-       g_free(property->name);
+       g_free(property->value);
        g_free(property);
 }
 
@@ -436,10 +433,14 @@ void __connman_element_initialize(struct connman_element *element)
 
        element->name    = NULL;
        element->type    = CONNMAN_ELEMENT_TYPE_UNKNOWN;
+       element->state   = CONNMAN_ELEMENT_STATE_UNKNOWN;
+       element->error   = CONNMAN_ELEMENT_ERROR_UNKNOWN;
        element->index   = -1;
        element->enabled = FALSE;
 
-       element->properties = g_hash_table_new_full(g_str_hash, g_direct_equal,
+       element->configuring = FALSE;
+
+       element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                g_free, unregister_property);
 }
 
@@ -511,7 +512,7 @@ void connman_element_unref(struct connman_element *element)
        }
 }
 
-int connman_element_add_static_property(struct connman_element *element,
+static int set_static_property(struct connman_element *element,
                                const char *name, int type, const void *value)
 {
        struct connman_property *property;
@@ -525,10 +526,8 @@ int connman_element_add_static_property(struct connman_element *element,
        if (property == NULL)
                return -ENOMEM;
 
-       property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
-       property->id    = CONNMAN_PROPERTY_ID_INVALID;
-       property->name  = g_strdup(name);
-       property->type  = type;
+       property->id   = CONNMAN_PROPERTY_ID_INVALID;
+       property->type = type;
 
        DBG("name %s type %d value %p", name, type, value);
 
@@ -545,50 +544,14 @@ int connman_element_add_static_property(struct connman_element *element,
 
        __connman_element_lock(element);
 
-       g_hash_table_insert(element->properties, g_strdup(name), property);
-
-       __connman_element_unlock(element);
-
-       return 0;
-}
-
-int connman_element_set_static_property(struct connman_element *element,
-                               const char *name, int type, const void *value)
-{
-       struct connman_property *property;
-
-       DBG("element %p name %s", element, element->name);
-
-       if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
-               return -EINVAL;
-
-       __connman_element_lock(element);
-
-       property = g_hash_table_lookup(element->properties, name);
-       if (property != NULL) {
-               property->flags |= CONNMAN_PROPERTY_FLAG_STATIC;
-
-               property->type = type;
-               g_free(property->value);
-
-               switch (type) {
-               case DBUS_TYPE_STRING:
-                       property->value = g_strdup(*((const char **) value));
-                       break;
-               case DBUS_TYPE_BYTE:
-                       property->value = g_try_malloc(1);
-                       if (property->value != NULL)
-                               memcpy(property->value, value, 1);
-                       break;
-               }
-       }
+       g_hash_table_replace(element->properties, g_strdup(name), property);
 
        __connman_element_unlock(element);
 
        return 0;
 }
 
-int connman_element_add_static_array_property(struct connman_element *element,
+static int set_static_array_property(struct connman_element *element,
                        const char *name, int type, const void *value, int len)
 {
        struct connman_property *property;
@@ -602,9 +565,7 @@ int connman_element_add_static_array_property(struct connman_element *element,
        if (property == NULL)
                return -ENOMEM;
 
-       property->flags   = CONNMAN_PROPERTY_FLAG_STATIC;
        property->id      = CONNMAN_PROPERTY_ID_INVALID;
-       property->name    = g_strdup(name);
        property->type    = DBUS_TYPE_ARRAY;
        property->subtype = type;
 
@@ -623,14 +584,15 @@ int connman_element_add_static_array_property(struct connman_element *element,
 
        __connman_element_lock(element);
 
-       g_hash_table_insert(element->properties, g_strdup(name), property);
+       g_hash_table_replace(element->properties, g_strdup(name), property);
 
        __connman_element_unlock(element);
 
        return 0;
 }
 
-int connman_element_set_property(struct connman_element *element,
+#if 0
+static int set_property(struct connman_element *element,
                                enum connman_property_id id, const void *value)
 {
        switch (id) {
@@ -670,6 +632,7 @@ int connman_element_set_property(struct connman_element *element,
 
        return 0;
 }
+#endif
 
 int connman_element_get_value(struct connman_element *element,
                                enum connman_property_id id, void *value)
@@ -733,7 +696,7 @@ int connman_element_get_value(struct connman_element *element,
        return 0;
 }
 
-gboolean connman_element_get_static_property(struct connman_element *element,
+static gboolean get_static_property(struct connman_element *element,
                                                const char *name, void *value)
 {
        struct connman_property *property;
@@ -744,33 +707,29 @@ gboolean connman_element_get_static_property(struct connman_element *element,
        __connman_element_lock(element);
 
        property = g_hash_table_lookup(element->properties, name);
-       if (property != NULL &&
-                       (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)) {
-               if (g_str_equal(property->name, name) == TRUE) {
-                       switch (property->type) {
-                       case DBUS_TYPE_STRING:
-                               *((char **) value) = property->value;
-                               found = TRUE;
-                               break;
-                       case DBUS_TYPE_BYTE:
-                               memcpy(value, property->value, 1);
-                               found = TRUE;
-                               break;
-                       }
+       if (property != NULL) {
+               switch (property->type) {
+               case DBUS_TYPE_STRING:
+                       *((char **) value) = property->value;
+                       found = TRUE;
+                       break;
+               case DBUS_TYPE_BYTE:
+                       memcpy(value, property->value, 1);
+                       found = TRUE;
+                       break;
                }
        }
 
        __connman_element_unlock(element);
 
        if (found == FALSE && element->parent != NULL)
-               return connman_element_get_static_property(element->parent,
-                                                               name, value);
+               return get_static_property(element->parent, name, value);
 
        return found;
 }
 
-gboolean connman_element_get_static_array_property(struct connman_element *element,
-                                       const char *name, void *value, int *len)
+static gboolean get_static_array_property(struct connman_element *element,
+                       const char *name, void *value, unsigned int *len)
 {
        struct connman_property *property;
        gboolean found = FALSE;
@@ -780,13 +739,10 @@ gboolean connman_element_get_static_array_property(struct connman_element *eleme
        __connman_element_lock(element);
 
        property = g_hash_table_lookup(element->properties, name);
-       if (property != NULL &&
-                       (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)) {
-               if (g_str_equal(property->name, name) == TRUE) {
-                       *((char **) value) = property->value;
-                       *len = property->size;
-                       found = TRUE;
-               }
+       if (property != NULL) {
+               *((char **) value) = property->value;
+               *len = property->size;
+               found = TRUE;
        }
 
        __connman_element_unlock(element);
@@ -794,7 +750,8 @@ gboolean connman_element_get_static_array_property(struct connman_element *eleme
        return found;
 }
 
-gboolean connman_element_match_static_property(struct connman_element *element,
+#if 0
+static gboolean match_static_property(struct connman_element *element,
                                        const char *name, const void *value)
 {
        struct connman_property *property;
@@ -805,10 +762,8 @@ gboolean connman_element_match_static_property(struct connman_element *element,
        __connman_element_lock(element);
 
        property = g_hash_table_lookup(element->properties, name);
-       if (property != NULL &&
-                       (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)) {
-               if (g_str_equal(property->name, name) == TRUE &&
-                                       property->type == DBUS_TYPE_STRING)
+       if (property != NULL) {
+               if (property->type == DBUS_TYPE_STRING)
                        result = g_str_equal(property->value,
                                                *((const char **) value));
        }
@@ -817,6 +772,106 @@ gboolean connman_element_match_static_property(struct connman_element *element,
 
        return result;
 }
+#endif
+
+/**
+ * connman_element_set_string:
+ * @element: element structure
+ * @key: unique identifier
+ * @value: string value
+ *
+ * Set string value for specific key
+ */
+int connman_element_set_string(struct connman_element *element,
+                                       const char *key, const char *value)
+{
+       return set_static_property(element, key, DBUS_TYPE_STRING, &value);
+}
+
+/**
+ * connman_element_get_string:
+ * @element: element structure
+ * @key: unique identifier
+ *
+ * Get string value for specific key
+ */
+const char *connman_element_get_string(struct connman_element *element,
+                                                       const char *key)
+{
+       const char *value;
+
+       if (get_static_property(element, key, &value) == FALSE)
+               return NULL;
+
+       return value;
+}
+
+/**
+ * connman_element_set_uint8:
+ * @element: element structure
+ * @key: unique identifier
+ * @value: integer value
+ *
+ * Set integer value for specific key
+ */
+int connman_element_set_uint8(struct connman_element *element,
+                                       const char *key, connman_uint8_t value)
+{
+        return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
+}
+
+/**
+ * connman_element_get_uint8:
+ * @element: element structure
+ * @key: unique identifier
+ *
+ * Get integer value for specific key
+ */
+connman_uint8_t connman_element_get_uint8(struct connman_element *element,
+                                                       const char *key)
+{
+       connman_uint8_t value;
+
+       if (get_static_property(element, key, &value) == FALSE)
+                return 0;
+
+       return value;
+}
+
+/**
+ * connman_element_set_blob:
+ * @element: element structure
+ * @key: unique identifier
+ * @data: blob data
+ * @size: blob size
+ *
+ * Set binary blob value for specific key
+ */
+int connman_element_set_blob(struct connman_element *element,
+                       const char *key, const void *data, unsigned int size)
+{
+       return set_static_array_property(element, key,
+                                               DBUS_TYPE_BYTE, &data, size);
+}
+
+/**
+ * connman_element_get_blob:
+ * @element: element structure
+ * @key: unique identifier
+ * @size: pointer to blob size
+ *
+ * Get binary blob value for specific key
+ */
+const void *connman_element_get_blob(struct connman_element *element,
+                                       const char *key, unsigned int *size)
+{
+       void *value;
+
+       if (get_static_array_property(element, key, &value, size) == FALSE)
+               return NULL;
+
+       return value;
+}
 
 int __connman_element_append_ipv4(struct connman_element *element,
                                                DBusMessageIter *dict)
@@ -919,44 +974,6 @@ int __connman_element_set_ipv4(struct connman_element *element,
        return 0;
 }
 
-static void append_connections(DBusMessageIter *entry)
-{
-       DBusMessageIter value, iter;
-       const char *key = "Connections";
-
-       dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
-
-       dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
-               DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
-                                                               &value);
-
-       dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
-                               DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
-       __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
-       dbus_message_iter_close_container(&value, &iter);
-
-       dbus_message_iter_close_container(entry, &value);
-}
-
-static void emit_connections_signal(DBusConnection *conn)
-{
-       DBusMessage *signal;
-       DBusMessageIter entry;
-
-       DBG("conn %p", conn);
-
-       signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
-                               CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
-       if (signal == NULL)
-               return;
-
-       dbus_message_iter_init_append(signal, &entry);
-
-       append_connections(&entry);
-
-       g_dbus_send_message(conn, signal);
-}
-
 static void append_state(DBusMessageIter *entry, const char *state)
 {
        DBusMessageIter value;
@@ -1039,9 +1056,25 @@ static void register_element(gpointer data, gpointer user_data)
 
        g_node_append_data(node, element);
 
+       if (element->type == CONNMAN_ELEMENT_TYPE_DHCP) {
+               element->parent->configuring = TRUE;
+
+               if (__connman_element_count(NULL,
+                                       CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
+                       emit_state_change(connection, "connecting");
+       }
+
        if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
-               emit_connections_signal(connection);
-               emit_state_change(connection, "online");
+               struct connman_element *parent = element->parent;
+
+               while (parent) {
+                       parent->configuring = FALSE;
+                       parent = parent->parent;
+               }
+
+               if (__connman_element_count(NULL,
+                                       CONNMAN_ELEMENT_TYPE_CONNECTION) == 1)
+                       emit_state_change(connection, "online");
        }
 
        emit_element_signal(connection, "ElementAdded", element);
@@ -1133,7 +1166,6 @@ static gboolean remove_element(GNode *node, gpointer user_data)
                if (__connman_element_count(NULL,
                                        CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
                        emit_state_change(connection, "offline");
-               emit_connections_signal(connection);
        }
 
        emit_element_signal(connection, "ElementRemoved", element);
@@ -1204,10 +1236,35 @@ int connman_element_set_enabled(struct connman_element *element,
 
        element->enabled = enabled;
 
+       connman_element_update(element);
+
        return 0;
 }
 
-int __connman_element_init(DBusConnection *conn, const char *device)
+/**
+ * connman_element_set_error:
+ * @element: element structure
+ * @error: error identifier
+ *
+ * Set error state and specific error identifier
+ */
+void connman_element_set_error(struct connman_element *element,
+                                       enum connman_element_error error)
+{
+       DBG("element %p error %d", element, error);
+
+       if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
+               return;
+
+       element->state = CONNMAN_ELEMENT_STATE_ERROR;
+       element->error = error;
+
+       if (element->driver && element->driver->change)
+               element->driver->change(element);
+}
+
+int __connman_element_init(DBusConnection *conn, const char *device,
+                                                       const char *nodevice)
 {
        struct connman_element *element;
 
@@ -1226,6 +1283,8 @@ int __connman_element_init(DBusConnection *conn, const char *device)
 
        element_root = g_node_new(element);
 
+       __connman_notifier_init();
+       __connman_service_init();
        __connman_network_init();
        __connman_device_init();
 
@@ -1310,6 +1369,8 @@ void __connman_element_cleanup(void)
 
        __connman_device_cleanup();
        __connman_network_cleanup();
+       __connman_service_cleanup();
+       __connman_notifier_cleanup();
 
        g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
                                                        free_driver, NULL);