Add first attempt for the property system
authorMarcel Holtmann <marcel@holtmann.org>
Sun, 29 Jun 2008 05:46:51 +0000 (07:46 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Sun, 29 Jun 2008 05:46:51 +0000 (07:46 +0200)
include/Makefile.am
include/element.h
include/property.h [new file with mode: 0644]
plugins/dhclient.c
plugins/hal.c
plugins/ipv4.c
src/element.c

index e2dacdc..70c39d2 100644 (file)
@@ -1,7 +1,7 @@
 
 includedir = @includedir@/connman
 
-include_HEADERS = log.h plugin.h driver.h element.h dbus.h
+include_HEADERS = log.h plugin.h driver.h element.h property.h dbus.h
 
 noinst_HEADERS = iface.h rtnl.h dhcp.h resolver.h
 
index dfcbd0f..1d14424 100644 (file)
@@ -29,6 +29,8 @@ extern "C" {
 #include <errno.h>
 #include <glib.h>
 
+#include <connman/property.h>
+
 enum connman_element_state {
        CONNMAN_ELEMENT_STATE_UNKNOWN   = 0,
        CONNMAN_ELEMENT_STATE_CONNECT   = 1,
@@ -74,11 +76,7 @@ struct connman_element {
        struct connman_driver *driver;
        void *driver_data;
 
-       struct {
-               gchar *driver;
-               gchar *vendor;
-               gchar *product;
-       } info;
+       GSList *properties;
 
        struct {
                int index;
@@ -100,6 +98,13 @@ extern struct connman_element *connman_element_create(void);
 extern struct connman_element *connman_element_ref(struct connman_element *element);
 extern void connman_element_unref(struct connman_element *element);
 
+extern int connman_element_add_static_property(struct connman_element *element,
+                               const char *name, int type, const void *value);
+extern int connman_element_set_property(struct connman_element *element,
+                       enum connman_property_type type, const void *value);
+extern int connman_element_get_value(struct connman_element *element,
+                               enum connman_property_type type, void *value);
+
 extern int connman_element_register(struct connman_element *element,
                                        struct connman_element *parent);
 extern void connman_element_unregister(struct connman_element *element);
diff --git a/include/property.h b/include/property.h
new file mode 100644 (file)
index 0000000..76ff04e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2007-2008  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __CONNMAN_PROPERTY_H
+#define __CONNMAN_PROPERTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum connman_property_type {
+       CONNMAN_PROPERTY_TYPE_INVALID = 0,
+
+       CONNMAN_PROPERTY_TYPE_IPV4_ADDRESS,
+       CONNMAN_PROPERTY_TYPE_IPV4_NETMASK,
+       CONNMAN_PROPERTY_TYPE_IPV4_GATEWAY,
+};
+
+enum connman_property_flags {
+       CONNMAN_PROPERTY_FLAG_STATIC = (1 << 0),
+};
+
+struct connman_property {
+       enum connman_property_flags flags;
+       char *name;
+       int type;
+       void *value;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMAN_PROPERTY_H */
index 5dddc63..1802259 100644 (file)
@@ -40,7 +40,7 @@ struct dhclient_task {
        GPid pid;
        int ifindex;
        gchar *ifname;
-       struct connman_element *parent;
+       struct connman_element *element;
        struct connman_element *child;
 };
 
@@ -143,7 +143,7 @@ static int dhclient_probe(struct connman_element *element)
 
        task->ifindex = element->netdev.index;
        task->ifname = g_strdup(element->netdev.name);
-       task->parent = element;
+       task->element = element;
        task->child = NULL;
 
        if (task->ifname == NULL) {
@@ -230,23 +230,6 @@ static struct connman_driver dhclient_driver = {
        .remove         = dhclient_remove,
 };
 
-static void copy_ipv4(struct connman_element *src, struct connman_element *dst)
-{
-       g_free(dst->ipv4.address);
-       g_free(dst->ipv4.netmask);
-       g_free(dst->ipv4.gateway);
-       g_free(dst->ipv4.network);
-       g_free(dst->ipv4.broadcast);
-       g_free(dst->ipv4.nameserver);
-
-       dst->ipv4.address = g_strdup(src->ipv4.address);
-       dst->ipv4.netmask = g_strdup(src->ipv4.netmask);
-       dst->ipv4.gateway = g_strdup(src->ipv4.gateway);
-       dst->ipv4.network = g_strdup(src->ipv4.network);
-       dst->ipv4.broadcast = g_strdup(src->ipv4.broadcast);
-       dst->ipv4.nameserver = g_strdup(src->ipv4.nameserver);
-}
-
 static DBusHandlerResult dhclient_filter(DBusConnection *conn,
                                                DBusMessage *msg, void *data)
 {
@@ -287,23 +270,35 @@ static DBusHandlerResult dhclient_filter(DBusConnection *conn,
 
                DBG("%s = %s", key, value);
 
-               if (g_ascii_strcasecmp(key, "new_ip_address") == 0)
-                       task->parent->ipv4.address = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_ip_address") == 0) {
+                       g_free(task->element->ipv4.address);
+                       task->element->ipv4.address = g_strdup(value);
+               }
 
-               if (g_ascii_strcasecmp(key, "new_subnet_mask") == 0)
-                       task->parent->ipv4.netmask = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_subnet_mask") == 0) {
+                       g_free(task->element->ipv4.netmask);
+                       task->element->ipv4.netmask = g_strdup(value);
+               }
 
-               if (g_ascii_strcasecmp(key, "new_routers") == 0)
-                       task->parent->ipv4.gateway = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_routers") == 0) {
+                       g_free(task->element->ipv4.gateway);
+                       task->element->ipv4.gateway = g_strdup(value);
+               }
 
-               if (g_ascii_strcasecmp(key, "new_network_number") == 0)
-                       task->parent->ipv4.network = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_network_number") == 0) {
+                       g_free(task->element->ipv4.network);
+                       task->element->ipv4.network = g_strdup(value);
+               }
 
-               if (g_ascii_strcasecmp(key, "new_broadcast_address") == 0)
-                       task->parent->ipv4.broadcast = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_broadcast_address") == 0) {
+                       g_free(task->element->ipv4.broadcast);
+                       task->element->ipv4.broadcast = g_strdup(value);
+               }
 
-               if (g_ascii_strcasecmp(key, "new_domain_name_servers") == 0)
-                       task->parent->ipv4.nameserver = g_strdup(value);
+               if (g_ascii_strcasecmp(key, "new_domain_name_servers") == 0) {
+                       g_free(task->element->ipv4.nameserver);
+                       task->element->ipv4.nameserver = g_strdup(value);
+               }
 
                dbus_message_iter_next(&dict);
        }
@@ -314,11 +309,11 @@ static DBusHandlerResult dhclient_filter(DBusConnection *conn,
                task->child = connman_element_create();
                task->child->type = CONNMAN_ELEMENT_TYPE_IPV4;
                task->child->netdev.index = task->ifindex;
-               copy_ipv4(task->parent, task->child);
-               connman_element_register(task->child, task->parent);
+               connman_element_update(task->element);
+               connman_element_register(task->child, task->element);
        } else if (g_ascii_strcasecmp(text, "RENEW") == 0 ||
                                g_ascii_strcasecmp(text, "REBIND") == 0) {
-               copy_ipv4(task->parent, task->child);
+               connman_element_update(task->element);
                connman_element_update(task->child);
        } else {
        }
index bb5ad94..467e5d3 100644 (file)
@@ -59,19 +59,22 @@ static void device_info(LibHalContext *ctx, const char *udi,
                value = libhal_device_get_property_string(ctx, parent,
                                                "info.linux.driver", NULL);
                if (value != NULL)
-                       element->info.driver = g_strdup(value);
+                       connman_element_add_static_property(element,
+                                       "Driver", DBUS_TYPE_STRING, &value);
        }
 
        if (g_str_equal(subsys, "net") == TRUE) {
                value = libhal_device_get_property_string(ctx, parent,
                                                        "info.vendor", NULL);
                if (value != NULL)
-                       element->info.vendor = g_strdup(value);
+                       connman_element_add_static_property(element,
+                                       "Vendor", DBUS_TYPE_STRING, &value);
 
                value = libhal_device_get_property_string(ctx, parent,
                                                        "info.product", NULL);
                if (value != NULL)
-                       element->info.product = g_strdup(value);
+                       connman_element_add_static_property(element,
+                                       "Product", DBUS_TYPE_STRING, &value);
        }
 }
 
index 66e55b9..9370644 100644 (file)
 
 static int ipv4_probe(struct connman_element *element)
 {
+       const char *address = NULL, *netmask = NULL, *gateway = NULL;
+
        DBG("element %p name %s", element, element->name);
 
-       DBG("address %s", element->ipv4.address);
-       DBG("netmask %s", element->ipv4.netmask);
-       DBG("gateway %s", element->ipv4.gateway);
+       connman_element_get_value(element,
+                               CONNMAN_PROPERTY_TYPE_IPV4_ADDRESS, &address);
+       connman_element_get_value(element,
+                               CONNMAN_PROPERTY_TYPE_IPV4_NETMASK, &netmask);
+       connman_element_get_value(element,
+                               CONNMAN_PROPERTY_TYPE_IPV4_GATEWAY, &gateway);
+
+       DBG("address %s", address);
+       DBG("netmask %s", netmask);
+       DBG("gateway %s", gateway);
 
        return 0;
 }
index a4f0328..93ae5d1 100644 (file)
@@ -106,6 +106,9 @@ static void append_entry(DBusMessageIter *dict,
        case DBUS_TYPE_UINT16:
                signature = DBUS_TYPE_UINT16_AS_STRING;
                break;
+       case DBUS_TYPE_OBJECT_PATH:
+               signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
+               break;
        default:
                signature = DBUS_TYPE_VARIANT_AS_STRING;
                break;
@@ -119,10 +122,21 @@ static void append_entry(DBusMessageIter *dict,
        dbus_message_iter_close_container(dict, &entry);
 }
 
+static void append_property(DBusMessageIter *dict,
+                               struct connman_property *property)
+{
+       if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC) {
+               append_entry(dict, property->name, property->type,
+                                                       &property->value);
+               return;
+       }
+}
+
 static DBusMessage *get_properties(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        struct connman_element *element = data;
+       GSList *list;
        DBusMessage *reply;
        DBusMessageIter array, dict;
        const char *str;
@@ -140,38 +154,33 @@ static DBusMessage *get_properties(DBusConnection *conn,
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
+       if (element->parent != NULL)
+               append_entry(&dict, "Parent",
+                               DBUS_TYPE_OBJECT_PATH, &element->parent->path);
+
        str = type2string(element->type);
        if (str != NULL)
                append_entry(&dict, "Type", DBUS_TYPE_STRING, &str);
-
        str = subtype2string(element->subtype);
        if (str != NULL)
                append_entry(&dict, "Subtype", DBUS_TYPE_STRING, &str);
 
-       if (element->info.driver != NULL)
-               append_entry(&dict, "Driver",
-                               DBUS_TYPE_STRING, &element->info.driver);
-
-       if (element->info.vendor != NULL)
-               append_entry(&dict, "Vendor",
-                               DBUS_TYPE_STRING, &element->info.vendor);
-
-       if (element->info.product != NULL)
-               append_entry(&dict, "Product",
-                               DBUS_TYPE_STRING, &element->info.product);
-
        if (element->ipv4.address != NULL)
                append_entry(&dict, "IPv4.Address",
                                DBUS_TYPE_STRING, &element->ipv4.address);
-
        if (element->ipv4.netmask != NULL)
                append_entry(&dict, "IPv4.Netmask",
                                DBUS_TYPE_STRING, &element->ipv4.netmask);
-
        if (element->ipv4.gateway != NULL)
                append_entry(&dict, "IPv4.Gateway",
                                DBUS_TYPE_STRING, &element->ipv4.gateway);
 
+       for (list = element->properties; list; list = list->next) {
+               struct connman_property *property = list->data;
+
+               append_property(&dict, property);
+       }
+
        dbus_message_iter_close_container(&array, &dict);
 
        return reply;
@@ -313,6 +322,18 @@ void connman_element_unref(struct connman_element *element)
                                g_atomic_int_get(&element->refcount) - 1);
 
        if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
+               GSList *list;
+
+               for (list = element->properties; list; list = list->next) {
+                       struct connman_property *property = list->data;
+                       if ((property->flags & CONNMAN_PROPERTY_FLAG_STATIC) &&
+                                       property->type == DBUS_TYPE_STRING)
+                               g_free(property->value);
+                       g_free(property);
+                       list->data = NULL;
+               }
+               g_slist_free(element->properties);
+
                g_free(element->ipv4.address);
                g_free(element->ipv4.netmask);
                g_free(element->ipv4.gateway);
@@ -320,15 +341,104 @@ void connman_element_unref(struct connman_element *element)
                g_free(element->ipv4.broadcast);
                g_free(element->ipv4.nameserver);
                g_free(element->netdev.name);
-               g_free(element->info.driver);
-               g_free(element->info.vendor);
-               g_free(element->info.product);
                g_free(element->path);
                g_free(element->name);
                g_free(element);
        }
 }
 
