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 GNode *element_root = NULL;
38 static GSList *driver_list = NULL;
39 static gchar *device_filter = NULL;
42 enum connman_property_id id;
47 { CONNMAN_PROPERTY_ID_IPV4_METHOD,
48 DBUS_TYPE_STRING, "IPv4.Method", "dhcp" },
49 { CONNMAN_PROPERTY_ID_IPV4_ADDRESS,
50 DBUS_TYPE_STRING, "IPv4.Address" },
51 { CONNMAN_PROPERTY_ID_IPV4_NETMASK,
52 DBUS_TYPE_STRING, "IPv4.Netmask" },
53 { CONNMAN_PROPERTY_ID_IPV4_GATEWAY,
54 DBUS_TYPE_STRING, "IPv4.Gateway" },
55 { CONNMAN_PROPERTY_ID_IPV4_NAMESERVER,
56 DBUS_TYPE_STRING, "IPv4.Nameserver" },
58 { CONNMAN_PROPERTY_ID_WIFI_SECURITY,
59 DBUS_TYPE_STRING, "WiFi.Security" },
60 { CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE,
61 DBUS_TYPE_STRING, "WiFi.Passphrase" },
66 static int propid2type(enum connman_property_id id)
70 for (i = 0; propid_table[i].name; i++) {
71 if (propid_table[i].id == id)
72 return propid_table[i].type;
75 return DBUS_TYPE_INVALID;
78 static const char *propid2name(enum connman_property_id id)
82 for (i = 0; propid_table[i].name; i++) {
83 if (propid_table[i].id == id)
84 return propid_table[i].name;
90 static const char *type2string(enum connman_element_type type)
93 case CONNMAN_ELEMENT_TYPE_UNKNOWN:
95 case CONNMAN_ELEMENT_TYPE_ROOT:
97 case CONNMAN_ELEMENT_TYPE_PROFILE:
99 case CONNMAN_ELEMENT_TYPE_DEVICE:
101 case CONNMAN_ELEMENT_TYPE_NETWORK:
103 case CONNMAN_ELEMENT_TYPE_SERVICE:
105 case CONNMAN_ELEMENT_TYPE_IPV4:
107 case CONNMAN_ELEMENT_TYPE_IPV6:
109 case CONNMAN_ELEMENT_TYPE_DHCP:
111 case CONNMAN_ELEMENT_TYPE_BOOTP:
113 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
115 case CONNMAN_ELEMENT_TYPE_RESOLVER:
117 case CONNMAN_ELEMENT_TYPE_CONNECTION:
124 static const char *subtype2string(enum connman_element_subtype type)
127 case CONNMAN_ELEMENT_SUBTYPE_UNKNOWN:
129 case CONNMAN_ELEMENT_SUBTYPE_FAKE:
131 case CONNMAN_ELEMENT_SUBTYPE_NETWORK:
133 case CONNMAN_ELEMENT_SUBTYPE_ETHERNET:
135 case CONNMAN_ELEMENT_SUBTYPE_WIFI:
137 case CONNMAN_ELEMENT_SUBTYPE_WIMAX:
139 case CONNMAN_ELEMENT_SUBTYPE_MODEM:
141 case CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH:
148 const char *__connman_element_policy2string(enum connman_element_policy policy)
151 case CONNMAN_ELEMENT_POLICY_UNKNOWN:
153 case CONNMAN_ELEMENT_POLICY_OFF:
155 case CONNMAN_ELEMENT_POLICY_AUTO:
157 case CONNMAN_ELEMENT_POLICY_IGNORE:
159 case CONNMAN_ELEMENT_POLICY_ASK:
166 enum connman_element_policy __connman_element_string2policy(const char *policy)
168 if (strcasecmp(policy, "off") == 0)
169 return CONNMAN_ELEMENT_POLICY_OFF;
170 else if (strcasecmp(policy, "ignore") == 0)
171 return CONNMAN_ELEMENT_POLICY_IGNORE;
172 else if (strcasecmp(policy, "auto") == 0)
173 return CONNMAN_ELEMENT_POLICY_AUTO;
174 else if (strcasecmp(policy, "ask") == 0)
175 return CONNMAN_ELEMENT_POLICY_ASK;
177 return CONNMAN_ELEMENT_POLICY_UNKNOWN;
180 const char *__connman_ipv4_method2string(enum connman_ipv4_method method)
183 case CONNMAN_IPV4_METHOD_UNKNOWN:
185 case CONNMAN_IPV4_METHOD_OFF:
187 case CONNMAN_IPV4_METHOD_STATIC:
189 case CONNMAN_IPV4_METHOD_DHCP:
196 enum connman_ipv4_method __connman_ipv4_string2method(const char *method)
198 if (strcasecmp(method, "off") == 0)
199 return CONNMAN_IPV4_METHOD_OFF;
200 else if (strcasecmp(method, "static") == 0)
201 return CONNMAN_IPV4_METHOD_STATIC;
202 else if (strcasecmp(method, "dhcp") == 0)
203 return CONNMAN_IPV4_METHOD_DHCP;
205 return CONNMAN_IPV4_METHOD_UNKNOWN;
208 static void append_property(DBusMessageIter *dict,
209 struct connman_property *property)
211 if (property->value == NULL)
214 switch (property->type) {
215 case DBUS_TYPE_ARRAY:
216 connman_dbus_dict_append_array(dict, property->name,
217 property->subtype, &property->value, property->size);
219 case DBUS_TYPE_STRING:
220 connman_dbus_dict_append_variant(dict, property->name,
221 property->type, &property->value);
224 connman_dbus_dict_append_variant(dict, property->name,
225 property->type, property->value);
230 static void add_common_properties(struct connman_element *element,
231 DBusMessageIter *dict)
233 const char *address = NULL, *netmask = NULL, *gateway = NULL;
236 connman_element_get_value(element,
237 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
238 connman_element_get_value(element,
239 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
240 connman_element_get_value(element,
241 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
243 if (element->priority > 0)
244 connman_dbus_dict_append_variant(dict, "Priority",
245 DBUS_TYPE_UINT16, &element->priority);
248 connman_dbus_dict_append_variant(dict, "IPv4.Address",
249 DBUS_TYPE_STRING, &address);
251 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
252 DBUS_TYPE_STRING, &netmask);
254 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
255 DBUS_TYPE_STRING, &gateway);
257 if (element->wifi.security != NULL) {
258 const char *passphrase = "";
260 connman_dbus_dict_append_variant(dict, "WiFi.Security",
261 DBUS_TYPE_STRING, &element->wifi.security);
263 if (element->wifi.passphrase != NULL)
264 passphrase = element->wifi.passphrase;
266 connman_dbus_dict_append_variant(dict, "WiFi.Passphrase",
267 DBUS_TYPE_STRING, &passphrase);
270 __connman_element_lock(element);
272 for (list = element->properties; list; list = list->next) {
273 struct connman_property *property = list->data;
275 append_property(dict, property);
278 __connman_element_unlock(element);
281 static void set_common_property(struct connman_element *element,
282 const char *name, DBusMessageIter *value)
286 if (g_str_equal(name, "Priority") == TRUE) {
287 dbus_message_iter_get_basic(value, &element->priority);
291 __connman_element_lock(element);
293 for (list = element->properties; list; list = list->next) {
294 struct connman_property *property = list->data;
297 if (g_str_equal(property->name, name) == FALSE)
300 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
303 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
305 if (property->type == DBUS_TYPE_STRING) {
306 dbus_message_iter_get_basic(value, &str);
307 g_free(property->value);
308 property->value = g_strdup(str);
310 property->value = NULL;
313 __connman_element_unlock(element);
316 static void emit_enabled_signal(DBusConnection *conn,
317 struct connman_element *element)
320 DBusMessageIter entry, value;
321 const char *iface, *key;
323 DBG("conn %p", conn);
328 switch (element->type) {
329 case CONNMAN_ELEMENT_TYPE_DEVICE:
330 iface = CONNMAN_DEVICE_INTERFACE;
333 case CONNMAN_ELEMENT_TYPE_NETWORK:
334 iface = CONNMAN_NETWORK_INTERFACE;
341 signal = dbus_message_new_signal(element->path,
342 iface, "PropertyChanged");
346 dbus_message_iter_init_append(signal, &entry);
348 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
350 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
351 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
353 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
356 dbus_message_iter_close_container(&entry, &value);
358 g_dbus_send_message(conn, signal);
361 static DBusMessage *do_update(DBusConnection *conn,
362 DBusMessage *msg, void *data)
364 struct connman_element *element = data;
366 DBG("conn %p", conn);
368 if (element->enabled == FALSE)
369 return __connman_error_failed(msg);
371 if (element->driver && element->driver->update) {
372 DBG("Calling update callback");
373 if (element->driver->update(element) < 0)
374 return __connman_error_failed(msg);
378 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
381 static DBusMessage *do_enable(DBusConnection *conn,
382 DBusMessage *msg, void *data)
384 struct connman_element *element = data;
386 DBG("conn %p", conn);
388 if (element->enabled == TRUE)
389 return __connman_error_failed(msg);
391 if (element->driver && element->driver->enable) {
392 DBG("Calling enable callback");
393 if (element->driver->enable(element) < 0)
394 return __connman_error_failed(msg);
397 element->enabled = TRUE;
399 emit_enabled_signal(connection, element);
401 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
404 static DBusMessage *do_disable(DBusConnection *conn,
405 DBusMessage *msg, void *data)
407 struct connman_element *element = data;
409 DBG("conn %p", conn);
411 if (element->enabled == FALSE)
412 return __connman_error_failed(msg);
414 if (element->driver && element->driver->disable) {
415 DBG("Calling disable callback");
416 if (element->driver->disable(element) < 0)
417 return __connman_error_failed(msg);
420 element->enabled = FALSE;
422 emit_enabled_signal(connection, element);
424 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
427 static void append_networks(struct connman_element *element,
428 DBusMessageIter *entry)
430 DBusMessageIter value, iter;
431 const char *key = "Networks";
433 if (element->subtype != CONNMAN_ELEMENT_SUBTYPE_WIFI &&
434 element->subtype != CONNMAN_ELEMENT_SUBTYPE_WIMAX)
437 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
439 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
440 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
443 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
444 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
446 __connman_element_list(element, CONNMAN_ELEMENT_TYPE_NETWORK, &iter);
448 dbus_message_iter_close_container(&value, &iter);
450 dbus_message_iter_close_container(entry, &value);
453 static DBusMessage *device_get_properties(DBusConnection *conn,
454 DBusMessage *msg, void *data)
456 struct connman_element *element = data;
458 DBusMessageIter array, dict, entry;
461 DBG("conn %p", conn);
463 reply = dbus_message_new_method_return(msg);
467 dbus_message_iter_init_append(reply, &array);
469 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
470 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
471 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
472 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
474 str = subtype2string(element->subtype);
476 connman_dbus_dict_append_variant(&dict, "Type",
477 DBUS_TYPE_STRING, &str);
479 str = __connman_element_policy2string(element->policy);
481 connman_dbus_dict_append_variant(&dict, "Policy",
482 DBUS_TYPE_STRING, &str);
484 connman_dbus_dict_append_variant(&dict, "Powered",
485 DBUS_TYPE_BOOLEAN, &element->enabled);
487 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
490 append_networks(element, &entry);
492 dbus_message_iter_close_container(&dict, &entry);
494 add_common_properties(element, &dict);
496 dbus_message_iter_close_container(&array, &dict);
501 static DBusMessage *device_set_property(DBusConnection *conn,
502 DBusMessage *msg, void *data)
504 struct connman_element *element = data;
505 DBusMessageIter iter, value;
508 DBG("conn %p", conn);
510 if (dbus_message_iter_init(msg, &iter) == FALSE)
511 return __connman_error_invalid_arguments(msg);
513 dbus_message_iter_get_basic(&iter, &name);
514 dbus_message_iter_next(&iter);
515 dbus_message_iter_recurse(&iter, &value);
517 if (__connman_security_check_privileges(msg) < 0)
518 return __connman_error_permission_denied(msg);
520 if (g_str_equal(name, "Powered") == TRUE) {
523 dbus_message_iter_get_basic(&value, &powered);
526 do_enable(conn, msg, data);
528 do_disable(conn, msg, data);
530 set_common_property(element, name, &value);
532 __connman_element_store(element);
534 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
537 static int parse_network_dict(DBusMessageIter *iter, const char **ssid,
538 const char **security, const char **passphrase)
540 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_DICT_ENTRY) {
541 DBusMessageIter entry, value;
544 dbus_message_iter_recurse(iter, &entry);
545 dbus_message_iter_get_basic(&entry, &key);
547 dbus_message_iter_next(&entry);
548 dbus_message_iter_recurse(&entry, &value);
550 switch (dbus_message_iter_get_arg_type(&value)) {
551 case DBUS_TYPE_STRING:
552 if (g_str_equal(key, "WiFi.SSID") == TRUE)
553 dbus_message_iter_get_basic(&value, ssid);
554 else if (g_str_equal(key, "WiFi.Security") == TRUE)
555 dbus_message_iter_get_basic(&value, security);
556 else if (g_str_equal(key, "WiFi.Passphrase") == TRUE)
557 dbus_message_iter_get_basic(&value, passphrase);
561 dbus_message_iter_next(iter);
567 static DBusMessage *device_create_network(DBusConnection *conn,
568 DBusMessage *msg, void *data)
570 struct connman_element *element = data;
571 struct connman_element *network;
572 DBusMessageIter iter, array;
573 const char *ssid = NULL, *security = NULL, *passphrase = NULL;
575 DBG("conn %p", conn);
577 if (dbus_message_iter_init(msg, &iter) == FALSE)
578 return __connman_error_invalid_arguments(msg);
580 dbus_message_iter_recurse(&iter, &array);
581 parse_network_dict(&array, &ssid, &security, &passphrase);
583 return __connman_error_invalid_arguments(msg);
585 DBG("ssid %s security %s passphrase %s", ssid, security, passphrase);
587 network = connman_element_create(ssid);
589 network->type = CONNMAN_ELEMENT_TYPE_NETWORK;
590 network->index = element->index;
592 network->remember = TRUE;
594 connman_element_add_static_property(network, "Name",
595 DBUS_TYPE_STRING, &ssid);
597 connman_element_add_static_array_property(element, "WiFi.SSID",
598 DBUS_TYPE_BYTE, &ssid, strlen(ssid));
600 network->wifi.security = g_strdup(security);
601 network->wifi.passphrase = g_strdup(passphrase);
603 connman_element_register(network, element);
605 return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &network->path,
609 static DBusMessage *device_remove_network(DBusConnection *conn,
610 DBusMessage *msg, void *data)
612 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
615 static DBusMessage *network_get_properties(DBusConnection *conn,
616 DBusMessage *msg, void *data)
618 struct connman_element *element = data;
620 DBusMessageIter array, dict;
623 DBG("conn %p", conn);
625 reply = dbus_message_new_method_return(msg);
629 dbus_message_iter_init_append(reply, &array);
631 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
632 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
633 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
634 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
636 str = __connman_element_policy2string(element->policy);
638 connman_dbus_dict_append_variant(&dict, "Policy",
639 DBUS_TYPE_STRING, &str);
641 connman_dbus_dict_append_variant(&dict, "Available",
642 DBUS_TYPE_BOOLEAN, &element->available);
644 connman_dbus_dict_append_variant(&dict, "Connected",
645 DBUS_TYPE_BOOLEAN, &element->enabled);
647 connman_dbus_dict_append_variant(&dict, "Remember",
648 DBUS_TYPE_BOOLEAN, &element->remember);
650 add_common_properties(element, &dict);
652 dbus_message_iter_close_container(&array, &dict);
657 static DBusMessage *network_set_property(DBusConnection *conn,
658 DBusMessage *msg, void *data)
660 struct connman_element *element = data;
661 DBusMessageIter iter;
662 DBusMessageIter value;
665 DBG("conn %p", conn);
667 if (dbus_message_iter_init(msg, &iter) == FALSE)
668 return __connman_error_invalid_arguments(msg);
670 dbus_message_iter_get_basic(&iter, &name);
671 dbus_message_iter_next(&iter);
672 dbus_message_iter_recurse(&iter, &value);
674 if (__connman_security_check_privileges(msg) < 0)
675 return __connman_error_permission_denied(msg);
677 if (g_str_equal(name, "Remember") == TRUE) {
678 dbus_message_iter_get_basic(&value, &element->remember);
679 } else if (g_str_equal(name, "WiFi.Passphrase") == TRUE) {
682 dbus_message_iter_get_basic(&value, &str);
683 g_free(element->wifi.passphrase);
684 element->wifi.passphrase = g_strdup(str);
686 set_common_property(element, name, &value);
688 __connman_element_store(element);
690 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
693 static DBusMessage *get_connection_properties(DBusConnection *conn,
694 DBusMessage *msg, void *data)
696 struct connman_element *element = data;
698 DBusMessageIter array, dict;
700 DBG("conn %p", conn);
702 reply = dbus_message_new_method_return(msg);
706 dbus_message_iter_init_append(reply, &array);
708 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
709 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
710 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
711 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
713 add_common_properties(element, &dict);
715 dbus_message_iter_close_container(&array, &dict);
720 static GDBusMethodTable device_methods[] = {
721 { "GetProperties", "", "a{sv}", device_get_properties },
722 { "SetProperty", "sv", "", device_set_property },
723 { "CreateNetwork", "a{sv}", "o", device_create_network },
724 { "RemoveNetwork", "o", "", device_remove_network },
725 { "ProposeScan", "", "", do_update },
729 static GDBusMethodTable network_methods[] = {
730 { "GetProperties", "", "a{sv}", network_get_properties },
731 { "SetProperty", "sv", "", network_set_property },
732 { "Connect", "", "", do_enable },
733 { "Disconnect", "", "", do_disable },
737 static GDBusMethodTable connection_methods[] = {
738 { "GetProperties", "", "a{sv}", get_connection_properties },
742 static GDBusSignalTable element_signals[] = {
743 { "PropertyChanged", "sv" },
747 struct append_filter {
748 enum connman_element_type type;
749 DBusMessageIter *iter;
752 static gboolean append_path(GNode *node, gpointer user_data)
754 struct connman_element *element = node->data;
755 struct append_filter *filter = user_data;
757 DBG("element %p name %s", element, element->name);
759 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
762 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
763 filter->type != element->type)
766 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
767 element->subtype == CONNMAN_ELEMENT_SUBTYPE_NETWORK)
770 dbus_message_iter_append_basic(filter->iter,
771 DBUS_TYPE_OBJECT_PATH, &element->path);
776 void __connman_element_list(struct connman_element *element,
777 enum connman_element_type type,
778 DBusMessageIter *iter)
780 struct append_filter filter = { type, iter };
785 if (element != NULL) {
786 node = g_node_find(element_root, G_PRE_ORDER,
787 G_TRAVERSE_ALL, element);
793 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
794 append_path, &filter);
798 enum connman_element_type type;
802 static gboolean count_element(GNode *node, gpointer user_data)
804 struct connman_element *element = node->data;
805 struct count_data *data = user_data;
807 DBG("element %p name %s", element, element->name);
809 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
812 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
813 data->type != element->type)
821 int __connman_element_count(struct connman_element *element,
822 enum connman_element_type type)
824 struct count_data data = { type, 0 };
829 if (element != NULL) {
830 node = g_node_find(element_root, G_PRE_ORDER,
831 G_TRAVERSE_ALL, element);
837 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
838 count_element, &data);
843 static gint compare_priority(gconstpointer a, gconstpointer b)
845 const struct connman_driver *driver1 = a;
846 const struct connman_driver *driver2 = b;
848 return driver2->priority - driver1->priority;
851 static gboolean match_driver(struct connman_element *element,
852 struct connman_driver *driver)
854 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
857 if (element->type != driver->type &&
858 driver->type != CONNMAN_ELEMENT_TYPE_UNKNOWN)
861 if (element->subtype == driver->subtype ||
862 driver->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
868 static void enable_element(struct connman_element *element)
870 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
873 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
876 if (element->driver && element->driver->enable) {
877 if (element->driver->enable(element) == 0) {
878 element->enabled = TRUE;
879 emit_enabled_signal(connection, element);
884 static gboolean probe_driver(GNode *node, gpointer data)
886 struct connman_element *element = node->data;
887 struct connman_driver *driver = data;
889 DBG("element %p name %s", element, element->name);
891 if (!element->driver && match_driver(element, driver) == TRUE) {
892 if (driver->probe(element) < 0)
895 __connman_element_lock(element);
896 element->driver = driver;
897 __connman_element_unlock(element);
899 enable_element(element);
905 void __connman_driver_rescan(struct connman_driver *driver)
907 DBG("driver %p name %s", driver, driver->name);
912 if (element_root != NULL)
913 g_node_traverse(element_root, G_PRE_ORDER,
914 G_TRAVERSE_ALL, -1, probe_driver, driver);
918 * connman_driver_register:
919 * @driver: driver definition
921 * Register a new driver
923 * Returns: %0 on success
925 int connman_driver_register(struct connman_driver *driver)
927 DBG("driver %p name %s", driver, driver->name);
929 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
935 driver_list = g_slist_insert_sorted(driver_list, driver,
938 if (element_root != NULL)
939 g_node_traverse(element_root, G_PRE_ORDER,
940 G_TRAVERSE_ALL, -1, probe_driver, driver);
945 static void disable_element(struct connman_element *element)
947 if (element->policy != CONNMAN_ELEMENT_POLICY_AUTO)
950 if (element->enabled == FALSE)
953 if (element->driver && element->driver->disable) {
954 if (element->driver->disable(element) == 0) {
955 element->enabled = FALSE;
956 emit_enabled_signal(connection, element);
961 static gboolean remove_driver(GNode *node, gpointer data)
963 struct connman_element *element = node->data;
964 struct connman_driver *driver = data;
966 DBG("element %p name %s", element, element->name);
968 if (element->driver == driver) {
969 disable_element(element);
972 driver->remove(element);
974 __connman_element_lock(element);
975 element->driver = NULL;
976 __connman_element_unlock(element);
983 * connman_driver_unregister:
984 * @driver: driver definition
986 * Remove a previously registered driver
988 void connman_driver_unregister(struct connman_driver *driver)
990 DBG("driver %p name %s", driver, driver->name);
992 driver_list = g_slist_remove(driver_list, driver);
994 if (element_root != NULL)
995 g_node_traverse(element_root, G_POST_ORDER,
996 G_TRAVERSE_ALL, -1, remove_driver, driver);
1000 * connman_element_create:
1001 * @name: element name
1003 * Allocate a new element and assign the given #name to it. If the name
1004 * is #NULL, it will be later on created based on the element type.
1006 * Returns: a newly-allocated #connman_element structure
1008 struct connman_element *connman_element_create(const char *name)
1010 struct connman_element *element;
1012 element = g_try_new0(struct connman_element, 1);
1013 if (element == NULL)
1016 DBG("element %p", element);
1018 element->refcount = 1;
1020 element->name = g_strdup(name);
1021 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
1022 element->subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
1023 element->state = CONNMAN_ELEMENT_STATE_CLOSED;
1024 element->policy = CONNMAN_ELEMENT_POLICY_AUTO;
1025 element->index = -1;
1026 element->enabled = FALSE;
1031 struct connman_element *connman_element_ref(struct connman_element *element)
1033 DBG("element %p name %s refcount %d", element, element->name,
1034 g_atomic_int_get(&element->refcount) + 1);
1036 g_atomic_int_inc(&element->refcount);
1041 static void free_properties(struct connman_element *element)
1045 DBG("element %p name %s", element, element->name);
1047 __connman_element_lock(element);
1049 for (list = element->properties; list; list = list->next) {
1050 struct connman_property *property = list->data;
1052 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1053 g_free(property->value);
1055 g_free(property->name);
1059 g_slist_free(element->properties);
1061 element->properties = NULL;
1063 __connman_element_unlock(element);
1066 void connman_element_unref(struct connman_element *element)
1068 DBG("element %p name %s refcount %d", element, element->name,
1069 g_atomic_int_get(&element->refcount) - 1);
1071 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
1072 free_properties(element);
1073 g_free(element->ipv4.address);
1074 g_free(element->ipv4.netmask);
1075 g_free(element->ipv4.gateway);
1076 g_free(element->ipv4.network);
1077 g_free(element->ipv4.broadcast);
1078 g_free(element->ipv4.nameserver);
1079 g_free(element->devname);
1080 g_free(element->path);
1081 g_free(element->name);
1086 int connman_element_add_static_property(struct connman_element *element,
1087 const char *name, int type, const void *value)
1089 struct connman_property *property;
1091 DBG("element %p name %s", element, element->name);
1093 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
1096 property = g_try_new0(struct connman_property, 1);
1097 if (property == NULL)
1100 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1101 property->id = CONNMAN_PROPERTY_ID_INVALID;
1102 property->name = g_strdup(name);
1103 property->type = type;
1105 DBG("name %s type %d value %p", name, type, value);
1108 case DBUS_TYPE_STRING:
1109 property->value = g_strdup(*((const char **) value));
1111 case DBUS_TYPE_BYTE:
1112 property->value = g_try_malloc(1);
1113 if (property->value != NULL)
1114 memcpy(property->value, value, 1);
1118 __connman_element_lock(element);
1119 element->properties = g_slist_append(element->properties, property);
1120 __connman_element_unlock(element);
1125 int connman_element_add_static_array_property(struct connman_element *element,
1126 const char *name, int type, const void *value, int len)
1128 struct connman_property *property;
1130 DBG("element %p name %s", element, element->name);
1132 if (type != DBUS_TYPE_BYTE)
1135 property = g_try_new0(struct connman_property, 1);
1136 if (property == NULL)
1139 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
1140 property->id = CONNMAN_PROPERTY_ID_INVALID;
1141 property->name = g_strdup(name);
1142 property->type = DBUS_TYPE_ARRAY;
1143 property->subtype = type;
1145 DBG("name %s type %d value %p", name, type, value);
1148 case DBUS_TYPE_BYTE:
1149 property->value = g_try_malloc(len);
1150 if (property->value != NULL) {
1151 memcpy(property->value,
1152 *((const unsigned char **) value), len);
1153 property->size = len;
1158 __connman_element_lock(element);
1159 element->properties = g_slist_append(element->properties, property);
1160 __connman_element_unlock(element);
1165 static void *get_reference_value(struct connman_element *element,
1166 enum connman_property_id id)
1170 DBG("element %p name %s", element, element->name);
1172 for (list = element->properties; list; list = list->next) {
1173 struct connman_property *property = list->data;
1175 if (property->id != id)
1178 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1179 return property->value;
1182 if (element->parent == NULL)
1185 return get_reference_value(element->parent, id);
1188 static void set_reference_properties(struct connman_element *element)
1192 DBG("element %p name %s", element, element->name);
1194 for (list = element->properties; list; list = list->next) {
1195 struct connman_property *property = list->data;
1197 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
1200 property->value = get_reference_value(element->parent,
1205 static struct connman_property *create_property(struct connman_element *element,
1206 enum connman_property_id id)
1208 struct connman_property *property;
1211 DBG("element %p name %s", element, element->name);
1213 __connman_element_lock(element);
1215 for (list = element->properties; list; list = list->next) {
1216 property = list->data;
1218 if (property->id == id)
1222 property = g_try_new0(struct connman_property, 1);
1223 if (property == NULL)
1226 property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
1228 property->name = g_strdup(propid2name(id));
1229 property->type = propid2type(id);
1231 if (property->name == NULL) {
1237 element->properties = g_slist_append(element->properties, property);
1240 __connman_element_unlock(element);
1245 static void create_default_properties(struct connman_element *element)
1247 struct connman_property *property;
1250 DBG("element %p name %s", element, element->name);
1252 for (i = 0; propid_table[i].name; i++) {
1253 DBG("property %s", propid_table[i].name);
1255 property = create_property(element, propid_table[i].id);
1257 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
1259 if (propid_table[i].type != DBUS_TYPE_STRING)
1262 if (propid_table[i].value)
1263 property->value = g_strdup(propid_table[i].value);
1265 property->value = g_strdup("");
1269 static int define_properties_valist(struct connman_element *element,
1272 enum connman_property_id id;
1274 DBG("element %p name %s", element, element->name);
1276 id = va_arg(args, enum connman_property_id);
1278 while (id != CONNMAN_PROPERTY_ID_INVALID) {
1280 DBG("property %d", id);
1282 create_property(element, id);
1284 id = va_arg(args, enum connman_property_id);
1291 * connman_element_define_properties:
1292 * @element: an element
1293 * @varargs: list of property identifiers
1295 * Define the valid properties for an element.
1297 * Returns: %0 on success
1299 int connman_element_define_properties(struct connman_element *element, ...)
1304 DBG("element %p name %s", element, element->name);
1306 va_start(args, element);
1308 err = define_properties_valist(element, args);
1315 int connman_element_create_property(struct connman_element *element,
1316 const char *name, int type)
1321 int connman_element_set_property(struct connman_element *element,
1322 enum connman_property_id id, const void *value)
1325 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1326 __connman_element_lock(element);
1327 g_free(element->ipv4.address);
1328 element->ipv4.address = g_strdup(*((const char **) value));
1329 __connman_element_unlock(element);
1331 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1332 __connman_element_lock(element);
1333 g_free(element->ipv4.netmask);
1334 element->ipv4.netmask = g_strdup(*((const char **) value));
1335 __connman_element_unlock(element);
1337 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1338 __connman_element_lock(element);
1339 g_free(element->ipv4.gateway);
1340 element->ipv4.gateway = g_strdup(*((const char **) value));
1341 __connman_element_unlock(element);
1343 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1344 __connman_element_lock(element);
1345 g_free(element->ipv4.nameserver);
1346 element->ipv4.nameserver = g_strdup(*((const char **) value));
1347 __connman_element_unlock(element);
1349 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1350 __connman_element_lock(element);
1351 g_free(element->wifi.security);
1352 element->wifi.security = g_strdup(*((const char **) value));
1353 __connman_element_unlock(element);
1355 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1356 __connman_element_lock(element);
1357 g_free(element->wifi.passphrase);
1358 element->wifi.passphrase = g_strdup(*((const char **) value));
1359 __connman_element_unlock(element);
1368 int connman_element_get_value(struct connman_element *element,
1369 enum connman_property_id id, void *value)
1371 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1375 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
1376 if (element->ipv4.address == NULL)
1377 return connman_element_get_value(element->parent,
1379 __connman_element_lock(element);
1380 *((char **) value) = element->ipv4.address;
1381 __connman_element_unlock(element);
1383 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
1384 if (element->ipv4.netmask == NULL)
1385 return connman_element_get_value(element->parent,
1387 __connman_element_lock(element);
1388 *((char **) value) = element->ipv4.netmask;
1389 __connman_element_unlock(element);
1391 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1392 if (element->ipv4.gateway == NULL)
1393 return connman_element_get_value(element->parent,
1395 __connman_element_lock(element);
1396 *((char **) value) = element->ipv4.gateway;
1397 __connman_element_unlock(element);
1399 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1400 if (element->ipv4.nameserver == NULL)
1401 return connman_element_get_value(element->parent,
1403 __connman_element_lock(element);
1404 *((char **) value) = element->ipv4.nameserver;
1405 __connman_element_unlock(element);
1407 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1408 if (element->wifi.security == NULL)
1409 return connman_element_get_value(element->parent,
1411 __connman_element_lock(element);
1412 *((char **) value) = element->wifi.security;
1413 __connman_element_unlock(element);
1415 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1416 if (element->wifi.passphrase == NULL)
1417 return connman_element_get_value(element->parent,
1419 __connman_element_lock(element);
1420 *((char **) value) = element->wifi.passphrase;
1421 __connman_element_unlock(element);
1430 gboolean connman_element_get_static_property(struct connman_element *element,
1431 const char *name, void *value)
1434 gboolean found = FALSE;
1436 DBG("element %p name %s", element, element->name);
1438 __connman_element_lock(element);
1440 for (list = element->properties; list; list = list->next) {
1441 struct connman_property *property = list->data;
1443 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1446 if (g_str_equal(property->name, name) == TRUE) {
1447 switch (property->type) {
1448 case DBUS_TYPE_STRING:
1449 *((char **) value) = property->value;
1457 __connman_element_unlock(element);
1462 gboolean connman_element_get_static_array_property(struct connman_element *element,
1463 const char *name, void *value, int *len)
1466 gboolean found = FALSE;
1468 DBG("element %p name %s", element, element->name);
1470 __connman_element_lock(element);
1472 for (list = element->properties; list; list = list->next) {
1473 struct connman_property *property = list->data;
1475 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1478 if (g_str_equal(property->name, name) == TRUE) {
1479 *((char **) value) = property->value;
1480 *len = property->size;
1486 __connman_element_unlock(element);
1491 gboolean connman_element_match_static_property(struct connman_element *element,
1492 const char *name, const void *value)
1495 gboolean result = FALSE;
1497 DBG("element %p name %s", element, element->name);
1499 __connman_element_lock(element);
1501 for (list = element->properties; list; list = list->next) {
1502 struct connman_property *property = list->data;
1504 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1507 if (g_str_equal(property->name, name) == FALSE)
1510 if (property->type == DBUS_TYPE_STRING)
1511 result = g_str_equal(property->value,
1512 *((const char **) value));
1518 __connman_element_unlock(element);
1523 static void append_devices(DBusMessageIter *entry)
1525 DBusMessageIter value, iter;
1526 const char *key = "Devices";
1528 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1530 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1531 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1534 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1535 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1537 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
1539 dbus_message_iter_close_container(&value, &iter);
1541 dbus_message_iter_close_container(entry, &value);
1544 static void emit_devices_signal(DBusConnection *conn)
1546 DBusMessage *signal;
1547 DBusMessageIter entry;
1549 DBG("conn %p", conn);
1551 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1552 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1556 dbus_message_iter_init_append(signal, &entry);
1558 append_devices(&entry);
1560 g_dbus_send_message(conn, signal);
1563 static void emit_networks_signal(DBusConnection *conn,
1564 struct connman_element *device)
1566 DBusMessage *signal;
1567 DBusMessageIter entry;
1569 DBG("conn %p", conn);
1574 signal = dbus_message_new_signal(device->path,
1575 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
1579 dbus_message_iter_init_append(signal, &entry);
1581 append_networks(device, &entry);
1583 g_dbus_send_message(conn, signal);
1586 static void append_connections(DBusMessageIter *entry)
1588 DBusMessageIter value, iter;
1589 const char *key = "Connections";
1591 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1593 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1594 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1597 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1598 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1600 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
1602 dbus_message_iter_close_container(&value, &iter);
1604 dbus_message_iter_close_container(entry, &value);
1607 static void emit_connections_signal(DBusConnection *conn)
1609 DBusMessage *signal;
1610 DBusMessageIter entry;
1612 DBG("conn %p", conn);
1614 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1615 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1619 dbus_message_iter_init_append(signal, &entry);
1621 append_connections(&entry);
1623 g_dbus_send_message(conn, signal);
1626 static void append_state(DBusMessageIter *entry, const char *state)
1628 DBusMessageIter value;
1629 const char *key = "State";
1631 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1633 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1634 DBUS_TYPE_STRING_AS_STRING, &value);
1636 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1638 dbus_message_iter_close_container(entry, &value);
1641 static void emit_state_change(DBusConnection *conn, const char *state)
1643 DBusMessage *signal;
1644 DBusMessageIter entry;
1646 DBG("conn %p", conn);
1648 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1649 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1653 dbus_message_iter_init_append(signal, &entry);
1655 append_state(&entry, state);
1657 g_dbus_send_message(conn, signal);
1660 static void register_element(gpointer data, gpointer user_data)
1662 struct connman_element *element = data;
1663 const gchar *basepath;
1667 __connman_element_lock(element);
1669 if (element->parent) {
1670 node = g_node_find(element_root, G_PRE_ORDER,
1671 G_TRAVERSE_ALL, element->parent);
1672 basepath = element->parent->path;
1674 if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_UNKNOWN)
1675 element->subtype = element->parent->subtype;
1677 element->parent = element_root->data;
1679 node = element_root;
1683 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1685 set_reference_properties(element);
1687 __connman_element_unlock(element);
1689 DBG("element %p path %s", element, element->path);
1691 __connman_element_load(element);
1693 g_node_append_data(node, element);
1695 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1696 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1697 if (g_dbus_register_interface(connection, element->path,
1698 CONNMAN_DEVICE_INTERFACE,
1699 device_methods, element_signals,
1700 NULL, element, NULL) == FALSE)
1701 connman_error("Failed to register %s device",
1704 emit_devices_signal(connection);
1707 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1708 if (g_dbus_register_interface(connection, element->path,
1709 CONNMAN_NETWORK_INTERFACE,
1710 network_methods, element_signals,
1711 NULL, element, NULL) == FALSE)
1712 connman_error("Failed to register %s network",
1715 emit_networks_signal(connection, element->parent);
1718 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1719 if (g_dbus_register_interface(connection, element->path,
1720 CONNMAN_CONNECTION_INTERFACE,
1721 connection_methods, element_signals,
1722 NULL, element, NULL) == FALSE)
1723 connman_error("Failed to register %s connection",
1726 emit_connections_signal(connection);
1727 emit_state_change(connection, "online");
1731 __connman_element_store(element);
1733 for (list = driver_list; list; list = list->next) {
1734 struct connman_driver *driver = list->data;
1736 if (match_driver(element, driver) == FALSE)
1739 DBG("driver %p name %s", driver, driver->name);
1741 if (driver->probe(element) == 0) {
1742 __connman_element_lock(element);
1743 element->driver = driver;
1744 __connman_element_unlock(element);
1746 enable_element(element);
1753 * connman_element_register:
1754 * @element: the element to register
1755 * @parent: the parent to register the element with
1757 * Register an element with the core. It will be register under the given
1758 * parent of if %NULL is provided under the root element.
1760 * Returns: %0 on success
1762 int connman_element_register(struct connman_element *element,
1763 struct connman_element *parent)
1765 DBG("element %p name %s parent %p", element, element->name, parent);
1767 if (element->devname == NULL)
1768 element->devname = g_strdup(element->name);
1770 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1771 if (g_pattern_match_simple(device_filter,
1772 element->devname) == FALSE) {
1773 DBG("ignoring %s [%s] device", element->name,
1779 if (connman_element_ref(element) == NULL)
1782 __connman_element_lock(element);
1784 if (element->name == NULL) {
1785 element->name = g_strdup(type2string(element->type));
1786 if (element->name == NULL) {
1787 __connman_element_unlock(element);
1792 element->parent = parent;
1794 __connman_element_unlock(element);
1796 register_element(element, NULL);
1801 static gboolean remove_element(GNode *node, gpointer user_data)
1803 struct connman_element *element = node->data;
1804 struct connman_element *root = user_data;
1806 DBG("element %p name %s", element, element->name);
1808 if (element == root)
1811 if (element->driver) {
1812 disable_element(element);
1814 if (element->driver->remove)
1815 element->driver->remove(element);
1817 __connman_element_lock(element);
1818 element->driver = NULL;
1819 __connman_element_unlock(element);
1823 g_node_unlink(node);
1824 g_node_destroy(node);
1827 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1828 emit_state_change(connection, "offline");
1829 emit_connections_signal(connection);
1831 g_dbus_unregister_interface(connection, element->path,
1832 CONNMAN_CONNECTION_INTERFACE);
1835 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1836 emit_networks_signal(connection, element->parent);
1838 g_dbus_unregister_interface(connection, element->path,
1839 CONNMAN_NETWORK_INTERFACE);
1842 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
1843 element->subtype != CONNMAN_ELEMENT_SUBTYPE_NETWORK) {
1844 emit_devices_signal(connection);
1846 g_dbus_unregister_interface(connection, element->path,
1847 CONNMAN_DEVICE_INTERFACE);
1850 connman_element_unref(element);
1855 void connman_element_unregister(struct connman_element *element)
1859 DBG("element %p name %s", element, element->name);
1861 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1864 g_node_traverse(node, G_POST_ORDER,
1865 G_TRAVERSE_ALL, -1, remove_element, NULL);
1868 void connman_element_unregister_children(struct connman_element *element)
1872 DBG("element %p name %s", element, element->name);
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);
1881 static gboolean update_element(GNode *node, gpointer user_data)
1883 struct connman_element *element = node->data;
1885 DBG("element %p name %s", element, element->name);
1887 if (element->driver && element->driver->update)
1888 element->driver->update(element);
1893 void connman_element_update(struct connman_element *element)
1897 DBG("element %p name %s", element, element->name);
1899 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1902 g_node_traverse(node, G_PRE_ORDER,
1903 G_TRAVERSE_ALL, -1, update_element, NULL);
1906 int connman_element_set_enabled(struct connman_element *element,
1909 if (element->enabled == enabled)
1912 element->enabled = enabled;
1914 connman_element_update(element);
1919 int __connman_element_init(DBusConnection *conn, const char *device)
1921 struct connman_element *element;
1923 DBG("conn %p", conn);
1925 connection = dbus_connection_ref(conn);
1926 if (connection == NULL)
1929 device_filter = g_strdup(device);
1931 element = connman_element_create("root");
1933 element->path = g_strdup("/");
1934 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1936 create_default_properties(element);
1938 element_root = g_node_new(element);
1940 __connman_device_init();
1945 static gboolean free_driver(GNode *node, gpointer data)
1947 struct connman_element *element = node->data;
1949 DBG("element %p name %s", element, element->name);
1951 if (element->driver) {
1952 disable_element(element);
1954 if (element->driver->remove)
1955 element->driver->remove(element);
1957 __connman_element_lock(element);
1958 element->driver = NULL;
1959 __connman_element_unlock(element);
1965 static gboolean free_node(GNode *node, gpointer data)
1967 struct connman_element *element = node->data;
1969 DBG("element %p name %s", element, element->name);
1971 if (g_node_depth(node) > 1)
1972 connman_element_unregister(element);
1977 void __connman_element_cleanup(void)
1981 __connman_device_cleanup();
1983 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1986 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1989 g_node_destroy(element_root);
1990 element_root = NULL;
1992 g_free(device_filter);
1994 dbus_connection_unref(connection);