From: Marcel Holtmann Date: Sun, 29 Jun 2008 05:46:51 +0000 (+0200) Subject: Add first attempt for the property system X-Git-Tag: 0.1~318 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6ec36bb5141766e44e4786cb11661e14fbd388a9;p=platform%2Fupstream%2Fconnman.git Add first attempt for the property system --- diff --git a/include/Makefile.am b/include/Makefile.am index e2dacdc..70c39d2 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 diff --git a/include/element.h b/include/element.h index dfcbd0f..1d14424 100644 --- a/include/element.h +++ b/include/element.h @@ -29,6 +29,8 @@ extern "C" { #include #include +#include + 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 index 0000000..76ff04e --- /dev/null +++ b/include/property.h @@ -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 */ diff --git a/plugins/dhclient.c b/plugins/dhclient.c index 5dddc63..1802259 100644 --- a/plugins/dhclient.c +++ b/plugins/dhclient.c @@ -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 { } diff --git a/plugins/hal.c b/plugins/hal.c index bb5ad94..467e5d3 100644 --- a/plugins/hal.c +++ b/plugins/hal.c @@ -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); } } diff --git a/plugins/ipv4.c b/plugins/ipv4.c index 66e55b9..9370644 100644 --- a/plugins/ipv4.c +++ b/plugins/ipv4.c @@ -29,11 +29,20 @@ 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; } diff --git a/src/element.c b/src/element.c index a4f0328..93ae5d1 100644 --- a/src/element.c +++ b/src/element.c @@ -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,