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_IPV4:
61 case CONNMAN_ELEMENT_TYPE_IPV6:
63 case CONNMAN_ELEMENT_TYPE_DHCP:
65 case CONNMAN_ELEMENT_TYPE_BOOTP:
67 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
69 case CONNMAN_ELEMENT_TYPE_CONNECTION:
71 case CONNMAN_ELEMENT_TYPE_VENDOR:
79 enum connman_element_type type;
80 element_cb_t callback;
84 static gboolean foreach_callback(GNode *node, gpointer user_data)
86 struct connman_element *element = node->data;
87 struct foreach_data *data = user_data;
89 DBG("element %p name %s", element, element->name);
91 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
94 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
95 data->type != element->type)
99 data->callback(element, data->user_data);
104 void __connman_element_foreach(struct connman_element *element,
105 enum connman_element_type type,
106 element_cb_t callback, gpointer user_data)
108 struct foreach_data data = { type, callback, user_data };
113 if (element != NULL) {
114 node = g_node_find(element_root, G_PRE_ORDER,
115 G_TRAVERSE_ALL, element);
121 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
122 foreach_callback, &data);
125 struct append_filter {
126 enum connman_element_type type;
127 DBusMessageIter *iter;
130 static gboolean append_path(GNode *node, gpointer user_data)
132 struct connman_element *element = node->data;
133 struct append_filter *filter = user_data;
135 DBG("element %p name %s", element, element->name);
137 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
140 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
141 filter->type != element->type)
144 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
145 __connman_device_has_driver(element->device) == FALSE)
148 if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
149 __connman_network_has_driver(element->network) == FALSE)
152 dbus_message_iter_append_basic(filter->iter,
153 DBUS_TYPE_OBJECT_PATH, &element->path);
158 void __connman_element_list(struct connman_element *element,
159 enum connman_element_type type,
160 DBusMessageIter *iter)
162 struct append_filter filter = { type, iter };
167 if (element != NULL) {
168 node = g_node_find(element_root, G_PRE_ORDER,
169 G_TRAVERSE_ALL, element);
175 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
176 append_path, &filter);
179 static struct connman_network *__connman_element_get_network(struct connman_element *element)
181 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
182 element->network != NULL)
183 return element->network;
185 if (element->parent == NULL)
188 return __connman_element_get_network(element->parent);
191 struct connman_service *__connman_element_get_service(struct connman_element *element)
193 struct connman_service *service = NULL;
194 struct connman_network *network;
195 struct connman_device *device;
196 enum connman_device_type type;
198 device = __connman_element_get_device(element);
202 type = connman_device_get_type(device);
205 case CONNMAN_DEVICE_TYPE_UNKNOWN:
206 case CONNMAN_DEVICE_TYPE_VENDOR:
207 case CONNMAN_DEVICE_TYPE_GPS:
209 case CONNMAN_DEVICE_TYPE_ETHERNET:
210 case CONNMAN_DEVICE_TYPE_WIFI:
211 case CONNMAN_DEVICE_TYPE_WIMAX:
212 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
213 case CONNMAN_DEVICE_TYPE_CELLULAR:
214 case CONNMAN_DEVICE_TYPE_MBM:
215 case CONNMAN_DEVICE_TYPE_HSO:
216 network = __connman_element_get_network(element);
219 service = __connman_service_lookup_from_network(network);
226 struct connman_device *__connman_element_get_device(struct connman_element *element)
228 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
229 element->device != NULL)
230 return element->device;
232 if (element->parent == NULL)
235 return __connman_element_get_device(element->parent);
238 const char *__connman_element_get_device_path(struct connman_element *element)
240 struct connman_device *device;
242 device = __connman_element_get_device(element);
246 return connman_device_get_path(device);
249 const char *__connman_element_get_network_path(struct connman_element *element)
251 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
252 element->network != NULL)
253 return element->path;
255 if (element->parent == NULL)
258 return __connman_element_get_network_path(element->parent);
262 enum connman_service_type type;
263 struct connman_device *device;
266 static gboolean find_device(GNode *node, gpointer user_data)
268 struct connman_element *element = node->data;
269 struct find_data *data = user_data;
271 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
274 if (element->device == NULL)
277 if (data->type != connman_device_get_type(element->device))
280 data->device = element->device;
285 struct connman_device *__connman_element_find_device(enum connman_service_type type)
287 struct find_data data = { .type = type, .device = NULL };
289 g_node_traverse(element_root, G_PRE_ORDER,
290 G_TRAVERSE_ALL, -1, find_device, &data);
295 static gboolean request_scan(GNode *node, gpointer user_data)
297 struct connman_element *element = node->data;
298 struct find_data *data = user_data;
299 enum connman_service_type type;
301 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
304 if (element->device == NULL)
307 type = __connman_device_get_service_type(element->device);
310 case CONNMAN_SERVICE_TYPE_UNKNOWN:
311 case CONNMAN_SERVICE_TYPE_SYSTEM:
312 case CONNMAN_SERVICE_TYPE_ETHERNET:
313 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
314 case CONNMAN_SERVICE_TYPE_CELLULAR:
315 case CONNMAN_SERVICE_TYPE_GPS:
316 case CONNMAN_SERVICE_TYPE_VPN:
318 case CONNMAN_SERVICE_TYPE_WIFI:
319 case CONNMAN_SERVICE_TYPE_WIMAX:
320 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
326 __connman_device_scan(element->device);
331 int __connman_element_request_scan(enum connman_service_type type)
333 struct find_data data = { .type = type, .device = NULL };
335 g_node_traverse(element_root, G_PRE_ORDER,
336 G_TRAVERSE_ALL, -1, request_scan, &data);
341 static gboolean enable_technology(GNode *node, gpointer user_data)
343 struct connman_element *element = node->data;
344 struct find_data *data = user_data;
345 enum connman_service_type type;
347 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
350 if (element->device == NULL)
353 type = __connman_device_get_service_type(element->device);
356 case CONNMAN_SERVICE_TYPE_UNKNOWN:
357 case CONNMAN_SERVICE_TYPE_SYSTEM:
358 case CONNMAN_SERVICE_TYPE_GPS:
359 case CONNMAN_SERVICE_TYPE_VPN:
361 case CONNMAN_SERVICE_TYPE_ETHERNET:
362 case CONNMAN_SERVICE_TYPE_WIFI:
363 case CONNMAN_SERVICE_TYPE_WIMAX:
364 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
365 case CONNMAN_SERVICE_TYPE_CELLULAR:
366 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
372 __connman_device_enable_persistent(element->device);
377 int __connman_element_enable_technology(enum connman_service_type type)
379 struct find_data data = { .type = type, .device = NULL };
381 g_node_traverse(element_root, G_PRE_ORDER,
382 G_TRAVERSE_ALL, -1, enable_technology, &data);
387 static gboolean disable_technology(GNode *node, gpointer user_data)
389 struct connman_element *element = node->data;
390 struct find_data *data = user_data;
391 enum connman_service_type type;
393 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
396 if (element->device == NULL)
399 type = __connman_device_get_service_type(element->device);
402 case CONNMAN_SERVICE_TYPE_UNKNOWN:
403 case CONNMAN_SERVICE_TYPE_SYSTEM:
404 case CONNMAN_SERVICE_TYPE_GPS:
405 case CONNMAN_SERVICE_TYPE_VPN:
407 case CONNMAN_SERVICE_TYPE_ETHERNET:
408 case CONNMAN_SERVICE_TYPE_WIFI:
409 case CONNMAN_SERVICE_TYPE_WIMAX:
410 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
411 case CONNMAN_SERVICE_TYPE_CELLULAR:
412 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
418 __connman_device_disable_persistent(element->device);
423 int __connman_element_disable_technology(enum connman_service_type type)
425 struct find_data data = { .type = type, .device = NULL };
427 g_node_traverse(element_root, G_PRE_ORDER,
428 G_TRAVERSE_ALL, -1, disable_technology, &data);
433 static gint compare_priority(gconstpointer a, gconstpointer b)
435 const struct connman_driver *driver1 = a;
436 const struct connman_driver *driver2 = b;
438 return driver2->priority - driver1->priority;
441 static gboolean match_driver(struct connman_element *element,
442 struct connman_driver *driver)
444 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
447 if (element->type == driver->type ||
448 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
454 static gboolean probe_driver(GNode *node, gpointer data)
456 struct connman_element *element = node->data;
457 struct connman_driver *driver = data;
459 DBG("element %p name %s", element, element->name);
461 if (!element->driver && match_driver(element, driver) == TRUE) {
462 if (driver->probe(element) < 0)
465 element->driver = driver;
471 void __connman_driver_rescan(struct connman_driver *driver)
473 DBG("driver %p name %s", driver, driver->name);
478 if (element_root != NULL)
479 g_node_traverse(element_root, G_PRE_ORDER,
480 G_TRAVERSE_ALL, -1, probe_driver, driver);
484 * connman_driver_register:
485 * @driver: driver definition
487 * Register a new driver
489 * Returns: %0 on success
491 int connman_driver_register(struct connman_driver *driver)
493 DBG("driver %p name %s", driver, driver->name);
495 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
501 driver_list = g_slist_insert_sorted(driver_list, driver,
504 if (started == FALSE)
507 if (element_root != NULL)
508 g_node_traverse(element_root, G_PRE_ORDER,
509 G_TRAVERSE_ALL, -1, probe_driver, driver);
514 static gboolean remove_driver(GNode *node, gpointer data)
516 struct connman_element *element = node->data;
517 struct connman_driver *driver = data;
519 DBG("element %p name %s", element, element->name);
521 if (element->driver == driver) {
523 driver->remove(element);
525 element->driver = NULL;
532 * connman_driver_unregister:
533 * @driver: driver definition
535 * Remove a previously registered driver
537 void connman_driver_unregister(struct connman_driver *driver)
539 DBG("driver %p name %s", driver, driver->name);
541 driver_list = g_slist_remove(driver_list, driver);
543 if (element_root != NULL)
544 g_node_traverse(element_root, G_POST_ORDER,
545 G_TRAVERSE_ALL, -1, remove_driver, driver);
548 static void unregister_property(gpointer data)
550 struct connman_property *property = data;
552 DBG("property %p", property);
554 g_free(property->value);
558 static void unregister_child(gpointer data)
560 struct connman_element *element = data;
562 DBG("element %p", element);
564 connman_element_unref(element);
567 void __connman_element_initialize(struct connman_element *element)
569 DBG("element %p", element);
571 element->refcount = 1;
573 element->name = NULL;
574 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
575 element->state = CONNMAN_ELEMENT_STATE_UNKNOWN;
576 element->error = CONNMAN_ELEMENT_ERROR_UNKNOWN;
578 element->enabled = FALSE;
580 element->children = g_hash_table_new_full(g_str_hash, g_str_equal,
581 NULL, unregister_child);
583 element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
584 g_free, unregister_property);
588 * connman_element_create:
589 * @name: element name
591 * Allocate a new element and assign the given #name to it. If the name
592 * is #NULL, it will be later on created based on the element type.
594 * Returns: a newly-allocated #connman_element structure
596 struct connman_element *connman_element_create(const char *name)
598 struct connman_element *element;
600 element = g_try_new0(struct connman_element, 1);
604 DBG("element %p", element);
606 __connman_element_initialize(element);
611 struct connman_element *connman_element_ref(struct connman_element *element)
613 DBG("element %p name %s refcount %d", element, element->name,
614 g_atomic_int_get(&element->refcount) + 1);
616 g_atomic_int_inc(&element->refcount);
621 static void free_properties(struct connman_element *element)
623 DBG("element %p name %s", element, element->name);
625 g_hash_table_destroy(element->properties);
626 element->properties = NULL;
629 static void free_children(struct connman_element *element)
631 DBG("element %p name %s", element, element->name);
633 g_hash_table_destroy(element->children);
634 element->children = NULL;
637 void connman_element_unref(struct connman_element *element)
639 DBG("element %p name %s refcount %d", element, element->name,
640 g_atomic_int_get(&element->refcount) - 1);
642 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
643 if (element->destruct)
644 element->destruct(element);
645 free_children(element);
646 free_properties(element);
647 g_free(element->ipv4.address);
648 g_free(element->ipv4.netmask);
649 g_free(element->ipv4.gateway);
650 g_free(element->ipv4.network);
651 g_free(element->ipv4.broadcast);
652 g_free(element->ipv4.nameserver);
653 g_free(element->ipv4.timeserver);
654 g_free(element->ipv4.pac);
655 g_free(element->devname);
656 g_free(element->path);
657 g_free(element->name);
662 static int set_static_property(struct connman_element *element,
663 const char *name, int type, const void *value)
665 struct connman_property *property;
667 DBG("element %p name %s", element, element->name);
669 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
672 property = g_try_new0(struct connman_property, 1);
673 if (property == NULL)
676 property->id = CONNMAN_PROPERTY_ID_INVALID;
677 property->type = type;
679 DBG("name %s type %d value %p", name, type, value);
682 case DBUS_TYPE_STRING:
683 property->value = g_strdup(*((const char **) value));
685 case DBUS_TYPE_BOOLEAN:
687 property->value = g_try_malloc(1);
688 if (property->value != NULL)
689 memcpy(property->value, value, 1);
693 g_hash_table_replace(element->properties, g_strdup(name), property);
698 static int set_static_array_property(struct connman_element *element,
699 const char *name, int type, const void *value, int len)
701 struct connman_property *property;
703 DBG("element %p name %s", element, element->name);
705 if (type != DBUS_TYPE_BYTE)
708 property = g_try_new0(struct connman_property, 1);
709 if (property == NULL)
712 property->id = CONNMAN_PROPERTY_ID_INVALID;
713 property->type = DBUS_TYPE_ARRAY;
714 property->subtype = type;
716 DBG("name %s type %d value %p", name, type, value);
720 property->value = g_try_malloc(len);
721 if (property->value != NULL) {
722 memcpy(property->value,
723 *((const unsigned char **) value), len);
724 property->size = len;
729 g_hash_table_replace(element->properties, g_strdup(name), property);
734 int connman_element_get_value(struct connman_element *element,
735 enum connman_property_id id, void *value)
737 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
741 case CONNMAN_PROPERTY_ID_IPV4_METHOD:
742 if (element->ipv4.method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
743 return connman_element_get_value(element->parent,
745 *((const char **) value) = __connman_ipconfig_method2string(element->ipv4.method);
747 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
748 if (element->ipv4.address == NULL)
749 return connman_element_get_value(element->parent,
751 *((char **) value) = element->ipv4.address;
753 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
754 if (element->ipv4.netmask == NULL)
755 return connman_element_get_value(element->parent,
757 *((char **) value) = element->ipv4.netmask;
759 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
760 if (element->ipv4.gateway == NULL)
761 return connman_element_get_value(element->parent,
763 *((char **) value) = element->ipv4.gateway;
765 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
766 if (element->ipv4.broadcast == NULL)
767 return connman_element_get_value(element->parent,
769 *((char **) value) = element->ipv4.broadcast;
771 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
772 if (element->ipv4.nameserver == NULL)
773 return connman_element_get_value(element->parent,
775 *((char **) value) = element->ipv4.nameserver;
777 case CONNMAN_PROPERTY_ID_IPV4_TIMESERVER:
778 if (element->ipv4.timeserver == NULL)
779 return connman_element_get_value(element->parent,
781 *((char **) value) = element->ipv4.timeserver;
783 case CONNMAN_PROPERTY_ID_IPV4_PAC:
784 if (element->ipv4.pac == NULL)
785 return connman_element_get_value(element->parent,
787 *((char **) value) = element->ipv4.pac;
796 static gboolean get_static_property(struct connman_element *element,
797 const char *name, void *value)
799 struct connman_property *property;
800 gboolean found = FALSE;
802 DBG("element %p name %s", element, element->name);
804 property = g_hash_table_lookup(element->properties, name);
805 if (property != NULL) {
806 switch (property->type) {
807 case DBUS_TYPE_STRING:
808 *((char **) value) = property->value;
811 case DBUS_TYPE_BOOLEAN:
813 memcpy(value, property->value, 1);
819 if (found == FALSE && element->parent != NULL)
820 return get_static_property(element->parent, name, value);
825 static gboolean get_static_array_property(struct connman_element *element,
826 const char *name, void *value, unsigned int *len)
828 struct connman_property *property;
829 gboolean found = FALSE;
831 DBG("element %p name %s", element, element->name);
833 property = g_hash_table_lookup(element->properties, name);
834 if (property != NULL) {
835 *((void **) value) = property->value;
836 *len = property->size;
844 * connman_element_set_string:
845 * @element: element structure
846 * @key: unique identifier
847 * @value: string value
849 * Set string value for specific key
851 int connman_element_set_string(struct connman_element *element,
852 const char *key, const char *value)
854 return set_static_property(element, key, DBUS_TYPE_STRING, &value);
858 * connman_element_get_string:
859 * @element: element structure
860 * @key: unique identifier
862 * Get string value for specific key
864 const char *connman_element_get_string(struct connman_element *element,
869 if (get_static_property(element, key, &value) == FALSE)
876 * connman_element_set_bool:
877 * @element: element structure
878 * @key: unique identifier
879 * @value: boolean value
881 * Set boolean value for specific key
883 int connman_element_set_bool(struct connman_element *element,
884 const char *key, connman_bool_t value)
886 return set_static_property(element, key, DBUS_TYPE_BOOLEAN, &value);
890 * connman_element_get_bool:
891 * @element: element structure
892 * @key: unique identifier
894 * Get boolean value for specific key
896 connman_bool_t connman_element_get_bool(struct connman_element *element,
899 connman_bool_t value;
901 if (get_static_property(element, key, &value) == FALSE)
908 * connman_element_set_uint8:
909 * @element: element structure
910 * @key: unique identifier
911 * @value: integer value
913 * Set integer value for specific key
915 int connman_element_set_uint8(struct connman_element *element,
916 const char *key, connman_uint8_t value)
918 return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
922 * connman_element_get_uint8:
923 * @element: element structure
924 * @key: unique identifier
926 * Get integer value for specific key
928 connman_uint8_t connman_element_get_uint8(struct connman_element *element,
931 connman_uint8_t value;
933 if (get_static_property(element, key, &value) == FALSE)
940 * connman_element_set_blob:
941 * @element: element structure
942 * @key: unique identifier
946 * Set binary blob value for specific key
948 int connman_element_set_blob(struct connman_element *element,
949 const char *key, const void *data, unsigned int size)
951 return set_static_array_property(element, key,
952 DBUS_TYPE_BYTE, &data, size);
956 * connman_element_get_blob:
957 * @element: element structure
958 * @key: unique identifier
959 * @size: pointer to blob size
961 * Get binary blob value for specific key
963 const void *connman_element_get_blob(struct connman_element *element,
964 const char *key, unsigned int *size)
968 if (get_static_array_property(element, key, &value, size) == FALSE)
974 static void probe_element(struct connman_element *element)
978 DBG("element %p name %s", element, element->name);
980 for (list = driver_list; list; list = list->next) {
981 struct connman_driver *driver = list->data;
983 if (match_driver(element, driver) == FALSE)
986 DBG("driver %p name %s", driver, driver->name);
988 if (driver->probe(element) == 0) {
989 element->driver = driver;
995 static void register_element(gpointer data, gpointer user_data)
997 struct connman_element *element = data;
998 const gchar *basepath;
1001 if (element->parent) {
1002 node = g_node_find(element_root, G_PRE_ORDER,
1003 G_TRAVERSE_ALL, element->parent);
1004 basepath = element->parent->path;
1006 element->parent = element_root->data;
1008 node = element_root;
1009 basepath = "/device";
1012 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1015 connman_error("Element registration for %s failed",
1020 DBG("element %p path %s", element, element->path);
1022 g_node_append_data(node, element);
1024 if (started == FALSE)
1027 probe_element(element);
1030 gboolean __connman_element_device_isfiltered(const char *devname)
1032 if (device_filter == NULL)
1035 if (g_pattern_match_simple(device_filter, devname) == FALSE) {
1036 DBG("ignoring device %s (match)", devname);
1041 if (nodevice_filter == NULL)
1044 if (g_pattern_match_simple(nodevice_filter, devname) == TRUE) {
1045 DBG("ignoring device %s (no match)", devname);
1053 * connman_element_register:
1054 * @element: the element to register
1055 * @parent: the parent to register the element with
1057 * Register an element with the core. It will be register under the given
1058 * parent of if %NULL is provided under the root element.
1060 * Returns: %0 on success
1062 int connman_element_register(struct connman_element *element,
1063 struct connman_element *parent)
1065 DBG("element %p name %s parent %p", element, element->name, parent);
1067 if (element->devname == NULL)
1068 element->devname = g_strdup(element->name);
1070 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
1073 if (__connman_element_device_isfiltered(element->devname) == TRUE)
1077 if (connman_element_ref(element) == NULL)
1080 if (element->name == NULL) {
1081 element->name = g_strdup(type2string(element->type));
1082 if (element->name == NULL) {
1087 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
1088 element->ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
1090 element->parent = parent;
1092 register_element(element, NULL);
1097 static gboolean remove_element(GNode *node, gpointer user_data)
1099 struct connman_element *element = node->data;
1100 struct connman_element *root = user_data;
1102 DBG("element %p name %s", element, element->name);
1104 if (element == root)
1108 g_node_unlink(node);
1110 if (element->driver) {
1111 if (element->driver->remove)
1112 element->driver->remove(element);
1114 element->driver = NULL;
1118 g_node_destroy(node);
1120 connman_element_unref(element);
1125 void connman_element_unregister(struct connman_element *element)
1129 DBG("element %p name %s", element, element->name);
1131 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1134 g_node_traverse(node, G_POST_ORDER,
1135 G_TRAVERSE_ALL, -1, remove_element, NULL);
1138 void connman_element_unregister_children(struct connman_element *element)
1142 DBG("element %p name %s", element, element->name);
1144 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1147 g_node_traverse(node, G_POST_ORDER,
1148 G_TRAVERSE_ALL, -1, remove_element, element);
1151 static gboolean update_element(GNode *node, gpointer user_data)
1153 struct connman_element *element = node->data;
1155 DBG("element %p name %s", element, element->name);
1157 if (element->driver && element->driver->update)
1158 element->driver->update(element);
1163 void connman_element_update(struct connman_element *element)
1167 DBG("element %p name %s", element, element->name);
1169 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1172 g_node_traverse(node, G_PRE_ORDER,
1173 G_TRAVERSE_ALL, -1, update_element, element);
1176 int connman_element_set_enabled(struct connman_element *element,
1179 if (element->enabled == enabled)
1182 element->enabled = enabled;
1184 connman_element_update(element);
1189 static enum connman_service_error convert_error(enum connman_element_error error)
1192 case CONNMAN_ELEMENT_ERROR_UNKNOWN:
1193 case CONNMAN_ELEMENT_ERROR_FAILED:
1195 case CONNMAN_ELEMENT_ERROR_DHCP_FAILED:
1196 return CONNMAN_SERVICE_ERROR_DHCP_FAILED;
1197 case CONNMAN_ELEMENT_ERROR_CONNECT_FAILED:
1198 return CONNMAN_SERVICE_ERROR_CONNECT_FAILED;
1201 return CONNMAN_SERVICE_ERROR_UNKNOWN;
1205 * connman_element_set_error:
1206 * @element: element structure
1207 * @error: error identifier
1209 * Set error state and specific error identifier
1211 void connman_element_set_error(struct connman_element *element,
1212 enum connman_element_error error)
1214 struct connman_service *service;
1216 DBG("element %p error %d", element, error);
1218 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1221 element->state = CONNMAN_ELEMENT_STATE_ERROR;
1222 element->error = error;
1224 if (element->driver && element->driver->change)
1225 element->driver->change(element);
1227 service = __connman_element_get_service(element);
1228 __connman_service_indicate_error(service, convert_error(error));
1231 int __connman_element_init(const char *device, const char *nodevice)
1233 struct connman_element *element;
1237 connection = connman_dbus_get_connection();
1238 if (connection == NULL)
1241 device_filter = g_strdup(device);
1242 nodevice_filter = g_strdup(nodevice);
1244 element = connman_element_create("root");
1246 element->path = g_strdup("/");
1247 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1249 element_root = g_node_new(element);
1251 __connman_technology_init();
1252 __connman_notifier_init();
1253 __connman_service_init();
1254 __connman_provider_init();
1255 __connman_network_init();
1256 __connman_device_init();
1261 static gboolean probe_node(GNode *node, gpointer data)
1263 struct connman_element *element = node->data;
1265 DBG("element %p name %s", element, element->name);
1267 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1270 if (element->driver)
1273 probe_element(element);
1278 void __connman_element_start(void)
1282 __connman_storage_init_profile();
1284 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1289 __connman_rtnl_start();
1290 __connman_udev_start();
1292 __connman_connection_init();
1293 __connman_ipv4_init();
1294 __connman_dhcp_init();
1296 if (__connman_rfkill_init() < 0)
1297 __connman_udev_enable_rfkill_processing();
1300 void __connman_element_stop(void)
1304 __connman_rfkill_cleanup();
1306 __connman_dhcp_cleanup();
1307 __connman_ipv4_cleanup();
1308 __connman_provider_cleanup();
1309 __connman_connection_cleanup();
1312 static gboolean free_driver(GNode *node, gpointer data)
1314 struct connman_element *element = node->data;
1316 DBG("element %p name %s", element, element->name);
1318 if (element->driver) {
1319 if (element->driver->remove)
1320 element->driver->remove(element);
1322 element->driver = NULL;
1328 static gboolean free_node(GNode *node, gpointer data)
1330 struct connman_element *element = node->data;
1332 DBG("element %p name %s", element, element->name);
1334 if (g_node_depth(node) > 1)
1335 connman_element_unregister(element);
1340 void __connman_element_cleanup(void)
1344 __connman_device_cleanup();
1345 __connman_network_cleanup();
1346 __connman_service_cleanup();
1347 __connman_notifier_cleanup();
1348 __connman_technology_cleanup();
1350 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1353 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1356 g_node_destroy(element_root);
1357 element_root = NULL;
1359 g_free(nodevice_filter);
1360 g_free(device_filter);
1362 if (connection == NULL)
1365 dbus_connection_unref(connection);