X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Felement.c;h=873a5f5fc51652ee956c2a201ceccbc815a0f085;hb=4f9a0637340e17790ad3c29546adc34ab6ce0362;hp=d1e6de3e56450b9e316bf8a77ffc9e998dab2395;hpb=5bb2816373b31c080a944dc957f3f38c1282aedf;p=connman diff --git a/src/element.c b/src/element.c index d1e6de3..873a5f5 100644 --- a/src/element.c +++ b/src/element.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2009 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 @@ -38,6 +38,8 @@ static GNode *element_root = NULL; static GSList *driver_list = NULL; static gchar *device_filter = NULL; +static gboolean started = FALSE; + static struct { enum connman_property_id id; int type; @@ -52,6 +54,8 @@ static struct { DBUS_TYPE_STRING, "IPv4.Netmask" }, { CONNMAN_PROPERTY_ID_IPV4_GATEWAY, DBUS_TYPE_STRING, "IPv4.Gateway" }, + { CONNMAN_PROPERTY_ID_IPV4_BROADCAST, + DBUS_TYPE_STRING, "IPv4.Broadcast" }, { CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, DBUS_TYPE_STRING, "IPv4.Nameserver" }, @@ -102,6 +106,8 @@ static const char *type2string(enum connman_element_type type) return "network"; case CONNMAN_ELEMENT_TYPE_SERVICE: return "service"; + case CONNMAN_ELEMENT_TYPE_PPP: + return "ppp"; case CONNMAN_ELEMENT_TYPE_IPV4: return "ipv4"; case CONNMAN_ELEMENT_TYPE_IPV6: @@ -114,6 +120,8 @@ static const char *type2string(enum connman_element_type type) return "zeroconf"; case CONNMAN_ELEMENT_TYPE_CONNECTION: return "connection"; + case CONNMAN_ELEMENT_TYPE_VENDOR: + return "vendor"; } return NULL; @@ -126,16 +134,14 @@ static const char *subtype2string(enum connman_element_subtype type) return "unknown"; case CONNMAN_ELEMENT_SUBTYPE_FAKE: return "fake"; - case CONNMAN_ELEMENT_SUBTYPE_NETWORK: - return "network"; case CONNMAN_ELEMENT_SUBTYPE_ETHERNET: return "ethernet"; case CONNMAN_ELEMENT_SUBTYPE_WIFI: return "wifi"; case CONNMAN_ELEMENT_SUBTYPE_WIMAX: return "wimax"; - case CONNMAN_ELEMENT_SUBTYPE_MODEM: - return "modem"; + case CONNMAN_ELEMENT_SUBTYPE_CELLULAR: + return "cellular"; case CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH: return "bluetooth"; } @@ -272,6 +278,7 @@ static void add_common_properties(struct connman_element *element, __connman_element_unlock(element); } +#if 0 static void set_common_property(struct connman_element *element, const char *name, DBusMessageIter *value) { @@ -306,6 +313,28 @@ static void set_common_property(struct connman_element *element, __connman_element_unlock(element); } +#endif + +static void emit_element_signal(DBusConnection *conn, const char *member, + struct connman_element *element) +{ + DBusMessage *signal; + + if (__connman_debug_enabled() == FALSE) + return; + + DBG("conn %p member %s", conn, member); + + if (element == NULL) + return; + + signal = dbus_message_new_signal(element->path, + CONNMAN_DEBUG_INTERFACE, member); + if (signal == NULL) + return; + + g_dbus_send_message(conn, signal); +} static void emit_enabled_signal(DBusConnection *conn, struct connman_element *element) @@ -320,13 +349,9 @@ static void emit_enabled_signal(DBusConnection *conn, return; switch (element->type) { - case CONNMAN_ELEMENT_TYPE_DEVICE: - iface = CONNMAN_DEVICE_INTERFACE; - key = "Powered"; - break; - case CONNMAN_ELEMENT_TYPE_NETWORK: - iface = CONNMAN_NETWORK_INTERFACE; - key = "Connected"; + case CONNMAN_ELEMENT_TYPE_CONNECTION: + iface = CONNMAN_CONNECTION_INTERFACE; + key = "Default"; break; default: return; @@ -350,26 +375,6 @@ static void emit_enabled_signal(DBusConnection *conn, g_dbus_send_message(conn, signal); } -static DBusMessage *do_update(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct connman_element *element = data; - - DBG("conn %p", conn); - - if (element->enabled == FALSE) - return __connman_error_failed(msg); - - if (element->driver && element->driver->update) { - DBG("Calling update callback"); - if (element->driver->update(element) < 0) - return __connman_error_failed(msg); - - } - - return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); -} - static DBusMessage *do_enable(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -416,34 +421,12 @@ static DBusMessage *do_disable(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static void append_networks(struct connman_element *element, - DBusMessageIter *entry) -{ - DBusMessageIter value, iter; - const char *key = "Networks"; - - 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(element, CONNMAN_ELEMENT_TYPE_NETWORK, &iter); - - dbus_message_iter_close_container(&value, &iter); - - dbus_message_iter_close_container(entry, &value); -} - -static DBusMessage *device_get_properties(DBusConnection *conn, +static DBusMessage *connection_get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { struct connman_element *element = data; DBusMessage *reply; - DBusMessageIter array, dict, entry; + DBusMessageIter array, dict; const char *str; DBG("conn %p", conn); @@ -464,21 +447,17 @@ static DBusMessage *device_get_properties(DBusConnection *conn, connman_dbus_dict_append_variant(&dict, "Type", DBUS_TYPE_STRING, &str); - str = __connman_element_policy2string(element->policy); - if (str != NULL) - connman_dbus_dict_append_variant(&dict, "Policy", - DBUS_TYPE_STRING, &str); - - connman_dbus_dict_append_variant(&dict, "Powered", - DBUS_TYPE_BOOLEAN, &element->enabled); + if (element->devname != NULL) + connman_dbus_dict_append_variant(&dict, "Interface", + DBUS_TYPE_STRING, &element->devname); if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_WIFI || - element->subtype == CONNMAN_ELEMENT_SUBTYPE_WIMAX) { - dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, - NULL, &entry); - append_networks(element, &entry); - dbus_message_iter_close_container(&dict, &entry); - } + element->subtype == CONNMAN_ELEMENT_SUBTYPE_WIMAX) + connman_dbus_dict_append_variant(&dict, "Strength", + DBUS_TYPE_BYTE, &element->strength); + + connman_dbus_dict_append_variant(&dict, "Default", + DBUS_TYPE_BOOLEAN, &element->enabled); add_common_properties(element, &dict); @@ -487,7 +466,7 @@ static DBusMessage *device_get_properties(DBusConnection *conn, return reply; } -static DBusMessage *device_set_property(DBusConnection *conn, +static DBusMessage *connection_set_property(DBusConnection *conn, DBusMessage *msg, void *data) { struct connman_element *element = data; @@ -506,239 +485,78 @@ static DBusMessage *device_set_property(DBusConnection *conn, if (__connman_security_check_privileges(msg) < 0) return __connman_error_permission_denied(msg); - if (g_str_equal(name, "Powered") == TRUE) { - dbus_bool_t powered; + if (g_str_equal(name, "Default") == TRUE) { + dbus_bool_t enabled; - dbus_message_iter_get_basic(&value, &powered); + dbus_message_iter_get_basic(&value, &enabled); - if (powered == TRUE) - do_enable(conn, msg, data); + if (enabled == TRUE) + return do_enable(conn, msg, element); else - do_disable(conn, msg, data); - } else - set_common_property(element, name, &value); - - __connman_element_store(element); - - return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); -} - -static int parse_network_dict(DBusMessageIter *iter, const char **ssid, - const char **security, const char **passphrase) -{ - while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter entry, value; - const char *key; - - dbus_message_iter_recurse(iter, &entry); - dbus_message_iter_get_basic(&entry, &key); - - dbus_message_iter_next(&entry); - dbus_message_iter_recurse(&entry, &value); - - switch (dbus_message_iter_get_arg_type(&value)) { - case DBUS_TYPE_STRING: - if (g_str_equal(key, "WiFi.SSID") == TRUE) - dbus_message_iter_get_basic(&value, ssid); - else if (g_str_equal(key, "WiFi.Security") == TRUE) - dbus_message_iter_get_basic(&value, security); - else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) - dbus_message_iter_get_basic(&value, passphrase); - break; - } - - dbus_message_iter_next(iter); + return do_disable(conn, msg, element); } - return 0; -} - -static DBusMessage *device_create_network(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct connman_element *element = data; - struct connman_element *network; - DBusMessageIter iter, array; - const char *ssid = NULL, *security = NULL, *passphrase = NULL; - - DBG("conn %p", conn); - - if (dbus_message_iter_init(msg, &iter) == FALSE) - return __connman_error_invalid_arguments(msg); - - dbus_message_iter_recurse(&iter, &array); - parse_network_dict(&array, &ssid, &security, &passphrase); - if (ssid == NULL) - return __connman_error_invalid_arguments(msg); - - DBG("ssid %s security %s passphrase %s", ssid, security, passphrase); - - network = connman_element_create(ssid); - - network->type = CONNMAN_ELEMENT_TYPE_NETWORK; - network->index = element->index; - - network->remember = TRUE; - - connman_element_add_static_property(network, "Name", - DBUS_TYPE_STRING, &ssid); - - connman_element_add_static_array_property(element, "WiFi.SSID", - DBUS_TYPE_BYTE, &ssid, strlen(ssid)); - - network->wifi.security = g_strdup(security); - network->wifi.passphrase = g_strdup(passphrase); - - connman_element_register(network, element); - - return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &network->path, - DBUS_TYPE_INVALID); -} - -static DBusMessage *device_remove_network(DBusConnection *conn, - DBusMessage *msg, void *data) -{ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static DBusMessage *network_get_properties(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct connman_element *element = data; - DBusMessage *reply; - DBusMessageIter array, dict; - const char *str; - - DBG("conn %p", conn); - - reply = dbus_message_new_method_return(msg); - if (reply == NULL) - return NULL; - - dbus_message_iter_init_append(reply, &array); - - dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - - str = __connman_element_policy2string(element->policy); - if (str != NULL) - connman_dbus_dict_append_variant(&dict, "Policy", - DBUS_TYPE_STRING, &str); - - connman_dbus_dict_append_variant(&dict, "Available", - DBUS_TYPE_BOOLEAN, &element->available); - - connman_dbus_dict_append_variant(&dict, "Connected", - DBUS_TYPE_BOOLEAN, &element->enabled); - - connman_dbus_dict_append_variant(&dict, "Remember", - DBUS_TYPE_BOOLEAN, &element->remember); - - add_common_properties(element, &dict); +static GDBusMethodTable connection_methods[] = { + { "GetProperties", "", "a{sv}", connection_get_properties }, + { "SetProperty", "sv", "", connection_set_property }, + { }, +}; - dbus_message_iter_close_container(&array, &dict); +static GDBusSignalTable element_signals[] = { + { "PropertyChanged", "sv" }, + { }, +}; - return reply; -} +struct foreach_data { + enum connman_element_type type; + element_cb_t callback; + gpointer user_data; +}; -static DBusMessage *network_set_property(DBusConnection *conn, - DBusMessage *msg, void *data) +static gboolean foreach_callback(GNode *node, gpointer user_data) { - struct connman_element *element = data; - DBusMessageIter iter; - DBusMessageIter value; - const char *name; - - DBG("conn %p", conn); - - if (dbus_message_iter_init(msg, &iter) == FALSE) - return __connman_error_invalid_arguments(msg); - - dbus_message_iter_get_basic(&iter, &name); - dbus_message_iter_next(&iter); - dbus_message_iter_recurse(&iter, &value); + struct connman_element *element = node->data; + struct foreach_data *data = user_data; - if (__connman_security_check_privileges(msg) < 0) - return __connman_error_permission_denied(msg); + DBG("element %p name %s", element, element->name); - if (g_str_equal(name, "Remember") == TRUE) { - dbus_message_iter_get_basic(&value, &element->remember); - } else if (g_str_equal(name, "WiFi.Passphrase") == TRUE) { - const char *str; + if (element->type == CONNMAN_ELEMENT_TYPE_ROOT) + return FALSE; - dbus_message_iter_get_basic(&value, &str); - g_free(element->wifi.passphrase); - element->wifi.passphrase = g_strdup(str); - } else - set_common_property(element, name, &value); + if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN && + data->type != element->type) + return FALSE; - __connman_element_store(element); + if (data->callback) + data->callback(element, data->user_data); - return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + return FALSE; } -static DBusMessage *connection_get_properties(DBusConnection *conn, - DBusMessage *msg, void *data) +void __connman_element_foreach(struct connman_element *element, + enum connman_element_type type, + element_cb_t callback, gpointer user_data) { - struct connman_element *element = data; - DBusMessage *reply; - DBusMessageIter array, dict; - const char *str; - - DBG("conn %p", conn); - - reply = dbus_message_new_method_return(msg); - if (reply == NULL) - return NULL; - - dbus_message_iter_init_append(reply, &array); - - dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, - DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING - DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING - DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - - str = subtype2string(element->subtype); - if (str != NULL) - connman_dbus_dict_append_variant(&dict, "Type", - DBUS_TYPE_STRING, &str); + struct foreach_data data = { type, callback, user_data }; + GNode *node; - add_common_properties(element, &dict); + DBG(""); - dbus_message_iter_close_container(&array, &dict); + if (element != NULL) { + node = g_node_find(element_root, G_PRE_ORDER, + G_TRAVERSE_ALL, element); + if (node == NULL) + return; + } else + node = element_root; - return reply; + g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, + foreach_callback, &data); } -static GDBusMethodTable device_methods[] = { - { "GetProperties", "", "a{sv}", device_get_properties }, - { "SetProperty", "sv", "", device_set_property }, - { "CreateNetwork", "a{sv}", "o", device_create_network }, - { "RemoveNetwork", "o", "", device_remove_network }, - { "ProposeScan", "", "", do_update }, - { }, -}; - -static GDBusMethodTable network_methods[] = { - { "GetProperties", "", "a{sv}", network_get_properties }, - { "SetProperty", "sv", "", network_set_property }, - { "Connect", "", "", do_enable }, - { "Disconnect", "", "", do_disable }, - { }, -}; - -static GDBusMethodTable connection_methods[] = { - { "GetProperties", "", "a{sv}", connection_get_properties }, - { }, -}; - -static GDBusSignalTable element_signals[] = { - { "PropertyChanged", "sv" }, - { }, -}; - struct append_filter { enum connman_element_type type; DBusMessageIter *iter; @@ -759,7 +577,11 @@ static gboolean append_path(GNode *node, gpointer user_data) return FALSE; if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE && - element->subtype == CONNMAN_ELEMENT_SUBTYPE_NETWORK) + __connman_device_has_driver(element->device) == FALSE) + 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, @@ -930,6 +752,9 @@ int connman_driver_register(struct connman_driver *driver) driver_list = g_slist_insert_sorted(driver_list, driver, compare_priority); + if (started == FALSE) + return 0; + if (element_root != NULL) g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, probe_driver, driver); @@ -1064,6 +889,8 @@ 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) { + if (element->destruct) + element->destruct(element); free_properties(element); g_free(element->ipv4.address); g_free(element->ipv4.netmask); @@ -1072,6 +899,7 @@ void connman_element_unref(struct connman_element *element) g_free(element->ipv4.broadcast); g_free(element->ipv4.nameserver); g_free(element->devname); + g_free(element->devpath); g_free(element->path); g_free(element->name); g_free(element); @@ -1128,11 +956,8 @@ static void emit_property_changed(DBusConnection *conn, DBG("conn %p", conn); switch (element->type) { - case CONNMAN_ELEMENT_TYPE_DEVICE: - iface = CONNMAN_DEVICE_INTERFACE; - break; - case CONNMAN_ELEMENT_TYPE_NETWORK: - iface = CONNMAN_NETWORK_INTERFACE; + case CONNMAN_ELEMENT_TYPE_CONNECTION: + iface = CONNMAN_CONNECTION_INTERFACE; break; default: return; @@ -1428,6 +1253,12 @@ int connman_element_set_property(struct connman_element *element, element->ipv4.gateway = g_strdup(*((const char **) value)); __connman_element_unlock(element); break; + case CONNMAN_PROPERTY_ID_IPV4_BROADCAST: + __connman_element_lock(element); + g_free(element->ipv4.broadcast); + element->ipv4.broadcast = g_strdup(*((const char **) value)); + __connman_element_unlock(element); + break; case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER: __connman_element_lock(element); g_free(element->ipv4.nameserver); @@ -1484,6 +1315,14 @@ int connman_element_get_value(struct connman_element *element, *((char **) value) = element->ipv4.gateway; __connman_element_unlock(element); break; + case CONNMAN_PROPERTY_ID_IPV4_BROADCAST: + if (element->ipv4.broadcast == NULL) + return connman_element_get_value(element->parent, + id, value); + __connman_element_lock(element); + *((char **) value) = element->ipv4.broadcast; + __connman_element_unlock(element); + break; case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER: if (element->ipv4.nameserver == NULL) return connman_element_get_value(element->parent, @@ -1608,10 +1447,10 @@ gboolean connman_element_match_static_property(struct connman_element *element, return result; } -static void append_devices(DBusMessageIter *entry) +static void append_connections(DBusMessageIter *entry) { DBusMessageIter value, iter; - const char *key = "Devices"; + const char *key = "Connections"; dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key); @@ -1621,13 +1460,13 @@ static void append_devices(DBusMessageIter *entry) dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter); - __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &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_devices_signal(DBusConnection *conn) +static void emit_connections_signal(DBusConnection *conn) { DBusMessage *signal; DBusMessageIter entry; @@ -1641,54 +1480,25 @@ static void emit_devices_signal(DBusConnection *conn) dbus_message_iter_init_append(signal, &entry); - append_devices(&entry); - - g_dbus_send_message(conn, signal); -} - -static void emit_networks_signal(DBusConnection *conn, - struct connman_element *device) -{ - DBusMessage *signal; - DBusMessageIter entry; - - DBG("conn %p", conn); - - if (device == NULL) - return; - - signal = dbus_message_new_signal(device->path, - CONNMAN_DEVICE_INTERFACE, "PropertyChanged"); - if (signal == NULL) - return; - - dbus_message_iter_init_append(signal, &entry); - - append_networks(device, &entry); + append_connections(&entry); g_dbus_send_message(conn, signal); } -static void append_connections(DBusMessageIter *entry) +static void append_state(DBusMessageIter *entry, const char *state) { - DBusMessageIter value, iter; - const char *key = "Connections"; + DBusMessageIter value; + const char *key = "State"; 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_TYPE_STRING_AS_STRING, &value); + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state); dbus_message_iter_close_container(entry, &value); } -static void emit_connections_signal(DBusConnection *conn) +static void emit_state_change(DBusConnection *conn, const char *state) { DBusMessage *signal; DBusMessageIter entry; @@ -1702,48 +1512,54 @@ static void emit_connections_signal(DBusConnection *conn) dbus_message_iter_init_append(signal, &entry); - append_connections(&entry); + append_state(&entry, state); g_dbus_send_message(conn, signal); } -static void append_state(DBusMessageIter *entry, const char *state) +static void set_signal_strength(struct connman_element *connection) { - DBusMessageIter value; - const char *key = "State"; + struct connman_element *element = connection; - dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key); + while (element != NULL) { + if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) { + connection->strength = element->strength; + break; + } - dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT, - DBUS_TYPE_STRING_AS_STRING, &value); - dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state); - dbus_message_iter_close_container(entry, &value); + element = element->parent; + } } -static void emit_state_change(DBusConnection *conn, const char *state) +static void probe_element(struct connman_element *element) { - DBusMessage *signal; - DBusMessageIter entry; + GSList *list; - DBG("conn %p", conn); + DBG("element %p name %s", element, element->name); - signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, - CONNMAN_MANAGER_INTERFACE, "PropertyChanged"); - if (signal == NULL) - return; + for (list = driver_list; list; list = list->next) { + struct connman_driver *driver = list->data; - dbus_message_iter_init_append(signal, &entry); + if (match_driver(element, driver) == FALSE) + continue; - append_state(&entry, state); + DBG("driver %p name %s", driver, driver->name); - g_dbus_send_message(conn, signal); + if (driver->probe(element) == 0) { + __connman_element_lock(element); + element->driver = driver; + __connman_element_unlock(element); + + enable_element(element); + break; + } + } } static void register_element(gpointer data, gpointer user_data) { struct connman_element *element = data; const gchar *basepath; - GSList *list; GNode *node; __connman_element_lock(element); @@ -1770,33 +1586,8 @@ static void register_element(gpointer data, gpointer user_data) DBG("element %p path %s", element, element->path); - __connman_element_load(element); - g_node_append_data(node, element); - if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE && - element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) { - if (g_dbus_register_interface(connection, element->path, - CONNMAN_DEVICE_INTERFACE, - device_methods, element_signals, - NULL, element, NULL) == FALSE) - connman_error("Failed to register %s device", - element->path); - else - emit_devices_signal(connection); - } - - if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) { - if (g_dbus_register_interface(connection, element->path, - CONNMAN_NETWORK_INTERFACE, - network_methods, element_signals, - NULL, element, NULL) == FALSE) - connman_error("Failed to register %s network", - element->path); - else - emit_networks_signal(connection, element->parent); - } - if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) { if (g_dbus_register_interface(connection, element->path, CONNMAN_CONNECTION_INTERFACE, @@ -1805,30 +1596,18 @@ static void register_element(gpointer data, gpointer user_data) connman_error("Failed to register %s connection", element->path); else { + set_signal_strength(element); emit_connections_signal(connection); emit_state_change(connection, "online"); } } - __connman_element_store(element); - - for (list = driver_list; list; list = list->next) { - struct connman_driver *driver = list->data; - - if (match_driver(element, driver) == FALSE) - continue; - - DBG("driver %p name %s", driver, driver->name); + emit_element_signal(connection, "ElementAdded", element); - if (driver->probe(element) == 0) { - __connman_element_lock(element); - element->driver = driver; - __connman_element_unlock(element); + if (started == FALSE) + return; - enable_element(element); - break; - } - } + probe_element(element); } /** @@ -1849,8 +1628,7 @@ int connman_element_register(struct connman_element *element, if (element->devname == NULL) element->devname = g_strdup(element->name); - if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE && - element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) { + if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) { if (g_pattern_match_simple(device_filter, element->devname) == FALSE) { DBG("ignoring %s [%s] device", element->name, @@ -1891,6 +1669,9 @@ static gboolean remove_element(GNode *node, gpointer user_data) if (element == root) return FALSE; + if (node != NULL) + g_node_unlink(node); + if (element->driver) { disable_element(element); @@ -1902,33 +1683,20 @@ static gboolean remove_element(GNode *node, gpointer user_data) __connman_element_unlock(element); } - if (node != NULL) { - g_node_unlink(node); + if (node != NULL) g_node_destroy(node); - } if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) { - emit_state_change(connection, "offline"); + if (__connman_element_count(NULL, + CONNMAN_ELEMENT_TYPE_CONNECTION) == 0) + emit_state_change(connection, "offline"); emit_connections_signal(connection); g_dbus_unregister_interface(connection, element->path, CONNMAN_CONNECTION_INTERFACE); } - if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) { - emit_networks_signal(connection, element->parent); - - g_dbus_unregister_interface(connection, element->path, - CONNMAN_NETWORK_INTERFACE); - } - - if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE && - element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) { - emit_devices_signal(connection); - - g_dbus_unregister_interface(connection, element->path, - CONNMAN_DEVICE_INTERFACE); - } + emit_element_signal(connection, "ElementRemoved", element); connman_element_unref(element); @@ -1964,12 +1732,24 @@ void connman_element_unregister_children(struct connman_element *element) static gboolean update_element(GNode *node, gpointer user_data) { struct connman_element *element = node->data; + struct connman_element *root = user_data; DBG("element %p name %s", element, element->name); if (element->driver && element->driver->update) element->driver->update(element); + if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION && + root->type == CONNMAN_ELEMENT_TYPE_NETWORK) { + if (element->strength != root->strength) { + element->strength = root->strength; + emit_property_changed(connection, element, "Strength", + DBUS_TYPE_BYTE, &element->strength); + } + } + + emit_element_signal(connection, "ElementUpdated", element); + return FALSE; } @@ -1983,7 +1763,7 @@ void connman_element_update(struct connman_element *element) if (node != NULL) g_node_traverse(node, G_PRE_ORDER, - G_TRAVERSE_ALL, -1, update_element, NULL); + G_TRAVERSE_ALL, -1, update_element, element); } int connman_element_set_enabled(struct connman_element *element, @@ -2021,10 +1801,48 @@ int __connman_element_init(DBusConnection *conn, const char *device) element_root = g_node_new(element); __connman_device_init(); + __connman_network_init(); + __connman_connection_init(); return 0; } +static gboolean probe_node(GNode *node, gpointer data) +{ + struct connman_element *element = node->data; + + DBG("element %p name %s", element, element->name); + + if (element->type == CONNMAN_ELEMENT_TYPE_ROOT) + return FALSE; + + if (element->driver) + return FALSE; + + probe_element(element); + + return FALSE; +} + +void __connman_element_start(void) +{ + DBG(""); + + g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, + probe_node, NULL); + + started = TRUE; + + __connman_detect_init(); +} + +void __connman_element_stop(void) +{ + DBG(""); + + __connman_detect_cleanup(); +} + static gboolean free_driver(GNode *node, gpointer data) { struct connman_element *element = node->data; @@ -2061,6 +1879,8 @@ void __connman_element_cleanup(void) { DBG(""); + __connman_connection_cleanup(); + __connman_network_cleanup(); __connman_device_cleanup(); g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,