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 enum connman_element_policy __connman_element_string2policy(const char *policy)
171 if (strcasecmp(policy, "off") == 0)
172 return CONNMAN_ELEMENT_POLICY_OFF;
173 else if (strcasecmp(policy, "ignore") == 0)
174 return CONNMAN_ELEMENT_POLICY_IGNORE;
175 else if (strcasecmp(policy, "auto") == 0)
176 return CONNMAN_ELEMENT_POLICY_AUTO;
177 else if (strcasecmp(policy, "ask") == 0)
178 return CONNMAN_ELEMENT_POLICY_ASK;
180 return CONNMAN_ELEMENT_POLICY_UNKNOWN;
183 static void append_property(DBusMessageIter *dict,
184 struct connman_property *property)
186 if (property->value == NULL)
189 switch (property->type) {
190 case DBUS_TYPE_ARRAY:
191 connman_dbus_dict_append_array(dict, property->name,
192 property->subtype, &property->value, property->size);
194 case DBUS_TYPE_STRING:
195 connman_dbus_dict_append_variant(dict, property->name,
196 property->type, &property->value);
199 connman_dbus_dict_append_variant(dict, property->name,
200 property->type, property->value);
205 static void add_common_properties(struct connman_element *element,
206 DBusMessageIter *dict)
208 const char *address = NULL, *netmask = NULL, *gateway = NULL;
211 connman_element_get_value(element,
212 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
213 connman_element_get_value(element,
214 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
215 connman_element_get_value(element,
216 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
218 if (element->priority > 0)
219 connman_dbus_dict_append_variant(dict, "Priority",
220 DBUS_TYPE_UINT16, &element->priority);
223 connman_dbus_dict_append_variant(dict, "IPv4.Address",
224 DBUS_TYPE_STRING, &address);
226 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
227 DBUS_TYPE_STRING, &netmask);
229 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
230 DBUS_TYPE_STRING, &gateway);
232 if (element->wifi.security != NULL) {
233 const char *passphrase = "";
235 connman_dbus_dict_append_variant(dict, "WiFi.Security",
236 DBUS_TYPE_STRING, &element->wifi.security);
238 if (element->wifi.passphrase != NULL)
239 passphrase = element->wifi.passphrase;
241 connman_dbus_dict_append_variant(dict, "WiFi.Passphrase",
242 DBUS_TYPE_STRING, &passphrase);
245 __connman_element_lock(element);
247 for (list = element->properties; list; list = list->next) {
248 struct connman_property *property = list->data;
250 append_property(dict, property);
253 __connman_element_unlock(element);
256 static void set_common_property(struct connman_element *element,
257 const char *name, DBusMessageIter *value)
261 if (g_str_equal(name, "Priority") == TRUE) {
262 dbus_message_iter_get_basic(value, &element->priority);
266 __connman_element_lock(element);
268 for (list = element->properties; list; list = list->next) {
269 struct connman_property *property = list->data;
272 if (g_str_equal(property->name, name) == FALSE)
275 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
278 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
280 if (property->type == DBUS_TYPE_STRING) {
281 dbus_message_iter_get_basic(value, &str);
282 g_free(property->value);
283 property->value = g_strdup(str);
285 property->value = NULL;
288 __connman_element_unlock(element);
291 static DBusMessage *do_update(DBusConnection *conn,
292 DBusMessage *msg, void *data)
294 struct connman_element *element = data;
296 DBG("conn %p", conn);
298 if (element->enabled == FALSE)
299 return __connman_error_failed(msg);
301 if (element->driver && element->driver->update) {
302 DBG("Calling update callback");
303 if (element->driver->update(element) < 0)
304 return __connman_error_failed(msg);
308 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
311 static DBusMessage *do_enable(DBusConnection *conn,
312 DBusMessage *msg, void *data)
314 struct connman_element *element = data;
316 DBG("conn %p", conn);
318 if (element->enabled == TRUE)
319 return __connman_error_failed(msg);
321 if (element->driver && element->driver->enable) {
322 DBG("Calling enable callback");
323 if (element->driver->enable(element) < 0)
324 return __connman_error_failed(msg);
327 element->enabled = TRUE;
330 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
331 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
332 DBUS_TYPE_OBJECT_PATH, &element->path,
336 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
339 static DBusMessage *do_disable(DBusConnection *conn,
340 DBusMessage *msg, void *data)
342 struct connman_element *element = data;
344 DBG("conn %p", conn);
346 if (element->enabled == FALSE)
347 return __connman_error_failed(msg);
349 if (element->driver && element->driver->disable) {
350 DBG("Calling disable callback");
351 if (element->driver->disable(element) < 0)
352 return __connman_error_failed(msg);
355 element->enabled = FALSE;
358 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
359 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
360 DBUS_TYPE_OBJECT_PATH, &element->path,
364 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
367 static void append_networks(struct connman_element *element,
368 DBusMessageIter *dict)
370 DBusMessageIter entry, value, iter;
371 const char *key = "Networks";
373 if (element->subtype != CONNMAN_ELEMENT_SUBTYPE_WIFI &&
374 element->subtype != CONNMAN_ELEMENT_SUBTYPE_WIMAX)
377 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
380 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
382 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
383 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
386 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
387 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
389 __connman_element_list(element, CONNMAN_ELEMENT_TYPE_NETWORK, &iter);
391 dbus_message_iter_close_container(&value, &iter);
393 dbus_message_iter_close_container(&entry, &value);
395 dbus_message_iter_close_container(dict, &entry);
398 static DBusMessage *get_device_properties(DBusConnection *conn,
399 DBusMessage *msg, void *data)
401 struct connman_element *element = data;
403 DBusMessageIter array, dict;
406 DBG("conn %p", conn);
408 reply = dbus_message_new_method_return(msg);
412 dbus_message_iter_init_append(reply, &array);
414 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
415 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
416 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
417 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
419 str = subtype2string(element->subtype);
421 connman_dbus_dict_append_variant(&dict, "Type",
422 DBUS_TYPE_STRING, &str);
424 str = __connman_element_policy2string(element->policy);
426 connman_dbus_dict_append_variant(&dict, "Policy",
427 DBUS_TYPE_STRING, &str);
429 connman_dbus_dict_append_variant(&dict, "Powered",
430 DBUS_TYPE_BOOLEAN, &element->enabled);
432 append_networks(element, &dict);
434 add_common_properties(element, &dict);
436 dbus_message_iter_close_container(&array, &dict);
441 static DBusMessage *set_device_property(DBusConnection *conn,
442 DBusMessage *msg, void *data)
444 struct connman_element *element = data;
445 DBusMessageIter iter;
446 DBusMessageIter value;
449 DBG("conn %p", conn);
451 if (dbus_message_iter_init(msg, &iter) == FALSE)
452 return __connman_error_invalid_arguments(msg);
454 dbus_message_iter_get_basic(&iter, &name);
455 dbus_message_iter_next(&iter);
456 dbus_message_iter_recurse(&iter, &value);
458 if (__connman_security_check_privileges(msg) < 0)
459 return __connman_error_permission_denied(msg);
461 if (g_str_equal(name, "Powered") == TRUE) {
464 dbus_message_iter_get_basic(&value, &powered);
467 do_enable(conn, msg, data);
469 do_disable(conn, msg, data);
471 set_common_property(element, name, &value);
473 __connman_element_store(element);
475 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
478 static DBusMessage *get_network_properties(DBusConnection *conn,
479 DBusMessage *msg, void *data)
481 struct connman_element *element = data;
483 DBusMessageIter array, dict;
486 DBG("conn %p", conn);
488 reply = dbus_message_new_method_return(msg);
492 dbus_message_iter_init_append(reply, &array);
494 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
495 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
496 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
497 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
499 str = __connman_element_policy2string(element->policy);
501 connman_dbus_dict_append_variant(&dict, "Policy",
502 DBUS_TYPE_STRING, &str);
504 connman_dbus_dict_append_variant(&dict, "Connected",
505 DBUS_TYPE_BOOLEAN, &element->enabled);
507 add_common_properties(element, &dict);
509 dbus_message_iter_close_container(&array, &dict);
514 static DBusMessage *set_network_property(DBusConnection *conn,
515 DBusMessage *msg, void *data)
517 struct connman_element *element = data;
518 DBusMessageIter iter;
519 DBusMessageIter value;
522 DBG("conn %p", conn);
524 if (dbus_message_iter_init(msg, &iter) == FALSE)
525 return __connman_error_invalid_arguments(msg);
527 dbus_message_iter_get_basic(&iter, &name);
528 dbus_message_iter_next(&iter);
529 dbus_message_iter_recurse(&iter, &value);
531 if (__connman_security_check_privileges(msg) < 0)
532 return __connman_error_permission_denied(msg);
534 if (g_str_equal(name, "WiFi.Passphrase") == TRUE) {
537 dbus_message_iter_get_basic(&value, &str);
538 g_free(element->wifi.passphrase);
539 element->wifi.passphrase = g_strdup(str);
541 set_common_property(element, name, &value);
543 __connman_element_store(element);
545 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
548 static DBusMessage *get_connection_properties(DBusConnection *conn,
549 DBusMessage *msg, void *data)
551 struct connman_element *element = data;
553 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 add_common_properties(element, &dict);
570 dbus_message_iter_close_container(&array, &dict);
576 static DBusMessage *get_properties(DBusConnection *conn,
577 DBusMessage *msg, void *data)
579 struct connman_element *element = data;
581 DBusMessageIter array, dict;
584 DBG("conn %p", conn);
586 reply = dbus_message_new_method_return(msg);
590 dbus_message_iter_init_append(reply, &array);
592 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
593 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
594 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
595 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
597 if (element->parent != NULL &&
598 element->parent->type != CONNMAN_ELEMENT_TYPE_ROOT) {
599 connman_dbus_dict_append_variant(&dict, "Parent",
600 DBUS_TYPE_OBJECT_PATH, &element->parent->path);
603 str = type2string(element->type);
605 connman_dbus_dict_append_variant(&dict, "Type",
606 DBUS_TYPE_STRING, &str);
607 str = subtype2string(element->subtype);
609 connman_dbus_dict_append_variant(&dict, "Subtype",
610 DBUS_TYPE_STRING, &str);
612 connman_dbus_dict_append_variant(&dict, "Enabled",
613 DBUS_TYPE_BOOLEAN, &element->enabled);
615 add_common_properties(element, &dict);
617 dbus_message_iter_close_container(&array, &dict);
622 static DBusMessage *set_property(DBusConnection *conn,
623 DBusMessage *msg, void *data)
625 struct connman_element *element = data;
626 DBusMessageIter iter;
627 DBusMessageIter value;
630 DBG("conn %p", conn);
632 if (dbus_message_iter_init(msg, &iter) == FALSE)
633 return __connman_error_invalid_arguments(msg);
635 dbus_message_iter_get_basic(&iter, &name);
636 dbus_message_iter_next(&iter);
637 dbus_message_iter_recurse(&iter, &value);
639 if (__connman_security_check_privileges(msg) < 0)
640 return __connman_error_permission_denied(msg);
642 set_common_property(element, name, &value);
644 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
647 static DBusMessage *clear_property(DBusConnection *conn,
648 DBusMessage *msg, void *data)
650 struct connman_element *element = data;
654 DBG("conn %p", conn);
656 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
657 DBUS_TYPE_INVALID) == FALSE)
658 return __connman_error_invalid_arguments(msg);
660 if (__connman_security_check_privileges(msg) < 0)
661 return __connman_error_permission_denied(msg);
663 __connman_element_lock(element);
665 for (list = element->properties; list; list = list->next) {
666 struct connman_property *property = list->data;
668 if (g_str_equal(property->name, name) == FALSE)
671 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
674 if (property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE)
677 property->flags |= CONNMAN_PROPERTY_FLAG_REFERENCE;
679 if (property->type == DBUS_TYPE_STRING)
680 g_free(property->value);
682 property->value = NULL;
685 __connman_element_unlock(element);
687 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
690 static GDBusMethodTable element_methods[] = {
691 { "GetProperties", "", "a{sv}", get_properties },
692 { "SetProperty", "sv", "", set_property },
693 { "ClearProperty", "s", "", clear_property },
694 { "Update", "", "", do_update },
695 { "Enable", "", "", do_enable },
696 { "Disable", "", "", do_disable },
701 static GDBusSignalTable element_signals[] = {
702 { "PropertyChanged", "sv" },
706 static GDBusMethodTable device_methods[] = {
707 { "GetProperties", "", "a{sv}", get_device_properties },
708 { "SetProperty", "sv", "", set_device_property },
709 { "Scan", "", "", do_update },
713 static GDBusMethodTable network_methods[] = {
714 { "GetProperties", "", "a{sv}", get_network_properties },
715 { "SetProperty", "sv", "", set_network_property },
716 { "Connect", "", "", do_enable },
717 { "Disconnect", "", "", do_disable },
721 static GDBusMethodTable connection_methods[] = {
722 { "GetProperties", "", "a{sv}", get_connection_properties },
726 struct append_filter {
727 enum connman_element_type type;
728 DBusMessageIter *iter;
731 static gboolean append_path(GNode *node, gpointer user_data)
733 struct connman_element *element = node->data;
734 struct append_filter *filter = user_data;
736 DBG("element %p name %s", element, element->name);
738 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
741 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
742 filter->type != element->type)
745 dbus_message_iter_append_basic(filter->iter,
746 DBUS_TYPE_OBJECT_PATH, &element->path);
751 void __connman_element_list(struct connman_element *element,
752 enum connman_element_type type,
753 DBusMessageIter *iter)
755 struct append_filter filter = { type, iter };
760 if (element != NULL) {
761 node = g_node_find(element_root, G_PRE_ORDER,
762 G_TRAVERSE_ALL, element);
768 g_static_rw_lock_reader_lock(&element_lock);
769 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
770 append_path, &filter);
771 g_static_rw_lock_reader_unlock(&element_lock);
775 enum connman_element_type type;
779 static gboolean count_element(GNode *node, gpointer user_data)
781 struct connman_element *element = node->data;
782 struct count_data *data = user_data;
784 DBG("element %p name %s", element, element->name);
786 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
789 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
790 data->type != element->type)
798 int __connman_element_count(struct connman_element *element,
799 enum connman_element_type type)
801 struct count_data data = { type, 0 };
806 if (element != NULL) {
807 node = g_node_find(element_root, G_PRE_ORDER,
808 G_TRAVERSE_ALL, element);
814 g_static_rw_lock_reader_lock(&element_lock);
815 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
816 count_element, &data);
817 g_static_rw_lock_reader_unlock(&element_lock);
822 static gint compare_priority(gconstpointer a, gconstpointer b)
824 const struct connman_driver *driver1 = a;
825 const struct connman_driver *driver2 = b;
827 return driver2->priority - driver1->priority;
830 static gboolean match_driver(struct connman_element *element,
831 struct connman_driver *driver)
833 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
836 if (element->type != driver->type &&
837 driver->type != CONNMAN_ELEMENT_TYPE_UNKNOWN)
840 if (element->subtype == driver->subtype ||
841 driver->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
847 static void enable_element(struct connman_element *element)
849 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
852 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
855 if (element->driver && element->driver->enable) {
856 if (element->driver->enable(element) == 0)
857 element->enabled = TRUE;
861 static gboolean probe_driver(GNode *node, gpointer data)
863 struct connman_element *element = node->data;
864 struct connman_driver *driver = data;
866 DBG("element %p name %s", element, element->name);
868 if (!element->driver && match_driver(element, driver) == TRUE) {
869 if (driver->probe(element) < 0)
872 __connman_element_lock(element);
873 element->driver = driver;
874 __connman_element_unlock(element);
876 enable_element(element);
882 void __connman_driver_rescan(struct connman_driver *driver)
884 DBG("driver %p name %s", driver, driver->name);
889 g_static_rw_lock_writer_lock(&element_lock);
891 if (element_root != NULL)
892 g_node_traverse(element_root, G_PRE_ORDER,
893 G_TRAVERSE_ALL, -1, probe_driver, driver);
895 g_static_rw_lock_writer_unlock(&element_lock);
899 * connman_driver_register:
900 * @driver: driver definition
902 * Register a new driver
904 * Returns: %0 on success
906 int connman_driver_register(struct connman_driver *driver)
908 DBG("driver %p name %s", driver, driver->name);
910 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
916 g_static_rw_lock_writer_lock(&element_lock);
918 driver_list = g_slist_insert_sorted(driver_list, driver,
921 if (element_root != NULL)
922 g_node_traverse(element_root, G_PRE_ORDER,
923 G_TRAVERSE_ALL, -1, probe_driver, driver);
925 g_static_rw_lock_writer_unlock(&element_lock);
930 static void disable_element(struct connman_element *element)
932 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
935 if (element->enabled == FALSE)
938 if (element->driver && element->driver->disable) {
939 if (element->driver->disable(element) == 0)
940 element->enabled = FALSE;
944 static gboolean remove_driver(GNode *node, gpointer data)
946 struct connman_element *element = node->data;
947 struct connman_driver *driver = data;
949 DBG("element %p name %s", element, element->name);
951 if (element->driver == driver) {
952 disable_element(element);
955 driver->remove(element);
957 __connman_element_lock(element);
958 element->driver = NULL;
959 __connman_element_unlock(element);
966 * connman_driver_unregister:
967 * @driver: driver definition
969 * Remove a previously registered driver
971 void connman_driver_unregister(struct connman_driver *driver)
973 DBG("driver %p name %s", driver, driver->name);
975 g_static_rw_lock_writer_lock(&element_lock);
977 driver_list = g_slist_remove(driver_list, driver);
979 if (element_root != NULL)
980 g_node_traverse(element_root, G_POST_ORDER,
981 G_TRAVERSE_ALL, -1, remove_driver, driver);
983 g_static_rw_lock_writer_unlock(&element_lock);
987 * connman_element_create:
988 * @name: element name
990 * Allocate a new element and assign the given #name to it. If the name
991 * is #NULL, it will be later on created based on the element type.
993 * Returns: a newly-allocated #connman_element structure
995 struct connman_element *connman_element_create(const char *name)
997 struct connman_element *element;
999 element = g_try_new0(struct connman_element, 1);
1000 if (element == NULL)
1003 DBG("element %p", element);
1005 element->refcount = 1;
1007 element->name = g_strdup(name);
1008 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
1009 element->subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
1010 element->state = CONNMAN_ELEMENT_STATE_CLOSED;
1011 element->policy = CONNMAN_ELEMENT_POLICY_AUTO;
1012 element->index = -1;
1013 element->enabled = FALSE;
1018 struct connman_element *connman_element_ref(struct connman_element *element)
1020 DBG("element %p name %s refcount %d", element, element->name,
1021 g_atomic_int_get(&element->refcount) + 1);
1023 g_atomic_int_inc(&element->refcount);
1028 static void free_properties(struct connman_element *element)
1032 DBG("element %p name %s", element, element->name);
1034 __connman_element_lock(element);
1036 for (list = element->properties; list; list = list->next) {
1037 struct connman_property *property = list->data;
1039 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1040 g_free(property->value);
1042 g_free(property->name);
1046 g_slist_free(element->properties);
1048 element->properties = NULL;
1050 __connman_element_unlock(element);
1053 void connman_element_unref(struct connman_element *element)
1055 DBG("element %p name %s refcount %d", element, element->name,
1056 g_atomic_int_get(&element->refcount) - 1);
1058 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
1059 free_properties(element);
1060 g_free(element->ipv4.address);
1061 g_free(element->ipv4.netmask);
1062 g_free(element->ipv4.gateway);
1063 g_free(element->ipv4.network);
1064 g_free(element->ipv4.broadcast);
1065 g_free(element->ipv4.nameserver);
1066 g_free(element->path);
1067 g_free(element->name);
1072 int connman_element_add_static_property(struct connman_element *element,
1073 const char *name, int type, const void *value)
1075 struct connman_property *property;
1077 DBG("element %p name %s", element, element->name);
1079 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
1082 property = g_try_new0(struct connman_property, 1);
1083 if (property == NULL)
1086 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1087 property->id = CONNMAN_PROPERTY_ID_INVALID;
1088 property->name = g_strdup(name);
1089 property->type = type;
1091 DBG("name %s type %d value %p", name, type, value);
1094 case DBUS_TYPE_STRING:
1095 property->value = g_strdup(*((const char **) value));
1097 case DBUS_TYPE_BYTE:
1098 property->value = g_try_malloc(1);
1099 if (property->value != NULL)
1100 memcpy(property->value, value, 1);
1104 __connman_element_lock(element);
1105 element->properties = g_slist_append(element->properties, property);
1106 __connman_element_unlock(element);
1111 int connman_element_add_static_array_property(struct connman_element *element,
1112 const char *name, int type, const void *value, int len)
1114 struct connman_property *property;
1116 DBG("element %p name %s", element, element->name);
1118 if (type != DBUS_TYPE_BYTE)
1121 property = g_try_new0(struct connman_property, 1);
1122 if (property == NULL)
1125 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1126 property->id = CONNMAN_PROPERTY_ID_INVALID;
1127 property->name = g_strdup(name);
1128 property->type = DBUS_TYPE_ARRAY;
1129 property->subtype = type;
1131 DBG("name %s type %d value %p", name, type, value);
1134 case DBUS_TYPE_BYTE:
1135 property->value = g_try_malloc(len);
1136 if (property->value != NULL) {
1137 memcpy(property->value,
1138 *((const unsigned char **) value), len);
1139 property->size = len;
1144 __connman_element_lock(element);
1145 element->properties = g_slist_append(element->properties, property);
1146 __connman_element_unlock(element);
1151 static void *get_reference_value(struct connman_element *element,
1152 enum connman_property_id id)
1156 DBG("element %p name %s", element, element->name);
1158 for (list = element->properties; list; list = list->next) {
1159 struct connman_property *property = list->data;
1161 if (property->id != id)
1164 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1165 return property->value;
1168 if (element->parent == NULL)
1171 return get_reference_value(element->parent, id);
1174 static void set_reference_properties(struct connman_element *element)
1178 DBG("element %p name %s", element, element->name);
1180 for (list = element->properties; list; list = list->next) {
1181 struct connman_property *property = list->data;
1183 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1186 property->value = get_reference_value(element->parent,
1191 static struct connman_property *create_property(struct connman_element *element,
1192 enum connman_property_id id)
1194 struct connman_property *property;
1197 DBG("element %p name %s", element, element->name);
1199 __connman_element_lock(element);
1201 for (list = element->properties; list; list = list->next) {
1202 property = list->data;
1204 if (property->id == id)
1208 property = g_try_new0(struct connman_property, 1);
1209 if (property == NULL)
1212 property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
1214 property->name = g_strdup(propid2name(id));
1215 property->type = propid2type(id);
1217 if (property->name == NULL) {
1223 element->properties = g_slist_append(element->properties, property);
1226 __connman_element_unlock(element);
1231 static void create_default_properties(struct connman_element *element)
1233 struct connman_property *property;
1236 DBG("element %p name %s", element, element->name);
1238 for (i = 0; propid_table[i].name; i++) {
1239 DBG("property %s", propid_table[i].name);
1241 property = create_property(element, propid_table[i].id);
1243 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
1245 if (propid_table[i].type != DBUS_TYPE_STRING)
1248 if (propid_table[i].value)
1249 property->value = g_strdup(propid_table[i].value);
1251 property->value = g_strdup("");
1255 static int define_properties_valist(struct connman_element *element,
1258 enum connman_property_id id;
1260 DBG("element %p name %s", element, element->name);
1262 id = va_arg(args, enum connman_property_id);
1264 while (id != CONNMAN_PROPERTY_ID_INVALID) {
1266 DBG("property %d", id);
1268 create_property(element, id);
1270 id = va_arg(args, enum connman_property_id);
1277 * connman_element_define_properties:
1278 * @element: an element
1279 * @varargs: list of property identifiers
1281 * Define the valid properties for an element.
1283 * Returns: %0 on success
1285 int connman_element_define_properties(struct connman_element *element, ...)
1290 DBG("element %p name %s", element, element->name);
1292 va_start(args, element);
1294 err = define_properties_valist(element, args);
1301 int connman_element_create_property(struct connman_element *element,
1302 const char *name, int type)
1307 int connman_element_set_property(struct connman_element *element,
1308 enum connman_property_id id, const void *value)
1311 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1312 __connman_element_lock(element);
1313 g_free(element->ipv4.address);
1314 element->ipv4.address = g_strdup(*((const char **) value));
1315 __connman_element_unlock(element);
1317 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1318 __connman_element_lock(element);
1319 g_free(element->ipv4.netmask);
1320 element->ipv4.netmask = g_strdup(*((const char **) value));
1321 __connman_element_unlock(element);
1323 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1324 __connman_element_lock(element);
1325 g_free(element->ipv4.gateway);
1326 element->ipv4.gateway = g_strdup(*((const char **) value));
1327 __connman_element_unlock(element);
1329 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1330 __connman_element_lock(element);
1331 g_free(element->ipv4.nameserver);
1332 element->ipv4.nameserver = g_strdup(*((const char **) value));
1333 __connman_element_unlock(element);
1335 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1336 __connman_element_lock(element);
1337 g_free(element->wifi.security);
1338 element->wifi.security = g_strdup(*((const char **) value));
1339 __connman_element_unlock(element);
1341 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1342 __connman_element_lock(element);
1343 g_free(element->wifi.passphrase);
1344 element->wifi.passphrase = g_strdup(*((const char **) value));
1345 __connman_element_unlock(element);
1352 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1353 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1354 DBUS_TYPE_OBJECT_PATH, &element->path,
1361 int connman_element_get_value(struct connman_element *element,
1362 enum connman_property_id id, void *value)
1364 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1368 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1369 if (element->ipv4.address == NULL)
1370 return connman_element_get_value(element->parent,
1372 __connman_element_lock(element);
1373 *((char **) value) = element->ipv4.address;
1374 __connman_element_unlock(element);
1376 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1377 if (element->ipv4.netmask == NULL)
1378 return connman_element_get_value(element->parent,
1380 __connman_element_lock(element);
1381 *((char **) value) = element->ipv4.netmask;
1382 __connman_element_unlock(element);
1384 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1385 if (element->ipv4.gateway == NULL)
1386 return connman_element_get_value(element->parent,
1388 __connman_element_lock(element);
1389 *((char **) value) = element->ipv4.gateway;
1390 __connman_element_unlock(element);
1392 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1393 if (element->ipv4.nameserver == NULL)
1394 return connman_element_get_value(element->parent,
1396 __connman_element_lock(element);
1397 *((char **) value) = element->ipv4.nameserver;
1398 __connman_element_unlock(element);
1400 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1401 if (element->wifi.security == NULL)
1402 return connman_element_get_value(element->parent,
1404 __connman_element_lock(element);
1405 *((char **) value) = element->wifi.security;
1406 __connman_element_unlock(element);
1408 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1409 if (element->wifi.passphrase == NULL)
1410 return connman_element_get_value(element->parent,
1412 __connman_element_lock(element);
1413 *((char **) value) = element->wifi.passphrase;
1414 __connman_element_unlock(element);
1423 gboolean connman_element_get_static_property(struct connman_element *element,
1424 const char *name, void *value)
1427 gboolean found = FALSE;
1429 DBG("element %p name %s", element, element->name);
1431 __connman_element_lock(element);
1433 for (list = element->properties; list; list = list->next) {
1434 struct connman_property *property = list->data;
1436 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1439 if (g_str_equal(property->name, name) == TRUE) {
1440 switch (property->type) {
1441 case DBUS_TYPE_STRING:
1442 *((char **) value) = property->value;
1450 __connman_element_unlock(element);
1455 gboolean connman_element_get_static_array_property(struct connman_element *element,
1456 const char *name, void *value, int *len)
1459 gboolean found = FALSE;
1461 DBG("element %p name %s", element, element->name);
1463 __connman_element_lock(element);
1465 for (list = element->properties; list; list = list->next) {
1466 struct connman_property *property = list->data;
1468 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1471 if (g_str_equal(property->name, name) == TRUE) {
1472 *((char **) value) = property->value;
1473 *len = property->size;
1479 __connman_element_unlock(element);
1484 gboolean connman_element_match_static_property(struct connman_element *element,
1485 const char *name, const void *value)
1488 gboolean result = FALSE;
1490 DBG("element %p name %s", element, element->name);
1492 __connman_element_lock(element);
1494 for (list = element->properties; list; list = list->next) {
1495 struct connman_property *property = list->data;
1497 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1500 if (g_str_equal(property->name, name) == FALSE)
1503 if (property->type == DBUS_TYPE_STRING)
1504 result = g_str_equal(property->value,
1505 *((const char **) value));
1511 __connman_element_unlock(element);
1516 static void append_devices(DBusMessageIter *entry)
1518 DBusMessageIter value, iter;
1519 const char *key = "Devices";
1521 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1523 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1524 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1527 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1528 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1530 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
1532 dbus_message_iter_close_container(&value, &iter);
1534 dbus_message_iter_close_container(entry, &value);
1537 static void emit_devices_signal(DBusConnection *conn)
1539 DBusMessage *signal;
1540 DBusMessageIter entry;
1542 DBG("conn %p", conn);
1544 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1545 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1549 dbus_message_iter_init_append(signal, &entry);
1551 append_devices(&entry);
1553 g_dbus_send_message(conn, signal);
1556 static void append_connections(DBusMessageIter *entry)
1558 DBusMessageIter value, iter;
1559 const char *key = "Connections";
1561 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1563 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1564 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1567 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1568 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1570 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
1572 dbus_message_iter_close_container(&value, &iter);
1574 dbus_message_iter_close_container(entry, &value);
1577 static void emit_connections_signal(DBusConnection *conn)
1579 DBusMessage *signal;
1580 DBusMessageIter entry;
1582 DBG("conn %p", conn);
1584 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1585 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1589 dbus_message_iter_init_append(signal, &entry);
1591 append_connections(&entry);
1593 g_dbus_send_message(conn, signal);
1596 static void append_state(DBusMessageIter *entry, const char *state)
1598 DBusMessageIter value;
1599 const char *key = "State";
1601 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1603 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1604 DBUS_TYPE_STRING_AS_STRING, &value);
1606 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1608 dbus_message_iter_close_container(entry, &value);
1611 static void emit_state_change(DBusConnection *conn, const char *state)
1613 DBusMessage *signal;
1614 DBusMessageIter entry;
1616 DBG("conn %p", conn);
1618 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1619 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1623 dbus_message_iter_init_append(signal, &entry);
1625 append_state(&entry, state);
1627 g_dbus_send_message(conn, signal);
1630 static void register_element(gpointer data, gpointer user_data)
1632 struct connman_element *element = data;
1633 const gchar *basepath;
1637 g_static_rw_lock_writer_lock(&element_lock);
1639 __connman_element_lock(element);
1641 if (element->parent) {
1642 node = g_node_find(element_root, G_PRE_ORDER,
1643 G_TRAVERSE_ALL, element->parent);
1644 basepath = element->parent->path;
1646 if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
1647 element->subtype = element->parent->subtype;
1649 element->parent = element_root->data;
1651 node = element_root;
1655 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1657 set_reference_properties(element);
1659 __connman_element_unlock(element);
1661 DBG("element %p path %s", element, element->path);
1663 __connman_element_load(element);
1665 g_node_append_data(node, element);
1668 if (g_dbus_register_interface(connection, element->path,
1669 CONNMAN_ELEMENT_INTERFACE,
1670 element_methods, element_signals,
1671 NULL, element, NULL) == FALSE)
1672 connman_error("Failed to register %s element", element->path);
1675 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1676 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1677 if (g_dbus_register_interface(connection, element->path,
1678 CONNMAN_DEVICE_INTERFACE,
1679 device_methods, element_signals,
1680 NULL, element, NULL) == FALSE)
1681 connman_error("Failed to register %s device",
1684 emit_devices_signal(connection);
1687 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1688 if (g_dbus_register_interface(connection, element->path,
1689 CONNMAN_NETWORK_INTERFACE,
1690 network_methods, element_signals,
1691 NULL, element, NULL) == FALSE)
1692 connman_error("Failed to register %s network",
1696 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1697 if (g_dbus_register_interface(connection, element->path,
1698 CONNMAN_CONNECTION_INTERFACE,
1699 connection_methods, element_signals,
1700 NULL, element, NULL) == FALSE)
1701 connman_error("Failed to register %s connection",
1704 emit_connections_signal(connection);
1705 emit_state_change(connection, "online");
1710 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1711 CONNMAN_MANAGER_INTERFACE, "ElementAdded",
1712 DBUS_TYPE_OBJECT_PATH, &element->path,
1716 g_static_rw_lock_writer_unlock(&element_lock);
1718 __connman_element_store(element);
1720 g_static_rw_lock_writer_lock(&element_lock);
1722 for (list = driver_list; list; list = list->next) {
1723 struct connman_driver *driver = list->data;
1725 if (match_driver(element, driver) == FALSE)
1728 DBG("driver %p name %s", driver, driver->name);
1730 if (driver->probe(element) == 0) {
1731 __connman_element_lock(element);
1732 element->driver = driver;
1733 __connman_element_unlock(element);
1735 enable_element(element);
1740 g_static_rw_lock_writer_unlock(&element_lock);
1744 * connman_element_register:
1745 * @element: the element to register
1746 * @parent: the parent to register the element with
1748 * Register an element with the core. It will be register under the given
1749 * parent of if %NULL is provided under the root element.
1751 * Returns: %0 on success
1753 int connman_element_register(struct connman_element *element,
1754 struct connman_element *parent)
1756 DBG("element %p name %s parent %p", element, element->name, parent);
1758 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1759 if (g_pattern_match_simple(device_filter,
1760 element->name) == FALSE) {
1761 DBG("ignoring %s device", element->name);
1766 if (connman_element_ref(element) == NULL)
1769 __connman_element_lock(element);
1771 if (element->name == NULL) {
1772 element->name = g_strdup(type2string(element->type));
1773 if (element->name == NULL) {
1774 __connman_element_unlock(element);
1779 element->parent = parent;
1781 __connman_element_unlock(element);
1783 register_element(element, NULL);
1788 static gboolean remove_element(GNode *node, gpointer user_data)
1790 struct connman_element *element = node->data;
1791 struct connman_element *root = user_data;
1793 DBG("element %p name %s", element, element->name);
1795 if (element == root)
1798 if (element->driver) {
1799 if (element->driver->remove)
1800 element->driver->remove(element);
1802 __connman_element_lock(element);
1803 element->driver = NULL;
1804 __connman_element_unlock(element);
1808 g_node_unlink(node);
1809 g_node_destroy(node);
1813 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1814 CONNMAN_MANAGER_INTERFACE, "ElementRemoved",
1815 DBUS_TYPE_OBJECT_PATH, &element->path,
1819 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1820 emit_state_change(connection, "offline");
1821 emit_connections_signal(connection);
1823 g_dbus_unregister_interface(connection, element->path,
1824 CONNMAN_CONNECTION_INTERFACE);
1827 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK)
1828 g_dbus_unregister_interface(connection, element->path,
1829 CONNMAN_NETWORK_INTERFACE);
1831 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1832 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1833 emit_devices_signal(connection);
1835 g_dbus_unregister_interface(connection, element->path,
1836 CONNMAN_DEVICE_INTERFACE);
1840 g_dbus_unregister_interface(connection, element->path,
1841 CONNMAN_ELEMENT_INTERFACE);
1844 connman_element_unref(element);
1849 void connman_element_unregister(struct connman_element *element)
1853 DBG("element %p name %s", element, element->name);
1855 g_static_rw_lock_writer_lock(&element_lock);
1857 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1860 g_node_traverse(node, G_POST_ORDER,
1861 G_TRAVERSE_ALL, -1, remove_element, NULL);
1863 g_static_rw_lock_writer_unlock(&element_lock);
1866 void connman_element_unregister_children(struct connman_element *element)
1870 DBG("element %p name %s", element, element->name);
1872 g_static_rw_lock_writer_lock(&element_lock);
1874 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1877 g_node_traverse(node, G_POST_ORDER,
1878 G_TRAVERSE_ALL, -1, remove_element, element);
1880 g_static_rw_lock_writer_unlock(&element_lock);
1883 static gboolean update_element(GNode *node, gpointer user_data)
1885 struct connman_element *element = node->data;
1887 DBG("element %p name %s", element, element->name);
1889 if (element->driver && element->driver->update)
1890 element->driver->update(element);
1893 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
1894 CONNMAN_MANAGER_INTERFACE, "ElementUpdated",
1895 DBUS_TYPE_OBJECT_PATH, &element->path,
1902 void connman_element_update(struct connman_element *element)
1906 DBG("element %p name %s", element, element->name);
1908 g_static_rw_lock_reader_lock(&element_lock);
1910 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1913 g_node_traverse(node, G_PRE_ORDER,
1914 G_TRAVERSE_ALL, -1, update_element, NULL);
1916 g_static_rw_lock_reader_unlock(&element_lock);
1919 int connman_element_set_enabled(struct connman_element *element,
1922 if (element->enabled == enabled)
1925 element->enabled = enabled;
1927 connman_element_update(element);
1932 int __connman_element_init(DBusConnection *conn, const char *device)
1934 struct connman_element *element;
1936 DBG("conn %p", conn);
1938 connection = dbus_connection_ref(conn);
1939 if (connection == NULL)
1942 device_filter = g_strdup(device);
1944 g_static_rw_lock_writer_lock(&element_lock);
1946 element = connman_element_create("root");
1948 element->path = g_strdup("/");
1949 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1951 create_default_properties(element);
1953 element_root = g_node_new(element);
1955 g_static_rw_lock_writer_unlock(&element_lock);
1957 __connman_device_init();
1962 static gboolean free_driver(GNode *node, gpointer data)
1964 struct connman_element *element = node->data;
1966 DBG("element %p name %s", element, element->name);
1968 if (element->driver) {
1969 if (element->driver->remove)
1970 element->driver->remove(element);
1972 __connman_element_lock(element);
1973 element->driver = NULL;
1974 __connman_element_unlock(element);
1980 static gboolean free_node(GNode *node, gpointer data)
1982 struct connman_element *element = node->data;
1984 DBG("element %p name %s", element, element->name);
1986 if (g_node_depth(node) > 1)
1987 connman_element_unregister(element);
1992 void __connman_element_cleanup(void)
1996 __connman_device_cleanup();
1998 g_static_rw_lock_writer_lock(&element_lock);
1999 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
2001 g_static_rw_lock_writer_unlock(&element_lock);
2003 g_static_rw_lock_writer_lock(&element_lock);
2004 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
2006 g_static_rw_lock_writer_unlock(&element_lock);
2008 g_static_rw_lock_writer_lock(&element_lock);
2009 g_node_destroy(element_root);
2010 element_root = NULL;
2011 g_static_rw_lock_writer_unlock(&element_lock);
2013 g_free(device_filter);
2015 dbus_connection_unref(connection);