+int connman_element_add_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)
+               return -EINVAL;
+
+       property = g_try_new0(struct connman_property, 1);
+       if (property == NULL)
+               return -ENOMEM;
+
+       property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
+
+       property->name = g_strdup(name);
+       property->type = type;
+
+       DBG("name %s type %d value %p", name, type, value);
+
+       switch (type) {
+       case DBUS_TYPE_STRING:
+               property->value = g_strdup(*((const char **) value));
+               break;
+       }
+
+       element->properties = g_slist_append(element->properties, property);
+
+       return 0;
+}
+
+int connman_element_set_property(struct connman_element *element,
+                       enum connman_property_type type, const void *value)
+{
+       switch (type) {
+       case CONNMAN_PROPERTY_TYPE_INVALID:
+               return -EINVAL;
+       case CONNMAN_PROPERTY_TYPE_IPV4_ADDRESS:
+               g_free(element->ipv4.address);
+               element->ipv4.address = g_strdup(*((const char **) value));
+               break;
+       case CONNMAN_PROPERTY_TYPE_IPV4_NETMASK:
+               g_free(element->ipv4.netmask);
+               element->ipv4.netmask = g_strdup(*((const char **) value));
+               break;
+       case CONNMAN_PROPERTY_TYPE_IPV4_GATEWAY:
+               g_free(element->ipv4.gateway);
+               element->ipv4.gateway = g_strdup(*((const char **) value));
+               break;
+       }
+
+       g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
+
+       return 0;
+}
+
+int connman_element_get_value(struct connman_element *element,
+                               enum connman_property_type type, void *value)
+{
+       if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
+               return -EINVAL;
+
+       switch (type) {
+       case CONNMAN_PROPERTY_TYPE_INVALID:
+               return -EINVAL;
+       case CONNMAN_PROPERTY_TYPE_IPV4_ADDRESS:
+               if (element->ipv4.address == NULL)
+                       return connman_element_get_value(element->parent,
+                                                               type, value);
+               *((char **) value) = element->ipv4.address;
+               break;
+       case CONNMAN_PROPERTY_TYPE_IPV4_NETMASK:
+               if (element->ipv4.netmask == NULL)
+                       return connman_element_get_value(element->parent,
+                                                               type, value);
+               *((char **) value) = element->ipv4.netmask;
+               break;
+       case CONNMAN_PROPERTY_TYPE_IPV4_GATEWAY:
+               if (element->ipv4.gateway == NULL)
+                       return connman_element_get_value(element->parent,
+                                                               type, value);
+               *((char **) value) = element->ipv4.gateway;
+               break;
+       }
+
+       return 0;
+}
+
 int connman_element_register(struct connman_element *element,
                                        struct connman_element *parent)
 {
@@ -455,6 +565,11 @@ void connman_element_update(struct connman_element *element)
                element->driver->update(element);
 
        g_static_mutex_unlock(&element_mutex);
+
+       g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
 }
 
 static inline void set_driver(struct connman_element *element,