5 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
35 static DBusConnection *connection;
37 static GStaticRWLock element_lock = G_STATIC_RW_LOCK_INIT;
38 static GNode *element_root = NULL;
40 static GSList *driver_list = NULL;
42 static gchar *device_filter = NULL;
45 enum connman_property_id id;
50 { CONNMAN_PROPERTY_ID_IPV4_METHOD,
51 DBUS_TYPE_STRING, "IPv4.Method", "dhcp" },
52 { CONNMAN_PROPERTY_ID_IPV4_ADDRESS,
53 DBUS_TYPE_STRING, "IPv4.Address" },
54 { CONNMAN_PROPERTY_ID_IPV4_NETMASK,
55 DBUS_TYPE_STRING, "IPv4.Netmask" },
56 { CONNMAN_PROPERTY_ID_IPV4_GATEWAY,
57 DBUS_TYPE_STRING, "IPv4.Gateway" },
58 { CONNMAN_PROPERTY_ID_IPV4_NAMESERVER,
59 DBUS_TYPE_STRING, "IPv4.Nameserver" },
61 { CONNMAN_PROPERTY_ID_WIFI_SECURITY,
62 DBUS_TYPE_STRING, "WiFi.Security" },
63 { CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE,
64 DBUS_TYPE_STRING, "WiFi.Passphrase" },
69 static int propid2type(enum connman_property_id id)
73 for (i = 0; propid_table[i].name; i++) {
74 if (propid_table[i].id == id)
75 return propid_table[i].type;
78 return DBUS_TYPE_INVALID;
81 static const char *propid2name(enum connman_property_id id)
85 for (i = 0; propid_table[i].name; i++) {
86 if (propid_table[i].id == id)
87 return propid_table[i].name;
93 static const char *type2string(enum connman_element_type type)
96 case CONNMAN_ELEMENT_TYPE_UNKNOWN:
98 case CONNMAN_ELEMENT_TYPE_ROOT:
100 case CONNMAN_ELEMENT_TYPE_PROFILE:
102 case CONNMAN_ELEMENT_TYPE_DEVICE:
104 case CONNMAN_ELEMENT_TYPE_NETWORK:
106 case CONNMAN_ELEMENT_TYPE_SERVICE:
108 case CONNMAN_ELEMENT_TYPE_IPV4:
110 case CONNMAN_ELEMENT_TYPE_IPV6:
112 case CONNMAN_ELEMENT_TYPE_DHCP:
114 case CONNMAN_ELEMENT_TYPE_BOOTP:
116 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
118 case CONNMAN_ELEMENT_TYPE_RESOLVER:
120 case CONNMAN_ELEMENT_TYPE_CONNECTION:
127 static const char *subtype2string(enum connman_element_subtype type)
130 case CONNMAN_ELEMENT_SUBTYPE_UNKNOWN:
132 case CONNMAN_ELEMENT_SUBTYPE_FAKE:
134 case CONNMAN_ELEMENT_SUBTYPE_NETWORK:
136 case CONNMAN_ELEMENT_SUBTYPE_ETHERNET:
138 case CONNMAN_ELEMENT_SUBTYPE_WIFI:
140 case CONNMAN_ELEMENT_SUBTYPE_WIMAX:
142 case CONNMAN_ELEMENT_SUBTYPE_MODEM:
144 case CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH:
151 const char *__connman_element_policy2string(enum connman_element_policy policy)
154 case CONNMAN_ELEMENT_POLICY_UNKNOWN:
156 case CONNMAN_ELEMENT_POLICY_OFF:
158 case CONNMAN_ELEMENT_POLICY_AUTO:
160 case CONNMAN_ELEMENT_POLICY_IGNORE:
162 case CONNMAN_ELEMENT_POLICY_ASK:
169 static void append_property(DBusMessageIter *dict,
170 struct connman_property *property)
172 if (property->value == NULL)
175 if (property->type == DBUS_TYPE_ARRAY)
176 connman_dbus_dict_append_array(dict, property->name,
177 property->subtype, &property->value, property->size);
179 connman_dbus_dict_append_variant(dict, property->name,
180 property->type, &property->value);
183 static void add_common_properties(struct connman_element *element,
184 DBusMessageIter *dict)
186 const char *address = NULL, *netmask = NULL, *gateway = NULL;
189 connman_element_get_value(element,
190 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
191 connman_element_get_value(element,
192 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
193 connman_element_get_value(element,
194 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
196 if (element->priority > 0)
197 connman_dbus_dict_append_variant(dict, "Priority",
198 DBUS_TYPE_UINT16, &element->priority);
201 connman_dbus_dict_append_variant(dict, "IPv4.Address",
202 DBUS_TYPE_STRING, &address);
204 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
205 DBUS_TYPE_STRING, &netmask);
207 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
208 DBUS_TYPE_STRING, &gateway);
210 if (element->wifi.security != NULL) {
211 const char *passphrase = "";
213 connman_dbus_dict_append_variant(dict, "WiFi.Security",
214 DBUS_TYPE_STRING, &element->wifi.security);
216 if (element->wifi.passphrase != NULL)
217 passphrase = element->wifi.passphrase;
219 connman_dbus_dict_append_variant(dict, "WiFi.Passphrase",
220 DBUS_TYPE_STRING, &passphrase);
223 __connman_element_lock(element);
225 for (list = element->properties; list; list = list->next) {
226 struct connman_property *property = list->data;
228 append_property(dict, property);
231 __connman_element_unlock(element);
234 static void set_common_property(struct connman_element *element,
235 const char *name, DBusMessageIter *value)
239 if (g_str_equal(name, "Priority") == TRUE) {
240 dbus_message_iter_get_basic(value, &element->priority);
244 __connman_element_lock(element);
246 for (list = element->properties; list; list = list->next) {
247 struct connman_property *property = list->data;
250 if (g_str_equal(property->name, name) == FALSE)
253 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
256 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
258 if (property->type == DBUS_TYPE_STRING) {
259 dbus_message_iter_get_basic(value, &str);
260 g_free(property->value);
261 property->value = g_strdup(str);
263 property->value = NULL;
266 __connman_element_unlock(element);
269 static DBusMessage *do_update(DBusConnection *conn,
270 DBusMessage *msg, void *data)
272 struct connman_element *element = data;
274 DBG("conn %p", conn);
276 if (element->enabled == FALSE)
277 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
279 if (element->driver && element->driver->update) {
280 DBG("Calling update callback");
281 element->driver->update(element);
284 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
287 static DBusMessage *do_enable(DBusConnection *conn,
288 DBusMessage *msg, void *data)
290 struct connman_element *element = data;
292 DBG("conn %p", conn);
294 if (element->enabled == TRUE)
295 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
297 if (element->driver && element->driver->enable) {
298 DBG("Calling enable callback");
299 if (element->driver->enable(element) < 0)
300 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
303 element->enabled = TRUE;
306 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
307 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
308 DBUS_TYPE_OBJECT_PATH, &element->path,
312 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
315 static DBusMessage *do_disable(DBusConnection *conn,
316 DBusMessage *msg, void *data)
318 struct connman_element *element = data;
320 DBG("conn %p", conn);
322 if (element->enabled == FALSE)
323 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
325 if (element->driver && element->driver->disable) {
326 DBG("Calling disable callback");
327 if (element->driver->disable(element) < 0)
328 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
331 element->enabled = FALSE;
334 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
335 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
336 DBUS_TYPE_OBJECT_PATH, &element->path,
340 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
343 static void append_networks(DBusMessageIter *dict)
345 DBusMessageIter entry, value, iter;
346 const char *key = "Networks";
348 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
351 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
353 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
354 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
357 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
358 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
360 __connman_element_list(CONNMAN_ELEMENT_TYPE_NETWORK, &iter);
362 dbus_message_iter_close_container(&value, &iter);
364 dbus_message_iter_close_container(&entry, &value);
366 dbus_message_iter_close_container(dict, &entry);
369 static DBusMessage *get_device_properties(DBusConnection *conn,
370 DBusMessage *msg, void *data)
372 struct connman_element *element = data;
374 DBusMessageIter array, dict;
377 DBG("conn %p", conn);
379 reply = dbus_message_new_method_return(msg);
383 dbus_message_iter_init_append(reply, &array);
385 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
386 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
387 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
388 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
390 str = subtype2string(element->subtype);
392 connman_dbus_dict_append_variant(&dict, "Type",
393 DBUS_TYPE_STRING, &str);
395 str = __connman_element_policy2string(element->policy);
397 connman_dbus_dict_append_variant(&dict, "Policy",
398 DBUS_TYPE_STRING, &str);
400 connman_dbus_dict_append_variant(&dict, "Powered",
401 DBUS_TYPE_BOOLEAN, &element->enabled);
403 append_networks(&dict);
405 add_common_properties(element, &dict);
407 dbus_message_iter_close_container(&array, &dict);
412 static DBusMessage *set_device_property(DBusConnection *conn,
413 DBusMessage *msg, void *data)
415 struct connman_element *element = data;
416 DBusMessageIter iter;
417 DBusMessageIter value;
420 DBG("conn %p", conn);
422 if (dbus_message_iter_init(msg, &iter) == FALSE)
423 return __connman_error_invalid_arguments(msg);
425 dbus_message_iter_get_basic(&iter, &name);
426 dbus_message_iter_next(&iter);
427 dbus_message_iter_recurse(&iter, &value);
429 if (__connman_security_check_privileges(msg) < 0)
430 return __connman_error_permission_denied(msg);
432 if (g_str_equal(name, "Powered") == TRUE) {
435 dbus_message_iter_get_basic(&value, &powered);
438 do_enable(conn, msg, data);
440 do_disable(conn, msg, data);
442 set_common_property(element, name, &value);
444 __connman_element_store(element);
446 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
449 static DBusMessage *get_network_properties(DBusConnection *conn,
450 DBusMessage *msg, void *data)
452 struct connman_element *element = data;
454 DBusMessageIter array, dict;
457 DBG("conn %p", conn);
459 reply = dbus_message_new_method_return(msg);
463 dbus_message_iter_init_append(reply, &array);
465 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
466 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
467 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
468 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
470 str = __connman_element_policy2string(element->policy);
472 connman_dbus_dict_append_variant(&dict, "Policy",
473 DBUS_TYPE_STRING, &str);
475 connman_dbus_dict_append_variant(&dict, "Connected",
476 DBUS_TYPE_BOOLEAN, &element->enabled);
478 add_common_properties(element, &dict);
480 dbus_message_iter_close_container(&array, &dict);
485 static DBusMessage *set_network_property(DBusConnection *conn,
486 DBusMessage *msg, void *data)
488 struct connman_element *element = data;
489 DBusMessageIter iter;
490 DBusMessageIter value;
493 DBG("conn %p", conn);
495 if (dbus_message_iter_init(msg, &iter) == FALSE)
496 return __connman_error_invalid_arguments(msg);
498 dbus_message_iter_get_basic(&iter, &name);
499 dbus_message_iter_next(&iter);
500 dbus_message_iter_recurse(&iter, &value);
502 if (__connman_security_check_privileges(msg) < 0)
503 return __connman_error_permission_denied(msg);
505 if (g_str_equal(name, "WiFi.Passphrase") == TRUE) {
508 dbus_message_iter_get_basic(&value, &str);
509 g_free(element->wifi.passphrase);
510 element->wifi.passphrase = g_strdup(str);
512 set_common_property(element, name, &value);
514 __connman_element_store(element);
516 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
519 static DBusMessage *get_connection_properties(DBusConnection *conn,
520 DBusMessage *msg, void *data)
522 struct connman_element *element = data;
524 DBusMessageIter array, dict;
526 DBG("conn %p", conn);
528 reply = dbus_message_new_method_return(msg);
532 dbus_message_iter_init_append(reply, &array);
534 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
535 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
536 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
537 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
539 add_common_properties(element, &dict);
541 dbus_message_iter_close_container(&array, &dict);
547 static DBusMessage *get_properties(DBusConnection *conn,
548 DBusMessage *msg, void *data)
550 struct connman_element *element = data;
552 DBusMessageIter array, dict;
555 DBG("conn %p", conn);
557 reply = dbus_message_new_method_return(msg);
561 dbus_message_iter_init_append(reply, &array);
563 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
564 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
565 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
566 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
568 if (element->parent != NULL &&
569 element->parent->type != CONNMAN_ELEMENT_TYPE_ROOT) {
570 connman_dbus_dict_append_variant(&dict, "Parent",
571 DBUS_TYPE_OBJECT_PATH, &element->parent->path);
574 str = type2string(element->type);
576 connman_dbus_dict_append_variant(&dict, "Type",
577 DBUS_TYPE_STRING, &str);
578 str = subtype2string(element->subtype);
580 connman_dbus_dict_append_variant(&dict, "Subtype",
581 DBUS_TYPE_STRING, &str);
583 connman_dbus_dict_append_variant(&dict, "Enabled",
584 DBUS_TYPE_BOOLEAN, &element->enabled);
586 add_common_properties(element, &dict);
588 dbus_message_iter_close_container(&array, &dict);
593 static DBusMessage *set_property(DBusConnection *conn,
594 DBusMessage *msg, void *data)
596 struct connman_element *element = data;
597 DBusMessageIter iter;
598 DBusMessageIter value;
601 DBG("conn %p", conn);
603 if (dbus_message_iter_init(msg, &iter) == FALSE)
604 return __connman_error_invalid_arguments(msg);
606 dbus_message_iter_get_basic(&iter, &name);
607 dbus_message_iter_next(&iter);
608 dbus_message_iter_recurse(&iter, &value);
610 if (__connman_security_check_privileges(msg) < 0)
611 return __connman_error_permission_denied(msg);
613 set_common_property(element, name, &value);
615 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
618 static DBusMessage *clear_property(DBusConnection *conn,
619 DBusMessage *msg, void *data)
621 struct connman_element *element = data;
625 DBG("conn %p", conn);
627 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
628 DBUS_TYPE_INVALID) == FALSE)
629 return __connman_error_invalid_arguments(msg);
631 if (__connman_security_check_privileges(msg) < 0)
632 return __connman_error_permission_denied(msg);
634 __connman_element_lock(element);
636 for (list = element->properties; list; list = list->next) {
637 struct connman_property *property = list->data;
639 if (g_str_equal(property->name, name) == FALSE)
642 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
645 if (property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE)
648 property->flags |= CONNMAN_PROPERTY_FLAG_REFERENCE;
650 if (property->type == DBUS_TYPE_STRING)
651 g_free(property->value);
653 property->value = NULL;
656 __connman_element_unlock(element);
658 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
661 static GDBusMethodTable element_methods[] = {
662 { "GetProperties", "", "a{sv}", get_properties },
663 { "SetProperty", "sv", "", set_property },
664 { "ClearProperty", "s", "", clear_property },
665 { "Update", "", "", do_update },
666 { "Enable", "", "", do_enable },
667 { "Disable", "", "", do_disable },
672 static GDBusSignalTable element_signals[] = {
673 { "PropertyChanged", "sv" },
677 static GDBusMethodTable device_methods[] = {
678 { "GetProperties", "", "a{sv}", get_device_properties },
679 { "SetProperty", "sv", "", set_device_property },
680 { "Scan", "", "", do_update },
684 static GDBusMethodTable network_methods[] = {
685 { "GetProperties", "", "a{sv}", get_network_properties },
686 { "SetProperty", "sv", "", set_network_property },
687 { "Connect", "", "", do_enable },
688 { "Disconnect", "", "", do_disable },
692 static GDBusMethodTable connection_methods[] = {
693 { "GetProperties", "", "a{sv}", get_connection_properties },
697 struct append_filter {
698 enum connman_element_type type;
699 DBusMessageIter *iter;
702 static gboolean append_path(GNode *node, gpointer user_data)
704 struct connman_element *element = node->data;
705 struct append_filter *filter = user_data;
707 DBG("element %p name %s", element, element->name);
709 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
712 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
713 filter->type != element->type)
716 dbus_message_iter_append_basic(filter->iter,
717 DBUS_TYPE_OBJECT_PATH, &element->path);
722 void __connman_element_list(enum connman_element_type type,
723 DBusMessageIter *iter)
725 struct append_filter filter = { type, iter };
729 g_static_rw_lock_reader_lock(&element_lock);
730 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
731 append_path, &filter);
732 g_static_rw_lock_reader_unlock(&element_lock);
736 enum connman_element_type type;
740 static gboolean count_element(GNode *node, gpointer user_data)
742 struct connman_element *element = node->data;
743 struct count_data *data = user_data;
745 DBG("element %p name %s", element, element->name);
747 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
750 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
751 data->type != element->type)
759 int __connman_element_count(enum connman_element_type type)
761 struct count_data data = { type, 0 };
765 g_static_rw_lock_reader_lock(&element_lock);
766 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
767 count_element, &data);
768 g_static_rw_lock_reader_unlock(&element_lock);
773 static gint compare_priority(gconstpointer a, gconstpointer b)
775 const struct connman_driver *driver1 = a;
776 const struct connman_driver *driver2 = b;
778 return driver2->priority - driver1->priority;
781 static gboolean match_driver(struct connman_element *element,
782 struct connman_driver *driver)
784 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
787 if (element->type != driver->type &&
788 driver->type != CONNMAN_ELEMENT_TYPE_UNKNOWN)
791 if (element->subtype == driver->subtype ||
792 driver->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
798 static void enable_element(struct connman_element *element)
800 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
803 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
806 if (element->driver && element->driver->enable) {
807 if (element->driver->enable(element) == 0)
808 element->enabled = TRUE;
812 static gboolean probe_driver(GNode *node, gpointer data)
814 struct connman_element *element = node->data;
815 struct connman_driver *driver = data;
817 DBG("element %p name %s", element, element->name);
819 if (!element->driver && match_driver(element, driver) == TRUE) {
820 if (driver->probe(element) < 0)
823 __connman_element_lock(element);
824 element->driver = driver;
825 __connman_element_unlock(element);
827 enable_element(element);
833 void __connman_driver_rescan(struct connman_driver *driver)
835 DBG("driver %p name %s", driver, driver->name);
840 g_static_rw_lock_writer_lock(&element_lock);
842 if (element_root != NULL)
843 g_node_traverse(element_root, G_PRE_ORDER,
844 G_TRAVERSE_ALL, -1, probe_driver, driver);
846 g_static_rw_lock_writer_unlock(&element_lock);
850 * connman_driver_register:
851 * @driver: driver definition
853 * Register a new driver
855 * Returns: %0 on success
857 int connman_driver_register(struct connman_driver *driver)
859 DBG("driver %p name %s", driver, driver->name);
861 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
867 g_static_rw_lock_writer_lock(&element_lock);
869 driver_list = g_slist_insert_sorted(driver_list, driver,
872 if (element_root != NULL)
873 g_node_traverse(element_root, G_PRE_ORDER,
874 G_TRAVERSE_ALL, -1, probe_driver, driver);
876 g_static_rw_lock_writer_unlock(&element_lock);
881 static void disable_element(struct connman_element *element)
883 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
886 if (element->enabled == FALSE)
889 if (element->driver && element->driver->disable) {
890 if (element->driver->disable(element) == 0)
891 element->enabled = FALSE;
895 static gboolean remove_driver(GNode *node, gpointer data)
897 struct connman_element *element = node->data;
898 struct connman_driver *driver = data;
900 DBG("element %p name %s", element, element->name);
902 if (element->driver == driver) {
903 disable_element(element);
906 driver->remove(element);
908 __connman_element_lock(element);
909 element->driver = NULL;
910 __connman_element_unlock(element);
917 * connman_driver_unregister:
918 * @driver: driver definition
920 * Remove a previously registered driver
922 void connman_driver_unregister(struct connman_driver *driver)
924 DBG("driver %p name %s", driver, driver->name);
926 g_static_rw_lock_writer_lock(&element_lock);
928 driver_list = g_slist_remove(driver_list, driver);
930 if (element_root != NULL)
931 g_node_traverse(element_root, G_POST_ORDER,
932 G_TRAVERSE_ALL, -1, remove_driver, driver);
934 g_static_rw_lock_writer_unlock(&element_lock);
938 * connman_element_create:
939 * @name: element name
941 * Allocate a new element and assign the given #name to it. If the name
942 * is #NULL, it will be later on created based on the element type.
944 * Returns: a newly-allocated #connman_element structure
946 struct connman_element *connman_element_create(const char *name)
948 struct connman_element *element;
950 element = g_try_new0(struct connman_element, 1);
954 DBG("element %p", element);
956 element->refcount = 1;
958 element->name = g_strdup(name);
959 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
960 element->subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
961 element->state = CONNMAN_ELEMENT_STATE_CLOSED;
962 element->policy = CONNMAN_ELEMENT_POLICY_AUTO;
964 element->enabled = FALSE;
969 struct connman_element *connman_element_ref(struct connman_element *element)
971 DBG("element %p name %s refcount %d", element, element->name,
972 g_atomic_int_get(&element->refcount) + 1);
974 g_atomic_int_inc(&element->refcount);
979 static void free_properties(struct connman_element *element)
983 DBG("element %p name %s", element, element->name);
985 __connman_element_lock(element);
987 for (list = element->properties; list; list = list->next) {
988 struct connman_property *property = list->data;
990 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
991 g_free(property->value);
993 g_free(property->name);
997 g_slist_free(element->properties);
999 element->properties = NULL;
1001 __connman_element_unlock(element);
1004 void connman_element_unref(struct connman_element *element)
1006 DBG("element %p name %s refcount %d", element, element->name,
1007 g_atomic_int_get(&element->refcount) - 1);
1009 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
1010 free_properties(element);
1011 g_free(element->ipv4.address);
1012 g_free(element->ipv4.netmask);
1013 g_free(element->ipv4.gateway);
1014 g_free(element->ipv4.network);
1015 g_free(element->ipv4.broadcast);
1016 g_free(element->ipv4.nameserver);
1017 g_free(element->path);
1018 g_free(element->name);
1023 int connman_element_add_static_property(struct connman_element *element,
1024 const char *name, int type, const void *value)
1026 struct connman_property *property;
1028 DBG("element %p name %s", element, element->name);
1030 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE &&
1031 type != DBUS_TYPE_INT32)
1034 property = g_try_new0(struct connman_property, 1);
1035 if (property == NULL)
1038 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1039 property->id = CONNMAN_PROPERTY_ID_INVALID;
1040 property->name = g_strdup(name);
1041 property->type = type;
1043 DBG("name %s type %d value %p", name, type, value);
1046 case DBUS_TYPE_STRING:
1047 property->value = g_strdup(*((const char **) value));
1049 case DBUS_TYPE_BYTE:
1050 property->value = g_try_malloc(1);
1051 if (property->value != NULL)
1052 memcpy(property->value, value, 1);
1054 case DBUS_TYPE_INT32:
1055 property->value = g_try_malloc(sizeof(gint32));
1056 if (property->value != NULL)
1057 memcpy(property->value, value, sizeof(gint32));
1061 __connman_element_lock(element);
1062 element->properties = g_slist_append(element->properties, property);
1063 __connman_element_unlock(element);
1068 int connman_element_add_static_array_property(struct connman_element *element,
1069 const char *name, int type, const void *value, int len)
1071 struct connman_property *property;
1073 DBG("element %p name %s", element, element->name);
1075 if (type != DBUS_TYPE_BYTE)
1078 property = g_try_new0(struct connman_property, 1);
1079 if (property == NULL)
1082 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1083 property->id = CONNMAN_PROPERTY_ID_INVALID;
1084 property->name = g_strdup(name);
1085 property->type = DBUS_TYPE_ARRAY;
1086 property->subtype = type;
1088 DBG("name %s type %d value %p", name, type, value);
1091 case DBUS_TYPE_BYTE:
1092 property->value = g_try_malloc(len);
1093 if (property->value != NULL) {
1094 memcpy(property->value,
1095 *((const unsigned char **) value), len);
1096 property->size = len;
1101 __connman_element_lock(element);
1102 element->properties = g_slist_append(element->properties, property);
1103 __connman_element_unlock(element);
1108 static void *get_reference_value(struct connman_element *element,
1109 enum connman_property_id id)
1113 DBG("element %p name %s", element, element->name);
1115 for (list = element->properties; list; list = list->next) {
1116 struct connman_property *property = list->data;
1118 if (property->id != id)
1121 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1122 return property->value;
1125 if (element->parent == NULL)
1128 return get_reference_value(element->parent, id);
1131 static void set_reference_properties(struct connman_element *element)
1135 DBG("element %p name %s", element, element->name);
1137 for (list = element->properties; list; list = list->next) {
1138 struct connman_property *property = list->data;
1140 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1143 property->value = get_reference_value(element->parent,
1148 static struct connman_property *create_property(struct connman_element *element,
1149 enum connman_property_id id)
1151 struct connman_property *property;
1154 DBG("element %p name %s", element, element->name);
1156 __connman_element_lock(element);
1158 for (list = element->properties; list; list = list->next) {
1159 property = list->data;
1161 if (property->id == id)
1165 property = g_try_new0(struct connman_property, 1);
1166 if (property == NULL)
1169 property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
1171 property->name = g_strdup(propid2name(id));
1172 property->type = propid2type(id);
1174 if (property->name == NULL) {
1180 element->properties = g_slist_append(element->properties, property);
1183 __connman_element_unlock(element);
1188 static void create_default_properties(struct connman_element *element)
1190 struct connman_property *property;
1193 DBG("element %p name %s", element, element->name);
1195 for (i = 0; propid_table[i].name; i++) {
1196 DBG("property %s", propid_table[i].name);
1198 property = create_property(element, propid_table[i].id);
1200 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
1202 if (propid_table[i].type != DBUS_TYPE_STRING)
1205 if (propid_table[i].value)
1206 property->value = g_strdup(propid_table[i].value);
1208 property->value = g_strdup("");
1212 static int define_properties_valist(struct connman_element *element,
1215 enum connman_property_id id;
1217 DBG("element %p name %s", element, element->name);
1219 id = va_arg(args, enum connman_property_id);
1221 while (id != CONNMAN_PROPERTY_ID_INVALID) {
1223 DBG("property %d", id);
1225 create_property(element, id);
1227 id = va_arg(args, enum connman_property_id);
1234 * connman_element_define_properties:
1235 * @element: an element
1236 * @varargs: list of property identifiers
1238 * Define the valid properties for an element.
1240 * Returns: %0 on success
1242 int connman_element_define_properties(struct connman_element *element, ...)
1247 DBG("element %p name %s", element, element->name);
1249 va_start(args, element);
1251 err = define_properties_valist(element, args);
1258 int connman_element_create_property(struct connman_element *element,
1259 const char *name, int type)
1264 int connman_element_set_property(struct connman_element *element,
1265 enum connman_property_id id, const void *value)
1268 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1269 __connman_element_lock(element);
1270 g_free(element->ipv4.address);
1271 element->ipv4.address = g_strdup(*((const char **) value));
1272 __connman_element_unlock(element);
1274 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1275 __connman_element_lock(element);
1276 g_free(element->ipv4.netmask);
1277 element->ipv4.netmask = g_strdup(*((const char **) value));
1278 __connman_element_unlock(element);
1280 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1281 __connman_element_lock(element);
1282 g_free(element->ipv4.gateway);
1283 element->ipv4.gateway = g_strdup(*((const char **) value));
1284 __connman_element_unlock(element);
1286 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1287 __connman_element_lock(element);
1288 g_free(element->ipv4.nameserver);
1289 element->ipv4.nameserver = g_strdup(*((const char **) value));
1290 __connman_element_unlock(element);
1292 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1293 __connman_element_lock(element);
1294 g_free(element->wifi.security);
1295 element->wifi.security = g_strdup(*((const char **) value));
1296 __connman_element_unlock(element);
1298 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1299 __connman_element_lock(element);
1300 g_free(element->wifi.passphrase);
1301 element->wifi.passphrase = g_strdup(*((const char **) value));
1302 __connman_element_unlock(element);
1309 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1310 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1311 DBUS_TYPE_OBJECT_PATH, &element->path,
1318 int connman_element_get_value(struct connman_element *element,
1319 enum connman_property_id id, void *value)
1321 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1325 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1326 if (element->ipv4.address == NULL)
1327 return connman_element_get_value(element->parent,
1329 __connman_element_lock(element);
1330 *((char **) value) = element->ipv4.address;
1331 __connman_element_unlock(element);
1333 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1334 if (element->ipv4.netmask == NULL)
1335 return connman_element_get_value(element->parent,
1337 __connman_element_lock(element);
1338 *((char **) value) = element->ipv4.netmask;
1339 __connman_element_unlock(element);
1341 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1342 if (element->ipv4.gateway == NULL)
1343 return connman_element_get_value(element->parent,
1345 __connman_element_lock(element);
1346 *((char **) value) = element->ipv4.gateway;
1347 __connman_element_unlock(element);
1349 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1350 if (element->ipv4.nameserver == NULL)
1351 return connman_element_get_value(element->parent,
1353 __connman_element_lock(element);
1354 *((char **) value) = element->ipv4.nameserver;
1355 __connman_element_unlock(element);
1357 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1358 if (element->wifi.security == NULL)
1359 return connman_element_get_value(element->parent,
1361 __connman_element_lock(element);
1362 *((char **) value) = element->wifi.security;
1363 __connman_element_unlock(element);
1365 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1366 if (element->wifi.passphrase == NULL)
1367 return connman_element_get_value(element->parent,
1369 __connman_element_lock(element);
1370 *((char **) value) = element->wifi.passphrase;
1371 __connman_element_unlock(element);
1380 gboolean connman_element_get_static_property(struct connman_element *element,
1381 const char *name, void *value)
1384 gboolean found = FALSE;
1386 DBG("element %p name %s", element, element->name);
1388 __connman_element_lock(element);
1390 for (list = element->properties; list; list = list->next) {
1391 struct connman_property *property = list->data;
1393 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1396 if (g_str_equal(property->name, name) == TRUE) {
1397 switch (property->type) {
1398 case DBUS_TYPE_STRING:
1399 *((char **) value) = property->value;
1401 case DBUS_TYPE_BYTE:
1402 *((guint8 *) value) = *((guint8 *) property->value);
1404 case DBUS_TYPE_INT32:
1405 *((gint32 *) value) = *((gint32 *) property->value);
1413 __connman_element_unlock(element);
1418 gboolean connman_element_get_static_array_property(struct connman_element *element,
1419 const char *name, void *value, int *len)
1422 gboolean found = FALSE;
1424 DBG("element %p name %s", element, element->name);
1426 __connman_element_lock(element);
1428 for (list = element->properties; list; list = list->next) {
1429 struct connman_property *property = list->data;
1431 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1434 if (g_str_equal(property->name, name) == TRUE) {
1435 *((char **) value) = property->value;
1436 *len = property->size;
1442 __connman_element_unlock(element);
1447 gboolean connman_element_match_static_property(struct connman_element *element,
1448 const char *name, const void *value)
1451 gboolean result = FALSE;
1453 DBG("element %p name %s", element, element->name);
1455 __connman_element_lock(element);
1457 for (list = element->properties; list; list = list->next) {
1458 struct connman_property *property = list->data;
1460 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1463 if (g_str_equal(property->name, name) == FALSE)
1466 if (property->type == DBUS_TYPE_STRING)
1467 result = g_str_equal(property->value,
1468 *((const char **) value));
1474 __connman_element_unlock(element);
1479 static void append_devices(DBusMessageIter *entry)
1481 DBusMessageIter value, iter;
1482 const char *key = "Devices";
1484 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1486 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1487 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1490 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1491 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1493 __connman_element_list(CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
1495 dbus_message_iter_close_container(&value, &iter);
1497 dbus_message_iter_close_container(entry, &value);
1500 static void emit_devices_signal(DBusConnection *conn)
1502 DBusMessage *signal;
1503 DBusMessageIter entry;
1505 DBG("conn %p", conn);
1507 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1508 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1512 dbus_message_iter_init_append(signal, &entry);
1514 append_devices(&entry);
1516 g_dbus_send_message(conn, signal);
1519 static void append_connections(DBusMessageIter *entry)
1521 DBusMessageIter value, iter;
1522 const char *key = "Connections";
1524 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1526 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1527 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1530 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1531 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1533 __connman_element_list(CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
1535 dbus_message_iter_close_container(&value, &iter);
1537 dbus_message_iter_close_container(entry, &value);
1540 static void emit_connections_signal(DBusConnection *conn)
1542 DBusMessage *signal;
1543 DBusMessageIter entry;
1545 DBG("conn %p", conn);
1547 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1548 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1552 dbus_message_iter_init_append(signal, &entry);
1554 append_connections(&entry);
1556 g_dbus_send_message(conn, signal);
1559 static void append_state(DBusMessageIter *entry, const char *state)
1561 DBusMessageIter value;
1562 const char *key = "State";
1564 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1566 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1567 DBUS_TYPE_STRING_AS_STRING, &value);
1569 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1571 dbus_message_iter_close_container(entry, &value);
1574 static void emit_state_change(DBusConnection *conn, const char *state)
1576 DBusMessage *signal;
1577 DBusMessageIter entry;
1579 DBG("conn %p", conn);
1581 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1582 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1586 dbus_message_iter_init_append(signal, &entry);
1588 append_state(&entry, state);
1590 g_dbus_send_message(conn, signal);
1593 static void register_element(gpointer data, gpointer user_data)
1595 struct connman_element *element = data;
1596 const gchar *basepath;
1600 g_static_rw_lock_writer_lock(&element_lock);
1602 __connman_element_lock(element);
1604 if (element->parent) {
1605 node = g_node_find(element_root, G_PRE_ORDER,
1606 G_TRAVERSE_ALL, element->parent);
1607 basepath = element->parent->path;
1609 if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
1610 element->subtype = element->parent->subtype;
1612 element->parent = element_root->data;
1614 node = element_root;
1618 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1620 set_reference_properties(element);
1622 __connman_element_unlock(element);
1624 DBG("element %p path %s", element, element->path);
1626 __connman_element_load(element);
1628 g_node_append_data(node, element);
1631 if (g_dbus_register_interface(connection, element->path,
1632 CONNMAN_ELEMENT_INTERFACE,
1633 element_methods, element_signals,
1634 NULL, element, NULL) == FALSE)
1635 connman_error("Failed to register %s element", element->path);
1638 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1639 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1640 if (g_dbus_register_interface(connection, element->path,
1641 CONNMAN_DEVICE_INTERFACE,
1642 device_methods, element_signals,
1643 NULL, element, NULL) == FALSE)
1644 connman_error("Failed to register %s device",
1647 emit_devices_signal(connection);
1650 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1651 if (g_dbus_register_interface(connection, element->path,
1652 CONNMAN_NETWORK_INTERFACE,
1653 network_methods, element_signals,
1654 NULL, element, NULL) == FALSE)
1655 connman_error("Failed to register %s network",
1659 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1660 if (g_dbus_register_interface(connection, element->path,
1661 CONNMAN_CONNECTION_INTERFACE,
1662 connection_methods, element_signals,
1663 NULL, element, NULL) == FALSE)
1664 connman_error("Failed to register %s connection",
1667 emit_connections_signal(connection);
1668 emit_state_change(connection, "online");
1673 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1674 CONNMAN_MANAGER_INTERFACE, "ElementAdded",
1675 DBUS_TYPE_OBJECT_PATH, &element->path,
1679 g_static_rw_lock_writer_unlock(&element_lock);
1681 __connman_element_store(element);
1683 g_static_rw_lock_writer_lock(&element_lock);
1685 for (list = driver_list; list; list = list->next) {
1686 struct connman_driver *driver = list->data;
1688 if (match_driver(element, driver) == FALSE)
1691 DBG("driver %p name %s", driver, driver->name);
1693 if (driver->probe(element) == 0) {
1694 __connman_element_lock(element);
1695 element->driver = driver;
1696 __connman_element_unlock(element);
1698 enable_element(element);
1703 g_static_rw_lock_writer_unlock(&element_lock);
1707 * connman_element_register:
1708 * @element: the element to register
1709 * @parent: the parent to register the element with
1711 * Register an element with the core. It will be register under the given
1712 * parent of if %NULL is provided under the root element.
1714 * Returns: %0 on success
1716 int connman_element_register(struct connman_element *element,
1717 struct connman_element *parent)
1719 DBG("element %p name %s parent %p", element, element->name, parent);
1721 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1722 if (g_pattern_match_simple(device_filter,
1723 element->name) == FALSE) {
1724 DBG("ignoring %s device", element->name);
1729 if (connman_element_ref(element) == NULL)
1732 __connman_element_lock(element);
1734 if (element->name == NULL) {
1735 element->name = g_strdup(type2string(element->type));
1736 if (element->name == NULL) {
1737 __connman_element_unlock(element);
1742 element->parent = parent;
1744 __connman_element_unlock(element);
1746 register_element(element, NULL);
1751 static gboolean remove_element(GNode *node, gpointer user_data)
1753 struct connman_element *element = node->data;
1754 struct connman_element *root = user_data;
1756 DBG("element %p name %s", element, element->name);
1758 if (element == root)
1761 if (element->driver) {
1762 if (element->driver->remove)
1763 element->driver->remove(element);
1765 __connman_element_lock(element);
1766 element->driver = NULL;
1767 __connman_element_unlock(element);
1771 g_node_unlink(node);
1772 g_node_destroy(node);
1776 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1777 CONNMAN_MANAGER_INTERFACE, "ElementRemoved",
1778 DBUS_TYPE_OBJECT_PATH, &element->path,
1782 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1783 emit_state_change(connection, "offline");
1784 emit_connections_signal(connection);
1786 g_dbus_unregister_interface(connection, element->path,
1787 CONNMAN_CONNECTION_INTERFACE);
1790 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK)
1791 g_dbus_unregister_interface(connection, element->path,
1792 CONNMAN_NETWORK_INTERFACE);
1794 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1795 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1796 emit_devices_signal(connection);
1798 g_dbus_unregister_interface(connection, element->path,
1799 CONNMAN_DEVICE_INTERFACE);
1803 g_dbus_unregister_interface(connection, element->path,
1804 CONNMAN_ELEMENT_INTERFACE);
1807 connman_element_unref(element);
1812 void connman_element_unregister(struct connman_element *element)
1816 DBG("element %p name %s", element, element->name);
1818 g_static_rw_lock_writer_lock(&element_lock);
1820 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1823 g_node_traverse(node, G_POST_ORDER,
1824 G_TRAVERSE_ALL, -1, remove_element, NULL);
1826 g_static_rw_lock_writer_unlock(&element_lock);
1829 void connman_element_unregister_children(struct connman_element *element)
1833 DBG("element %p name %s", element, element->name);
1835 g_static_rw_lock_writer_lock(&element_lock);
1837 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1840 g_node_traverse(node, G_POST_ORDER,
1841 G_TRAVERSE_ALL, -1, remove_element, element);
1843 g_static_rw_lock_writer_unlock(&element_lock);
1846 static gboolean update_element(GNode *node, gpointer user_data)
1848 struct connman_element *element = node->data;
1850 DBG("element %p name %s", element, element->name);
1852 if (element->driver && element->driver->update)
1853 element->driver->update(element);
1856 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1857 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1858 DBUS_TYPE_OBJECT_PATH, &element->path,
1865 void connman_element_update(struct connman_element *element)
1869 DBG("element %p name %s", element, element->name);
1871 g_static_rw_lock_reader_lock(&element_lock);
1873 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1876 g_node_traverse(node, G_PRE_ORDER,
1877 G_TRAVERSE_ALL, -1, update_element, NULL);
1879 g_static_rw_lock_reader_unlock(&element_lock);
1882 int connman_element_set_enabled(struct connman_element *element,
1885 if (element->enabled == enabled)
1888 element->enabled = enabled;
1890 connman_element_update(element);
1895 int __connman_element_init(DBusConnection *conn, const char *device)
1897 struct connman_element *element;
1899 DBG("conn %p", conn);
1901 connection = dbus_connection_ref(conn);
1902 if (connection == NULL)
1905 device_filter = g_strdup(device);
1907 g_static_rw_lock_writer_lock(&element_lock);
1909 element = connman_element_create("root");
1911 element->path = g_strdup("/");
1912 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1914 create_default_properties(element);
1916 element_root = g_node_new(element);
1918 g_static_rw_lock_writer_unlock(&element_lock);
1920 __connman_device_init();
1925 static gboolean free_driver(GNode *node, gpointer data)
1927 struct connman_element *element = node->data;
1929 DBG("element %p name %s", element, element->name);
1931 if (element->driver) {
1932 if (element->driver->remove)
1933 element->driver->remove(element);
1935 __connman_element_lock(element);
1936 element->driver = NULL;
1937 __connman_element_unlock(element);
1943 static gboolean free_node(GNode *node, gpointer data)
1945 struct connman_element *element = node->data;
1947 DBG("element %p name %s", element, element->name);
1949 if (g_node_depth(node) > 1)
1950 connman_element_unregister(element);
1955 void __connman_element_cleanup(void)
1959 __connman_device_cleanup();
1961 g_static_rw_lock_writer_lock(&element_lock);
1962 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1964 g_static_rw_lock_writer_unlock(&element_lock);
1966 g_static_rw_lock_writer_lock(&element_lock);
1967 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1969 g_static_rw_lock_writer_unlock(&element_lock);
1971 g_static_rw_lock_writer_lock(&element_lock);
1972 g_node_destroy(element_root);
1973 element_root = NULL;
1974 g_static_rw_lock_writer_unlock(&element_lock);
1976 g_free(device_filter);
1978 dbus_connection_unref(connection);