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 static const char *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 = 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 = 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 gboolean probe_driver(GNode *node, gpointer data)
800 struct connman_element *element = node->data;
801 struct connman_driver *driver = data;
803 DBG("element %p name %s", element, element->name);
805 if (!element->driver && match_driver(element, driver) == TRUE) {
806 if (driver->probe(element) < 0)
809 __connman_element_lock(element);
810 element->driver = driver;
811 __connman_element_unlock(element);
817 void __connman_driver_rescan(struct connman_driver *driver)
819 DBG("driver %p name %s", driver, driver->name);
824 g_static_rw_lock_writer_lock(&element_lock);
826 if (element_root != NULL)
827 g_node_traverse(element_root, G_PRE_ORDER,
828 G_TRAVERSE_ALL, -1, probe_driver, driver);
830 g_static_rw_lock_writer_unlock(&element_lock);
834 * connman_driver_register:
835 * @driver: driver definition
837 * Register a new driver
839 * Returns: %0 on success
841 int connman_driver_register(struct connman_driver *driver)
843 DBG("driver %p name %s", driver, driver->name);
845 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
851 g_static_rw_lock_writer_lock(&element_lock);
853 driver_list = g_slist_insert_sorted(driver_list, driver,
856 if (element_root != NULL)
857 g_node_traverse(element_root, G_PRE_ORDER,
858 G_TRAVERSE_ALL, -1, probe_driver, driver);
860 g_static_rw_lock_writer_unlock(&element_lock);
865 static gboolean remove_driver(GNode *node, gpointer data)
867 struct connman_element *element = node->data;
868 struct connman_driver *driver = data;
870 DBG("element %p name %s", element, element->name);
872 if (element->driver == driver) {
874 driver->remove(element);
876 __connman_element_lock(element);
877 element->driver = NULL;
878 __connman_element_unlock(element);
885 * connman_driver_unregister:
886 * @driver: driver definition
888 * Remove a previously registered driver
890 void connman_driver_unregister(struct connman_driver *driver)
892 DBG("driver %p name %s", driver, driver->name);
894 g_static_rw_lock_writer_lock(&element_lock);
896 driver_list = g_slist_remove(driver_list, driver);
898 if (element_root != NULL)
899 g_node_traverse(element_root, G_POST_ORDER,
900 G_TRAVERSE_ALL, -1, remove_driver, driver);
902 g_static_rw_lock_writer_unlock(&element_lock);
906 * connman_element_create:
907 * @name: element name
909 * Allocate a new element and assign the given #name to it. If the name
910 * is #NULL, it will be later on created based on the element type.
912 * Returns: a newly-allocated #connman_element structure
914 struct connman_element *connman_element_create(const char *name)
916 struct connman_element *element;
918 element = g_try_new0(struct connman_element, 1);
922 DBG("element %p", element);
924 element->refcount = 1;
926 element->name = g_strdup(name);
927 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
928 element->subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
929 element->state = CONNMAN_ELEMENT_STATE_CLOSED;
930 element->policy = CONNMAN_ELEMENT_POLICY_AUTO;
932 element->enabled = FALSE;
937 struct connman_element *connman_element_ref(struct connman_element *element)
939 DBG("element %p name %s refcount %d", element, element->name,
940 g_atomic_int_get(&element->refcount) + 1);
942 g_atomic_int_inc(&element->refcount);
947 static void free_properties(struct connman_element *element)
951 DBG("element %p name %s", element, element->name);
953 __connman_element_lock(element);
955 for (list = element->properties; list; list = list->next) {
956 struct connman_property *property = list->data;
958 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
959 g_free(property->value);
961 g_free(property->name);
965 g_slist_free(element->properties);
967 element->properties = NULL;
969 __connman_element_unlock(element);
972 void connman_element_unref(struct connman_element *element)
974 DBG("element %p name %s refcount %d", element, element->name,
975 g_atomic_int_get(&element->refcount) - 1);
977 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
978 free_properties(element);
979 g_free(element->ipv4.address);
980 g_free(element->ipv4.netmask);
981 g_free(element->ipv4.gateway);
982 g_free(element->ipv4.network);
983 g_free(element->ipv4.broadcast);
984 g_free(element->ipv4.nameserver);
985 g_free(element->path);
986 g_free(element->name);
991 int connman_element_add_static_property(struct connman_element *element,
992 const char *name, int type, const void *value)
994 struct connman_property *property;
996 DBG("element %p name %s", element, element->name);
998 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE &&
999 type != DBUS_TYPE_INT32)
1002 property = g_try_new0(struct connman_property, 1);
1003 if (property == NULL)
1006 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1007 property->id = CONNMAN_PROPERTY_ID_INVALID;
1008 property->name = g_strdup(name);
1009 property->type = type;
1011 DBG("name %s type %d value %p", name, type, value);
1014 case DBUS_TYPE_STRING:
1015 property->value = g_strdup(*((const char **) value));
1017 case DBUS_TYPE_BYTE:
1018 property->value = g_try_malloc(1);
1019 if (property->value != NULL)
1020 memcpy(property->value, value, 1);
1022 case DBUS_TYPE_INT32:
1023 property->value = g_try_malloc(sizeof(gint32));
1024 if (property->value != NULL)
1025 memcpy(property->value, value, sizeof(gint32));
1029 __connman_element_lock(element);
1030 element->properties = g_slist_append(element->properties, property);
1031 __connman_element_unlock(element);
1036 int connman_element_add_static_array_property(struct connman_element *element,
1037 const char *name, int type, const void *value, int len)
1039 struct connman_property *property;
1041 DBG("element %p name %s", element, element->name);
1043 if (type != DBUS_TYPE_BYTE)
1046 property = g_try_new0(struct connman_property, 1);
1047 if (property == NULL)
1050 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1051 property->id = CONNMAN_PROPERTY_ID_INVALID;
1052 property->name = g_strdup(name);
1053 property->type = DBUS_TYPE_ARRAY;
1054 property->subtype = type;
1056 DBG("name %s type %d value %p", name, type, value);
1059 case DBUS_TYPE_BYTE:
1060 property->value = g_try_malloc(len);
1061 if (property->value != NULL) {
1062 memcpy(property->value,
1063 *((const unsigned char **) value), len);
1064 property->size = len;
1069 __connman_element_lock(element);
1070 element->properties = g_slist_append(element->properties, property);
1071 __connman_element_unlock(element);
1076 static void *get_reference_value(struct connman_element *element,
1077 enum connman_property_id id)
1081 DBG("element %p name %s", element, element->name);
1083 for (list = element->properties; list; list = list->next) {
1084 struct connman_property *property = list->data;
1086 if (property->id != id)
1089 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1090 return property->value;
1093 if (element->parent == NULL)
1096 return get_reference_value(element->parent, id);
1099 static void set_reference_properties(struct connman_element *element)
1103 DBG("element %p name %s", element, element->name);
1105 for (list = element->properties; list; list = list->next) {
1106 struct connman_property *property = list->data;
1108 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1111 property->value = get_reference_value(element->parent,
1116 static struct connman_property *create_property(struct connman_element *element,
1117 enum connman_property_id id)
1119 struct connman_property *property;
1122 DBG("element %p name %s", element, element->name);
1124 __connman_element_lock(element);
1126 for (list = element->properties; list; list = list->next) {
1127 property = list->data;
1129 if (property->id == id)
1133 property = g_try_new0(struct connman_property, 1);
1134 if (property == NULL)
1137 property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
1139 property->name = g_strdup(propid2name(id));
1140 property->type = propid2type(id);
1142 if (property->name == NULL) {
1148 element->properties = g_slist_append(element->properties, property);
1151 __connman_element_unlock(element);
1156 static void create_default_properties(struct connman_element *element)
1158 struct connman_property *property;
1161 DBG("element %p name %s", element, element->name);
1163 for (i = 0; propid_table[i].name; i++) {
1164 DBG("property %s", propid_table[i].name);
1166 property = create_property(element, propid_table[i].id);
1168 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
1170 if (propid_table[i].type != DBUS_TYPE_STRING)
1173 if (propid_table[i].value)
1174 property->value = g_strdup(propid_table[i].value);
1176 property->value = g_strdup("");
1180 static int define_properties_valist(struct connman_element *element,
1183 enum connman_property_id id;
1185 DBG("element %p name %s", element, element->name);
1187 id = va_arg(args, enum connman_property_id);
1189 while (id != CONNMAN_PROPERTY_ID_INVALID) {
1191 DBG("property %d", id);
1193 create_property(element, id);
1195 id = va_arg(args, enum connman_property_id);
1202 * connman_element_define_properties:
1203 * @element: an element
1204 * @varargs: list of property identifiers
1206 * Define the valid properties for an element.
1208 * Returns: %0 on success
1210 int connman_element_define_properties(struct connman_element *element, ...)
1215 DBG("element %p name %s", element, element->name);
1217 va_start(args, element);
1219 err = define_properties_valist(element, args);
1226 int connman_element_create_property(struct connman_element *element,
1227 const char *name, int type)
1232 int connman_element_set_property(struct connman_element *element,
1233 enum connman_property_id id, const void *value)
1236 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1237 __connman_element_lock(element);
1238 g_free(element->ipv4.address);
1239 element->ipv4.address = g_strdup(*((const char **) value));
1240 __connman_element_unlock(element);
1242 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1243 __connman_element_lock(element);
1244 g_free(element->ipv4.netmask);
1245 element->ipv4.netmask = g_strdup(*((const char **) value));
1246 __connman_element_unlock(element);
1248 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1249 __connman_element_lock(element);
1250 g_free(element->ipv4.gateway);
1251 element->ipv4.gateway = g_strdup(*((const char **) value));
1252 __connman_element_unlock(element);
1254 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1255 __connman_element_lock(element);
1256 g_free(element->ipv4.nameserver);
1257 element->ipv4.nameserver = g_strdup(*((const char **) value));
1258 __connman_element_unlock(element);
1260 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1261 __connman_element_lock(element);
1262 g_free(element->wifi.security);
1263 element->wifi.security = g_strdup(*((const char **) value));
1264 __connman_element_unlock(element);
1266 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1267 __connman_element_lock(element);
1268 g_free(element->wifi.passphrase);
1269 element->wifi.passphrase = g_strdup(*((const char **) value));
1270 __connman_element_unlock(element);
1277 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1278 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1279 DBUS_TYPE_OBJECT_PATH, &element->path,
1286 int connman_element_get_value(struct connman_element *element,
1287 enum connman_property_id id, void *value)
1289 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1293 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1294 if (element->ipv4.address == NULL)
1295 return connman_element_get_value(element->parent,
1297 __connman_element_lock(element);
1298 *((char **) value) = element->ipv4.address;
1299 __connman_element_unlock(element);
1301 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1302 if (element->ipv4.netmask == NULL)
1303 return connman_element_get_value(element->parent,
1305 __connman_element_lock(element);
1306 *((char **) value) = element->ipv4.netmask;
1307 __connman_element_unlock(element);
1309 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1310 if (element->ipv4.gateway == NULL)
1311 return connman_element_get_value(element->parent,
1313 __connman_element_lock(element);
1314 *((char **) value) = element->ipv4.gateway;
1315 __connman_element_unlock(element);
1317 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1318 if (element->ipv4.nameserver == NULL)
1319 return connman_element_get_value(element->parent,
1321 __connman_element_lock(element);
1322 *((char **) value) = element->ipv4.nameserver;
1323 __connman_element_unlock(element);
1325 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1326 if (element->wifi.security == NULL)
1327 return connman_element_get_value(element->parent,
1329 __connman_element_lock(element);
1330 *((char **) value) = element->wifi.security;
1331 __connman_element_unlock(element);
1333 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1334 if (element->wifi.passphrase == NULL)
1335 return connman_element_get_value(element->parent,
1337 __connman_element_lock(element);
1338 *((char **) value) = element->wifi.passphrase;
1339 __connman_element_unlock(element);
1348 gboolean connman_element_get_static_property(struct connman_element *element,
1349 const char *name, void *value)
1352 gboolean found = FALSE;
1354 DBG("element %p name %s", element, element->name);
1356 __connman_element_lock(element);
1358 for (list = element->properties; list; list = list->next) {
1359 struct connman_property *property = list->data;
1361 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1364 if (g_str_equal(property->name, name) == TRUE) {
1365 switch (property->type) {
1366 case DBUS_TYPE_STRING:
1367 *((char **) value) = property->value;
1369 case DBUS_TYPE_BYTE:
1370 *((guint8 *) value) = *((guint8 *) property->value);
1372 case DBUS_TYPE_INT32:
1373 *((gint32 *) value) = *((gint32 *) property->value);
1381 __connman_element_unlock(element);
1386 gboolean connman_element_get_static_array_property(struct connman_element *element,
1387 const char *name, void *value, int *len)
1390 gboolean found = FALSE;
1392 DBG("element %p name %s", element, element->name);
1394 __connman_element_lock(element);
1396 for (list = element->properties; list; list = list->next) {
1397 struct connman_property *property = list->data;
1399 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1402 if (g_str_equal(property->name, name) == TRUE) {
1403 *((char **) value) = property->value;
1404 *len = property->size;
1410 __connman_element_unlock(element);
1415 gboolean connman_element_match_static_property(struct connman_element *element,
1416 const char *name, const void *value)
1419 gboolean result = FALSE;
1421 DBG("element %p name %s", element, element->name);
1423 __connman_element_lock(element);
1425 for (list = element->properties; list; list = list->next) {
1426 struct connman_property *property = list->data;
1428 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1431 if (g_str_equal(property->name, name) == FALSE)
1434 if (property->type == DBUS_TYPE_STRING)
1435 result = g_str_equal(property->value,
1436 *((const char **) value));
1442 __connman_element_unlock(element);
1447 static void append_devices(DBusMessageIter *entry)
1449 DBusMessageIter value, iter;
1450 const char *key = "Devices";
1452 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1454 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1455 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1458 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1459 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1461 __connman_element_list(CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
1463 dbus_message_iter_close_container(&value, &iter);
1465 dbus_message_iter_close_container(entry, &value);
1468 static void emit_devices_signal(DBusConnection *conn)
1470 DBusMessage *signal;
1471 DBusMessageIter entry;
1473 DBG("conn %p", conn);
1475 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1476 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1480 dbus_message_iter_init_append(signal, &entry);
1482 append_devices(&entry);
1484 g_dbus_send_message(conn, signal);
1487 static void append_connections(DBusMessageIter *entry)
1489 DBusMessageIter value, iter;
1490 const char *key = "Connections";
1492 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1494 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1495 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1498 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1499 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1501 __connman_element_list(CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
1503 dbus_message_iter_close_container(&value, &iter);
1505 dbus_message_iter_close_container(entry, &value);
1508 static void emit_connections_signal(DBusConnection *conn)
1510 DBusMessage *signal;
1511 DBusMessageIter entry;
1513 DBG("conn %p", conn);
1515 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1516 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1520 dbus_message_iter_init_append(signal, &entry);
1522 append_connections(&entry);
1524 g_dbus_send_message(conn, signal);
1527 static void append_state(DBusMessageIter *entry, const char *state)
1529 DBusMessageIter value;
1530 const char *key = "State";
1532 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1534 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1535 DBUS_TYPE_STRING_AS_STRING, &value);
1537 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1539 dbus_message_iter_close_container(entry, &value);
1542 static void emit_state_change(DBusConnection *conn, const char *state)
1544 DBusMessage *signal;
1545 DBusMessageIter entry;
1547 DBG("conn %p", conn);
1549 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1550 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1554 dbus_message_iter_init_append(signal, &entry);
1556 append_state(&entry, state);
1558 g_dbus_send_message(conn, signal);
1561 static void register_element(gpointer data, gpointer user_data)
1563 struct connman_element *element = data;
1564 const gchar *basepath;
1568 g_static_rw_lock_writer_lock(&element_lock);
1570 __connman_element_lock(element);
1572 if (element->parent) {
1573 node = g_node_find(element_root, G_PRE_ORDER,
1574 G_TRAVERSE_ALL, element->parent);
1575 basepath = element->parent->path;
1577 if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
1578 element->subtype = element->parent->subtype;
1580 element->parent = element_root->data;
1582 node = element_root;
1586 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1588 set_reference_properties(element);
1590 __connman_element_unlock(element);
1592 DBG("element %p path %s", element, element->path);
1594 __connman_element_load(element);
1596 g_node_append_data(node, element);
1599 if (g_dbus_register_interface(connection, element->path,
1600 CONNMAN_ELEMENT_INTERFACE,
1601 element_methods, element_signals,
1602 NULL, element, NULL) == FALSE)
1603 connman_error("Failed to register %s element", element->path);
1606 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1607 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1608 if (g_dbus_register_interface(connection, element->path,
1609 CONNMAN_DEVICE_INTERFACE,
1610 device_methods, element_signals,
1611 NULL, element, NULL) == FALSE)
1612 connman_error("Failed to register %s device",
1615 emit_devices_signal(connection);
1618 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1619 if (g_dbus_register_interface(connection, element->path,
1620 CONNMAN_NETWORK_INTERFACE,
1621 network_methods, element_signals,
1622 NULL, element, NULL) == FALSE)
1623 connman_error("Failed to register %s network",
1627 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1628 if (g_dbus_register_interface(connection, element->path,
1629 CONNMAN_CONNECTION_INTERFACE,
1630 connection_methods, element_signals,
1631 NULL, element, NULL) == FALSE)
1632 connman_error("Failed to register %s connection",
1635 emit_connections_signal(connection);
1636 emit_state_change(connection, "online");
1641 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1642 CONNMAN_MANAGER_INTERFACE, "ElementAdded",
1643 DBUS_TYPE_OBJECT_PATH, &element->path,
1647 g_static_rw_lock_writer_unlock(&element_lock);
1649 __connman_element_store(element);
1651 g_static_rw_lock_writer_lock(&element_lock);
1653 for (list = driver_list; list; list = list->next) {
1654 struct connman_driver *driver = list->data;
1656 if (match_driver(element, driver) == FALSE)
1659 DBG("driver %p name %s", driver, driver->name);
1661 if (driver->probe(element) == 0) {
1662 __connman_element_lock(element);
1663 element->driver = driver;
1664 __connman_element_unlock(element);
1669 g_static_rw_lock_writer_unlock(&element_lock);
1673 * connman_element_register:
1674 * @element: the element to register
1675 * @parent: the parent to register the element with
1677 * Register an element with the core. It will be register under the given
1678 * parent of if %NULL is provided under the root element.
1680 * Returns: %0 on success
1682 int connman_element_register(struct connman_element *element,
1683 struct connman_element *parent)
1685 DBG("element %p name %s parent %p", element, element->name, parent);
1687 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1688 if (g_pattern_match_simple(device_filter,
1689 element->name) == FALSE) {
1690 DBG("ignoring %s device", element->name);
1695 if (connman_element_ref(element) == NULL)
1698 __connman_element_lock(element);
1700 if (element->name == NULL) {
1701 element->name = g_strdup(type2string(element->type));
1702 if (element->name == NULL) {
1703 __connman_element_unlock(element);
1708 element->parent = parent;
1710 __connman_element_unlock(element);
1712 register_element(element, NULL);
1717 static gboolean remove_element(GNode *node, gpointer user_data)
1719 struct connman_element *element = node->data;
1720 struct connman_element *root = user_data;
1722 DBG("element %p name %s", element, element->name);
1724 if (element == root)
1727 if (element->driver) {
1728 if (element->driver->remove)
1729 element->driver->remove(element);
1731 __connman_element_lock(element);
1732 element->driver = NULL;
1733 __connman_element_unlock(element);
1737 g_node_unlink(node);
1738 g_node_destroy(node);
1742 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1743 CONNMAN_MANAGER_INTERFACE, "ElementRemoved",
1744 DBUS_TYPE_OBJECT_PATH, &element->path,
1748 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1749 emit_state_change(connection, "offline");
1750 emit_connections_signal(connection);
1752 g_dbus_unregister_interface(connection, element->path,
1753 CONNMAN_CONNECTION_INTERFACE);
1756 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK)
1757 g_dbus_unregister_interface(connection, element->path,
1758 CONNMAN_NETWORK_INTERFACE);
1760 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1761 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1762 emit_devices_signal(connection);
1764 g_dbus_unregister_interface(connection, element->path,
1765 CONNMAN_DEVICE_INTERFACE);
1769 g_dbus_unregister_interface(connection, element->path,
1770 CONNMAN_ELEMENT_INTERFACE);
1773 connman_element_unref(element);
1778 static void unregister_element(gpointer data, gpointer user_data)
1780 struct connman_element *element = data;
1783 DBG("element %p name %s", element, element->name);
1785 g_static_rw_lock_writer_lock(&element_lock);
1787 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1790 g_node_traverse(node, G_POST_ORDER,
1791 G_TRAVERSE_ALL, -1, remove_element, NULL);
1793 g_static_rw_lock_writer_unlock(&element_lock);
1796 void connman_element_unregister(struct connman_element *element)
1798 DBG("element %p name %s", element, element->name);
1800 unregister_element(element, NULL);
1803 static void unregister_children(gpointer data, gpointer user_data)
1805 struct connman_element *element = data;
1808 DBG("element %p name %s", element, element->name);
1810 g_static_rw_lock_writer_lock(&element_lock);
1812 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1815 g_node_traverse(node, G_POST_ORDER,
1816 G_TRAVERSE_ALL, -1, remove_element, element);
1818 g_static_rw_lock_writer_unlock(&element_lock);
1821 void connman_element_unregister_children(struct connman_element *element)
1823 DBG("element %p name %s", element, element->name);
1825 unregister_children(element, NULL);
1828 static gboolean update_element(GNode *node, gpointer user_data)
1830 struct connman_element *element = node->data;
1832 DBG("element %p name %s", element, element->name);
1834 if (element->driver && element->driver->update)
1835 element->driver->update(element);
1838 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1839 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1840 DBUS_TYPE_OBJECT_PATH, &element->path,
1847 void connman_element_update(struct connman_element *element)
1851 DBG("element %p name %s", element, element->name);
1853 g_static_rw_lock_reader_lock(&element_lock);
1855 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1858 g_node_traverse(node, G_PRE_ORDER,
1859 G_TRAVERSE_ALL, -1, update_element, NULL);
1861 g_static_rw_lock_reader_unlock(&element_lock);
1864 int connman_element_set_enabled(struct connman_element *element,
1867 if (element->enabled == enabled)
1870 element->enabled = enabled;
1872 connman_element_update(element);
1877 int __connman_element_init(DBusConnection *conn, const char *device)
1879 struct connman_element *element;
1881 DBG("conn %p", conn);
1883 connection = dbus_connection_ref(conn);
1884 if (connection == NULL)
1887 device_filter = g_strdup(device);
1889 g_static_rw_lock_writer_lock(&element_lock);
1891 element = connman_element_create("root");
1893 element->path = g_strdup("/");
1894 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1896 create_default_properties(element);
1898 element_root = g_node_new(element);
1900 g_static_rw_lock_writer_unlock(&element_lock);
1902 __connman_device_init();
1907 static gboolean free_driver(GNode *node, gpointer data)
1909 struct connman_element *element = node->data;
1911 DBG("element %p name %s", element, element->name);
1913 if (element->driver) {
1914 if (element->driver->remove)
1915 element->driver->remove(element);
1917 __connman_element_lock(element);
1918 element->driver = NULL;
1919 __connman_element_unlock(element);
1925 static gboolean free_node(GNode *node, gpointer data)
1927 struct connman_element *element = node->data;
1929 DBG("element %p name %s", element, element->name);
1931 if (g_node_depth(node) > 1)
1932 unregister_element(element, NULL);
1937 void __connman_element_cleanup(void)
1941 __connman_device_cleanup();
1943 g_static_rw_lock_writer_lock(&element_lock);
1944 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1946 g_static_rw_lock_writer_unlock(&element_lock);
1948 g_static_rw_lock_writer_lock(&element_lock);
1949 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1951 g_static_rw_lock_writer_unlock(&element_lock);
1953 g_static_rw_lock_writer_lock(&element_lock);
1954 g_node_destroy(element_root);
1955 element_root = NULL;
1956 g_static_rw_lock_writer_unlock(&element_lock);
1958 g_free(device_filter);
1960 dbus_connection_unref(connection);