5 * Copyright (C) 2007-2010 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;
40 static gchar **nodevice_filter = NULL;
42 static gboolean started = FALSE;
44 static const char *type2string(enum connman_element_type type)
47 case CONNMAN_ELEMENT_TYPE_UNKNOWN:
49 case CONNMAN_ELEMENT_TYPE_ROOT:
51 case CONNMAN_ELEMENT_TYPE_PROFILE:
53 case CONNMAN_ELEMENT_TYPE_DEVICE:
55 case CONNMAN_ELEMENT_TYPE_NETWORK:
57 case CONNMAN_ELEMENT_TYPE_SERVICE:
59 case CONNMAN_ELEMENT_TYPE_IPV6:
61 case CONNMAN_ELEMENT_TYPE_BOOTP:
63 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
65 case CONNMAN_ELEMENT_TYPE_VENDOR:
73 enum connman_element_type type;
74 element_cb_t callback;
78 static gboolean foreach_callback(GNode *node, gpointer user_data)
80 struct connman_element *element = node->data;
81 struct foreach_data *data = user_data;
83 DBG("element %p name %s", element, element->name);
85 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
88 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
89 data->type != element->type)
93 data->callback(element, data->user_data);
98 void __connman_element_foreach(struct connman_element *element,
99 enum connman_element_type type,
100 element_cb_t callback, gpointer user_data)
102 struct foreach_data data = { type, callback, user_data };
107 if (element != NULL) {
108 node = g_node_find(element_root, G_PRE_ORDER,
109 G_TRAVERSE_ALL, element);
115 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
116 foreach_callback, &data);
119 struct append_filter {
120 enum connman_element_type type;
121 DBusMessageIter *iter;
124 static gboolean append_path(GNode *node, gpointer user_data)
126 struct connman_element *element = node->data;
127 struct append_filter *filter = user_data;
129 DBG("element %p name %s", element, element->name);
131 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
134 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
135 filter->type != element->type)
138 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
139 __connman_device_has_driver(element->device) == FALSE)
142 if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
143 __connman_network_has_driver(element->network) == FALSE)
146 dbus_message_iter_append_basic(filter->iter,
147 DBUS_TYPE_OBJECT_PATH, &element->path);
152 void __connman_element_list(struct connman_element *element,
153 enum connman_element_type type,
154 DBusMessageIter *iter)
156 struct append_filter filter = { type, iter };
161 if (element != NULL) {
162 node = g_node_find(element_root, G_PRE_ORDER,
163 G_TRAVERSE_ALL, element);
169 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
170 append_path, &filter);
173 static struct connman_network *get_network(struct connman_element *element)
175 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
176 element->network != NULL)
177 return element->network;
179 if (element->parent == NULL)
182 return get_network(element->parent);
185 struct connman_service *__connman_element_get_service(struct connman_element *element)
187 struct connman_service *service = NULL;
188 struct connman_network *network;
189 struct connman_device *device;
190 enum connman_device_type type;
192 device = __connman_element_get_device(element);
193 if (device == NULL) {
194 /* Workaround for the connection removal. */
195 service = __connman_service_lookup_from_index(element->index);
199 type = connman_device_get_type(device);
202 case CONNMAN_DEVICE_TYPE_UNKNOWN:
203 case CONNMAN_DEVICE_TYPE_VENDOR:
204 case CONNMAN_DEVICE_TYPE_GPS:
205 case CONNMAN_DEVICE_TYPE_GADGET:
207 case CONNMAN_DEVICE_TYPE_ETHERNET:
208 case CONNMAN_DEVICE_TYPE_WIFI:
209 case CONNMAN_DEVICE_TYPE_WIMAX:
210 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
211 case CONNMAN_DEVICE_TYPE_CELLULAR:
212 network = get_network(element);
215 service = __connman_service_lookup_from_network(network);
222 struct connman_device *__connman_element_get_device(struct connman_element *element)
224 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
225 element->device != NULL)
226 return element->device;
228 if (element->parent == NULL)
231 return __connman_element_get_device(element->parent);
235 enum connman_service_type type;
236 struct connman_device *device;
237 connman_bool_t error;
240 static gboolean find_device(GNode *node, gpointer user_data)
242 struct connman_element *element = node->data;
243 struct find_data *data = user_data;
245 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
248 if (element->device == NULL)
251 if (data->type != __connman_device_get_service_type(element->device))
254 data->device = element->device;
259 struct connman_device *__connman_element_find_device(enum connman_service_type type)
261 struct find_data data = { .type = type, .device = NULL };
263 g_node_traverse(element_root, G_PRE_ORDER,
264 G_TRAVERSE_ALL, -1, find_device, &data);
269 static gboolean request_scan(GNode *node, gpointer user_data)
271 struct connman_element *element = node->data;
272 struct find_data *data = user_data;
273 enum connman_service_type type;
275 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
278 if (element->device == NULL)
281 type = __connman_device_get_service_type(element->device);
284 case CONNMAN_SERVICE_TYPE_UNKNOWN:
285 case CONNMAN_SERVICE_TYPE_SYSTEM:
286 case CONNMAN_SERVICE_TYPE_ETHERNET:
287 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
288 case CONNMAN_SERVICE_TYPE_CELLULAR:
289 case CONNMAN_SERVICE_TYPE_GPS:
290 case CONNMAN_SERVICE_TYPE_VPN:
291 case CONNMAN_SERVICE_TYPE_GADGET:
293 case CONNMAN_SERVICE_TYPE_WIFI:
294 case CONNMAN_SERVICE_TYPE_WIMAX:
295 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
301 __connman_device_scan(element->device);
306 int __connman_element_request_scan(enum connman_service_type type)
308 struct find_data data = { .type = type, .device = NULL };
310 g_node_traverse(element_root, G_PRE_ORDER,
311 G_TRAVERSE_ALL, -1, request_scan, &data);
316 static gboolean enable_technology(GNode *node, gpointer user_data)
318 struct connman_element *element = node->data;
319 struct find_data *data = user_data;
320 enum connman_service_type type;
323 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
326 if (element->device == NULL)
329 type = __connman_device_get_service_type(element->device);
332 case CONNMAN_SERVICE_TYPE_UNKNOWN:
333 case CONNMAN_SERVICE_TYPE_SYSTEM:
334 case CONNMAN_SERVICE_TYPE_GPS:
335 case CONNMAN_SERVICE_TYPE_VPN:
336 case CONNMAN_SERVICE_TYPE_GADGET:
338 case CONNMAN_SERVICE_TYPE_ETHERNET:
339 case CONNMAN_SERVICE_TYPE_WIFI:
340 case CONNMAN_SERVICE_TYPE_WIMAX:
341 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
342 case CONNMAN_SERVICE_TYPE_CELLULAR:
343 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
349 err = __connman_device_enable_persistent(element->device);
350 if (err == 0 || (err < 0 && err == -EINPROGRESS))
356 int __connman_element_enable_technology(enum connman_service_type type)
358 struct find_data data = { .type = type, .device = NULL, .error = TRUE };
360 g_node_traverse(element_root, G_PRE_ORDER,
361 G_TRAVERSE_ALL, -1, enable_technology, &data);
363 if (data.error == TRUE)
369 static gboolean disable_technology(GNode *node, gpointer user_data)
371 struct connman_element *element = node->data;
372 struct find_data *data = user_data;
373 enum connman_service_type type;
376 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
379 if (element->device == NULL)
382 type = __connman_device_get_service_type(element->device);
385 case CONNMAN_SERVICE_TYPE_UNKNOWN:
386 case CONNMAN_SERVICE_TYPE_SYSTEM:
387 case CONNMAN_SERVICE_TYPE_GPS:
388 case CONNMAN_SERVICE_TYPE_VPN:
389 case CONNMAN_SERVICE_TYPE_GADGET:
391 case CONNMAN_SERVICE_TYPE_ETHERNET:
392 case CONNMAN_SERVICE_TYPE_WIFI:
393 case CONNMAN_SERVICE_TYPE_WIMAX:
394 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
395 case CONNMAN_SERVICE_TYPE_CELLULAR:
396 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
402 err = __connman_device_disable_persistent(element->device);
403 if (err == 0 || (err < 0 && err == -EINPROGRESS))
409 int __connman_element_disable_technology(enum connman_service_type type)
411 struct find_data data = { .type = type, .device = NULL, .error = TRUE };
413 g_node_traverse(element_root, G_PRE_ORDER,
414 G_TRAVERSE_ALL, -1, disable_technology, &data);
416 if (data.error == TRUE)
422 static gint compare_priority(gconstpointer a, gconstpointer b)
424 const struct connman_driver *driver1 = a;
425 const struct connman_driver *driver2 = b;
427 return driver2->priority - driver1->priority;
430 static gboolean match_driver(struct connman_element *element,
431 struct connman_driver *driver)
433 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
436 if (element->type == driver->type ||
437 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
443 static gboolean probe_driver(GNode *node, gpointer data)
445 struct connman_element *element = node->data;
446 struct connman_driver *driver = data;
448 DBG("element %p name %s", element, element->name);
450 if (!element->driver && match_driver(element, driver) == TRUE) {
451 if (driver->probe(element) < 0)
454 element->driver = driver;
460 void __connman_driver_rescan(struct connman_driver *driver)
462 DBG("driver %p name %s", driver, driver->name);
467 if (element_root != NULL)
468 g_node_traverse(element_root, G_PRE_ORDER,
469 G_TRAVERSE_ALL, -1, probe_driver, driver);
473 * connman_driver_register:
474 * @driver: driver definition
476 * Register a new driver
478 * Returns: %0 on success
480 int connman_driver_register(struct connman_driver *driver)
482 DBG("driver %p name %s", driver, driver->name);
484 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
490 driver_list = g_slist_insert_sorted(driver_list, driver,
493 if (started == FALSE)
496 if (element_root != NULL)
497 g_node_traverse(element_root, G_PRE_ORDER,
498 G_TRAVERSE_ALL, -1, probe_driver, driver);
503 static gboolean remove_driver(GNode *node, gpointer data)
505 struct connman_element *element = node->data;
506 struct connman_driver *driver = data;
508 DBG("element %p name %s", element, element->name);
510 if (element->driver == driver) {
512 driver->remove(element);
514 element->driver = NULL;
521 * connman_driver_unregister:
522 * @driver: driver definition
524 * Remove a previously registered driver
526 void connman_driver_unregister(struct connman_driver *driver)
528 DBG("driver %p name %s", driver, driver->name);
530 driver_list = g_slist_remove(driver_list, driver);
532 if (element_root != NULL)
533 g_node_traverse(element_root, G_POST_ORDER,
534 G_TRAVERSE_ALL, -1, remove_driver, driver);
537 static void unregister_property(gpointer data)
539 struct connman_property *property = data;
541 DBG("property %p", property);
543 g_free(property->value);
547 static void unregister_child(gpointer data)
549 struct connman_element *element = data;
551 DBG("element %p", element);
553 connman_element_unref(element);
556 void __connman_element_initialize(struct connman_element *element)
558 DBG("element %p", element);
560 element->refcount = 1;
562 element->name = NULL;
563 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
564 element->state = CONNMAN_ELEMENT_STATE_UNKNOWN;
565 element->error = CONNMAN_ELEMENT_ERROR_UNKNOWN;
567 element->enabled = FALSE;
569 element->children = g_hash_table_new_full(g_str_hash, g_str_equal,
570 NULL, unregister_child);
572 element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
573 g_free, unregister_property);
577 * connman_element_create:
578 * @name: element name
580 * Allocate a new element and assign the given #name to it. If the name
581 * is #NULL, it will be later on created based on the element type.
583 * Returns: a newly-allocated #connman_element structure
585 struct connman_element *connman_element_create(const char *name)
587 struct connman_element *element;
589 element = g_try_new0(struct connman_element, 1);
593 DBG("element %p", element);
595 __connman_element_initialize(element);
597 element->name = g_strdup(name);
602 struct connman_element *connman_element_ref(struct connman_element *element)
604 DBG("element %p name %s refcount %d", element, element->name,
605 g_atomic_int_get(&element->refcount) + 1);
607 g_atomic_int_inc(&element->refcount);
612 static void free_properties(struct connman_element *element)
614 DBG("element %p name %s", element, element->name);
616 g_hash_table_destroy(element->properties);
617 element->properties = NULL;
620 static void free_children(struct connman_element *element)
622 DBG("element %p name %s", element, element->name);
624 g_hash_table_destroy(element->children);
625 element->children = NULL;
628 void connman_element_unref(struct connman_element *element)
630 DBG("element %p name %s refcount %d", element, element->name,
631 g_atomic_int_get(&element->refcount) - 1);
633 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
634 if (element->destruct)
635 element->destruct(element);
636 free_children(element);
637 free_properties(element);
638 g_free(element->hostname);
639 g_free(element->domainname);
640 g_free(element->ipv6.address);
641 g_free(element->ipv6.network);
642 g_free(element->devname);
643 g_free(element->path);
644 g_free(element->name);
649 static int set_static_property(struct connman_element *element,
650 const char *name, int type, const void *value)
652 struct connman_property *property;
654 DBG("element %p name %s", element, element->name);
656 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
659 property = g_try_new0(struct connman_property, 1);
660 if (property == NULL)
663 property->id = CONNMAN_PROPERTY_ID_INVALID;
664 property->type = type;
666 DBG("name %s type %d value %p", name, type, value);
669 case DBUS_TYPE_STRING:
670 property->value = g_strdup(*((const char **) value));
672 case DBUS_TYPE_BOOLEAN:
674 property->value = g_try_malloc(1);
675 if (property->value != NULL)
676 memcpy(property->value, value, 1);
680 g_hash_table_replace(element->properties, g_strdup(name), property);
685 static int set_static_array_property(struct connman_element *element,
686 const char *name, int type, const void *value, int len)
688 struct connman_property *property;
690 DBG("element %p name %s", element, element->name);
692 if (type != DBUS_TYPE_BYTE)
695 property = g_try_new0(struct connman_property, 1);
696 if (property == NULL)
699 property->id = CONNMAN_PROPERTY_ID_INVALID;
700 property->type = DBUS_TYPE_ARRAY;
701 property->subtype = type;
703 DBG("name %s type %d value %p", name, type, value);
707 property->value = g_try_malloc(len);
708 if (property->value != NULL) {
709 memcpy(property->value,
710 *((const unsigned char **) value), len);
711 property->size = len;
716 g_hash_table_replace(element->properties, g_strdup(name), property);
721 int connman_element_get_value(struct connman_element *element,
722 enum connman_property_id id, void *value)
724 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
728 case CONNMAN_PROPERTY_ID_HOSTNAME:
729 if (element->hostname == NULL)
730 return connman_element_get_value(element->parent,
732 *((char **) value) = element->hostname;
734 case CONNMAN_PROPERTY_ID_DOMAINNAME:
735 if (element->domainname == NULL)
736 return connman_element_get_value(element->parent,
738 *((char **) value) = element->domainname;
740 case CONNMAN_PROPERTY_ID_IPV6_GATEWAY:
741 if (element->ipv6.gateway == NULL)
742 return connman_element_get_value(element->parent,
744 *((char **) value) = element->ipv6.gateway;
754 static gboolean get_static_property(struct connman_element *element,
755 const char *name, void *value)
757 struct connman_property *property;
758 gboolean found = FALSE;
760 DBG("element %p name %s", element, element->name);
762 property = g_hash_table_lookup(element->properties, name);
763 if (property != NULL) {
764 switch (property->type) {
765 case DBUS_TYPE_STRING:
766 *((char **) value) = property->value;
769 case DBUS_TYPE_BOOLEAN:
771 memcpy(value, property->value, 1);
777 if (found == FALSE && element->parent != NULL)
778 return get_static_property(element->parent, name, value);
783 static gboolean get_static_array_property(struct connman_element *element,
784 const char *name, void *value, unsigned int *len)
786 struct connman_property *property;
787 gboolean found = FALSE;
789 DBG("element %p name %s", element, element->name);
791 property = g_hash_table_lookup(element->properties, name);
792 if (property != NULL) {
793 *((void **) value) = property->value;
794 *len = property->size;
802 * connman_element_set_string:
803 * @element: element structure
804 * @key: unique identifier
805 * @value: string value
807 * Set string value for specific key
809 int connman_element_set_string(struct connman_element *element,
810 const char *key, const char *value)
812 return set_static_property(element, key, DBUS_TYPE_STRING, &value);
816 * connman_element_get_string:
817 * @element: element structure
818 * @key: unique identifier
820 * Get string value for specific key
822 const char *connman_element_get_string(struct connman_element *element,
827 if (get_static_property(element, key, &value) == FALSE)
834 * connman_element_set_bool:
835 * @element: element structure
836 * @key: unique identifier
837 * @value: boolean value
839 * Set boolean value for specific key
841 int connman_element_set_bool(struct connman_element *element,
842 const char *key, connman_bool_t value)
844 return set_static_property(element, key, DBUS_TYPE_BOOLEAN, &value);
848 * connman_element_get_bool:
849 * @element: element structure
850 * @key: unique identifier
852 * Get boolean value for specific key
854 connman_bool_t connman_element_get_bool(struct connman_element *element,
857 connman_bool_t value;
859 if (get_static_property(element, key, &value) == FALSE)
866 * connman_element_set_uint8:
867 * @element: element structure
868 * @key: unique identifier
869 * @value: integer value
871 * Set integer value for specific key
873 int connman_element_set_uint8(struct connman_element *element,
874 const char *key, connman_uint8_t value)
876 return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
880 * connman_element_get_uint8:
881 * @element: element structure
882 * @key: unique identifier
884 * Get integer value for specific key
886 connman_uint8_t connman_element_get_uint8(struct connman_element *element,
889 connman_uint8_t value;
891 if (get_static_property(element, key, &value) == FALSE)
898 * connman_element_set_blob:
899 * @element: element structure
900 * @key: unique identifier
904 * Set binary blob value for specific key
906 int connman_element_set_blob(struct connman_element *element,
907 const char *key, const void *data, unsigned int size)
909 return set_static_array_property(element, key,
910 DBUS_TYPE_BYTE, &data, size);
914 * connman_element_get_blob:
915 * @element: element structure
916 * @key: unique identifier
917 * @size: pointer to blob size
919 * Get binary blob value for specific key
921 const void *connman_element_get_blob(struct connman_element *element,
922 const char *key, unsigned int *size)
926 if (get_static_array_property(element, key, &value, size) == FALSE)
932 static void probe_element(struct connman_element *element)
936 DBG("element %p name %s", element, element->name);
938 for (list = driver_list; list; list = list->next) {
939 struct connman_driver *driver = list->data;
941 if (match_driver(element, driver) == FALSE)
944 DBG("driver %p name %s", driver, driver->name);
946 if (driver->probe(element) == 0) {
947 element->driver = driver;
953 static void register_element(gpointer data, gpointer user_data)
955 struct connman_element *element = data;
956 const gchar *basepath;
959 if (element->parent) {
960 node = g_node_find(element_root, G_PRE_ORDER,
961 G_TRAVERSE_ALL, element->parent);
962 basepath = element->parent->path;
964 element->parent = element_root->data;
967 basepath = CONNMAN_PATH "/device";
970 element->path = g_strdup_printf("%s/%s", basepath, element->name);
973 connman_error("Element registration for %s failed",
978 DBG("element %p path %s", element, element->path);
980 g_node_append_data(node, element);
982 if (started == FALSE)
985 probe_element(element);
988 gboolean __connman_element_device_isfiltered(const char *devname)
992 if (device_filter == NULL)
995 for (pattern = device_filter; *pattern; pattern++) {
996 if (g_pattern_match_simple(*pattern, devname) == FALSE) {
997 DBG("ignoring device %s (match)", devname);
1003 if (nodevice_filter == NULL)
1006 for (pattern = nodevice_filter; *pattern; pattern++) {
1007 if (g_pattern_match_simple(*pattern, devname) == TRUE) {
1008 DBG("ignoring device %s (no match)", devname);
1017 * connman_element_register:
1018 * @element: the element to register
1019 * @parent: the parent to register the element with
1021 * Register an element with the core. It will be register under the given
1022 * parent of if %NULL is provided under the root element.
1024 * Returns: %0 on success
1026 int connman_element_register(struct connman_element *element,
1027 struct connman_element *parent)
1029 DBG("element %p name %s parent %p", element, element->name, parent);
1031 if (element->devname == NULL)
1032 element->devname = g_strdup(element->name);
1034 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
1037 if (__connman_element_device_isfiltered(element->devname) == TRUE)
1041 if (connman_element_ref(element) == NULL)
1044 if (element->name == NULL) {
1045 element->name = g_strdup(type2string(element->type));
1046 if (element->name == NULL) {
1051 element->parent = parent;
1053 register_element(element, NULL);
1058 static gboolean remove_element(GNode *node, gpointer user_data)
1060 struct connman_element *element = node->data;
1061 struct connman_element *root = user_data;
1063 DBG("element %p name %s", element, element->name);
1065 if (element == root)
1068 g_node_unlink(node);
1070 if (element->driver) {
1071 if (element->driver->remove)
1072 element->driver->remove(element);
1074 element->driver = NULL;
1077 g_node_destroy(node);
1079 connman_element_unref(element);
1084 struct unregister_type {
1085 struct connman_element *root;
1086 enum connman_element_type type;
1089 static gboolean remove_element_type(GNode *node, gpointer user_data)
1091 struct unregister_type *children_type = user_data;
1092 struct connman_element *root = children_type->root;
1093 struct connman_element *element = node->data;
1094 enum connman_element_type type = children_type->type;
1096 DBG("element %p name %s", element, element->name);
1098 if (element == root)
1101 if(element->type != type)
1104 g_node_unlink(node);
1106 if (element->driver) {
1107 if (element->driver->remove)
1108 element->driver->remove(element);
1110 element->driver = NULL;
1113 g_node_destroy(node);
1115 connman_element_unref(element);
1121 void connman_element_unregister(struct connman_element *element)
1125 DBG("element %p name %s", element, element->name);
1127 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1130 g_node_traverse(node, G_POST_ORDER,
1131 G_TRAVERSE_ALL, -1, remove_element, NULL);
1134 void connman_element_unregister_children(struct connman_element *element)
1138 DBG("element %p name %s", element, element->name);
1140 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1143 g_node_traverse(node, G_POST_ORDER,
1144 G_TRAVERSE_ALL, -1, remove_element, element);
1147 void connman_element_unregister_children_type(struct connman_element *element, enum connman_element_type type)
1151 DBG("element %p name %s", element, element->name);
1153 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1156 struct unregister_type children_type;
1158 children_type.root = element;
1159 children_type.type = type;
1160 g_node_traverse(node, G_POST_ORDER,
1161 G_TRAVERSE_ALL, -1, remove_element_type, &children_type);
1166 static gboolean update_element(GNode *node, gpointer user_data)
1168 struct connman_element *element = node->data;
1170 DBG("element %p name %s", element, element->name);
1172 if (element->driver && element->driver->update)
1173 element->driver->update(element);
1178 void connman_element_update(struct connman_element *element)
1182 DBG("element %p name %s", element, element->name);
1184 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1187 g_node_traverse(node, G_PRE_ORDER,
1188 G_TRAVERSE_ALL, -1, update_element, element);
1191 int connman_element_set_enabled(struct connman_element *element,
1194 if (element->enabled == enabled)
1197 element->enabled = enabled;
1199 connman_element_update(element);
1204 static enum connman_service_error convert_error(enum connman_element_error error)
1207 case CONNMAN_ELEMENT_ERROR_UNKNOWN:
1208 case CONNMAN_ELEMENT_ERROR_FAILED:
1210 case CONNMAN_ELEMENT_ERROR_DHCP_FAILED:
1211 return CONNMAN_SERVICE_ERROR_DHCP_FAILED;
1212 case CONNMAN_ELEMENT_ERROR_CONNECT_FAILED:
1213 return CONNMAN_SERVICE_ERROR_CONNECT_FAILED;
1216 return CONNMAN_SERVICE_ERROR_UNKNOWN;
1220 * connman_element_set_error:
1221 * @element: element structure
1222 * @error: error identifier
1224 * Set error state and specific error identifier
1226 void connman_element_set_error(struct connman_element *element,
1227 enum connman_element_error error)
1229 struct connman_service *service;
1231 DBG("element %p error %d", element, error);
1233 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1236 element->state = CONNMAN_ELEMENT_STATE_ERROR;
1237 element->error = error;
1239 if (element->driver && element->driver->change)
1240 element->driver->change(element);
1242 service = __connman_element_get_service(element);
1243 __connman_service_indicate_error(service, convert_error(error));
1246 void __connman_element_set_driver(struct connman_element *element)
1250 DBG("element %p name %s driver %p", element, element->name,
1253 if (element->driver)
1256 for (list = driver_list; list; list = list->next) {
1257 struct connman_driver *driver = list->data;
1259 if (match_driver(element, driver) == FALSE)
1262 element->driver = driver;
1268 int __connman_element_init(const char *device, const char *nodevice)
1270 struct connman_element *element;
1274 connection = connman_dbus_get_connection();
1275 if (connection == NULL)
1279 device_filter = g_strsplit(device, ",", -1);
1282 nodevice_filter = g_strsplit(nodevice, ",", -1);
1284 element = connman_element_create("root");
1286 element->path = g_strdup("/");
1287 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1289 element_root = g_node_new(element);
1291 __connman_technology_init();
1292 __connman_notifier_init();
1293 __connman_location_init();
1294 __connman_service_init();
1295 __connman_provider_init();
1296 __connman_network_init();
1297 __connman_device_init();
1302 static gboolean probe_node(GNode *node, gpointer data)
1304 struct connman_element *element = node->data;
1306 DBG("element %p name %s", element, element->name);
1308 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1311 if (element->driver)
1314 probe_element(element);
1319 void __connman_element_start(void)
1323 __connman_storage_init_profile();
1325 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1330 __connman_rtnl_start();
1332 __connman_dhcp_init();
1333 __connman_wpad_init();
1334 __connman_wispr_init();
1336 __connman_rfkill_init();
1339 void __connman_element_stop(void)
1343 __connman_rfkill_cleanup();
1345 __connman_wispr_cleanup();
1346 __connman_wpad_cleanup();
1347 __connman_dhcp_cleanup();
1348 __connman_provider_cleanup();
1351 static gboolean free_driver(GNode *node, gpointer data)
1353 struct connman_element *element = node->data;
1355 DBG("element %p name %s", element, element->name);
1357 if (element->driver) {
1358 if (element->driver->remove)
1359 element->driver->remove(element);
1361 element->driver = NULL;
1367 static gboolean free_node(GNode *node, gpointer data)
1369 struct connman_element *element = node->data;
1371 DBG("element %p name %s", element, element->name);
1373 if (g_node_depth(node) > 1)
1374 connman_element_unregister(element);
1379 void __connman_element_cleanup(void)
1383 __connman_device_cleanup();
1384 __connman_network_cleanup();
1385 __connman_service_cleanup();
1386 __connman_location_cleanup();
1387 __connman_notifier_cleanup();
1388 __connman_technology_cleanup();
1390 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1393 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1396 connman_element_unref(element_root->data);
1398 g_node_destroy(element_root);
1399 element_root = NULL;
1401 g_strfreev(nodevice_filter);
1402 g_strfreev(device_filter);
1404 if (connection == NULL)
1407 dbus_connection_unref(connection);