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 *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 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 network = get_network(element);
217 service = __connman_service_lookup_from_network(network);
224 struct connman_device *__connman_element_get_device(struct connman_element *element)
226 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
227 element->device != NULL)
228 return element->device;
230 if (element->parent == NULL)
233 return __connman_element_get_device(element->parent);
236 const char *__connman_element_get_device_path(struct connman_element *element)
238 struct connman_device *device;
240 device = __connman_element_get_device(element);
244 return connman_device_get_path(device);
247 const char *__connman_element_get_network_path(struct connman_element *element)
249 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
250 element->network != NULL)
251 return element->path;
253 if (element->parent == NULL)
256 return __connman_element_get_network_path(element->parent);
260 enum connman_service_type type;
261 struct connman_device *device;
262 connman_bool_t error;
265 static gboolean find_device(GNode *node, gpointer user_data)
267 struct connman_element *element = node->data;
268 struct find_data *data = user_data;
270 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
273 if (element->device == NULL)
276 if (data->type != __connman_device_get_service_type(element->device))
279 data->device = element->device;
284 struct connman_device *__connman_element_find_device(enum connman_service_type type)
286 struct find_data data = { .type = type, .device = NULL };
288 g_node_traverse(element_root, G_PRE_ORDER,
289 G_TRAVERSE_ALL, -1, find_device, &data);
294 static gboolean request_scan(GNode *node, gpointer user_data)
296 struct connman_element *element = node->data;
297 struct find_data *data = user_data;
298 enum connman_service_type type;
300 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
303 if (element->device == NULL)
306 type = __connman_device_get_service_type(element->device);
309 case CONNMAN_SERVICE_TYPE_UNKNOWN:
310 case CONNMAN_SERVICE_TYPE_SYSTEM:
311 case CONNMAN_SERVICE_TYPE_ETHERNET:
312 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
313 case CONNMAN_SERVICE_TYPE_CELLULAR:
314 case CONNMAN_SERVICE_TYPE_GPS:
315 case CONNMAN_SERVICE_TYPE_VPN:
317 case CONNMAN_SERVICE_TYPE_WIFI:
318 case CONNMAN_SERVICE_TYPE_WIMAX:
319 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
325 __connman_device_scan(element->device);
330 int __connman_element_request_scan(enum connman_service_type type)
332 struct find_data data = { .type = type, .device = NULL };
334 g_node_traverse(element_root, G_PRE_ORDER,
335 G_TRAVERSE_ALL, -1, request_scan, &data);
340 static gboolean enable_technology(GNode *node, gpointer user_data)
342 struct connman_element *element = node->data;
343 struct find_data *data = user_data;
344 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 err = __connman_device_enable_persistent(element->device);
373 if (err == 0 || (err < 0 && err == -EINPROGRESS))
379 int __connman_element_enable_technology(enum connman_service_type type)
381 struct find_data data = { .type = type, .device = NULL, .error = TRUE };
383 g_node_traverse(element_root, G_PRE_ORDER,
384 G_TRAVERSE_ALL, -1, enable_technology, &data);
386 if (data.error == TRUE)
392 static gboolean disable_technology(GNode *node, gpointer user_data)
394 struct connman_element *element = node->data;
395 struct find_data *data = user_data;
396 enum connman_service_type type;
399 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
402 if (element->device == NULL)
405 type = __connman_device_get_service_type(element->device);
408 case CONNMAN_SERVICE_TYPE_UNKNOWN:
409 case CONNMAN_SERVICE_TYPE_SYSTEM:
410 case CONNMAN_SERVICE_TYPE_GPS:
411 case CONNMAN_SERVICE_TYPE_VPN:
413 case CONNMAN_SERVICE_TYPE_ETHERNET:
414 case CONNMAN_SERVICE_TYPE_WIFI:
415 case CONNMAN_SERVICE_TYPE_WIMAX:
416 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
417 case CONNMAN_SERVICE_TYPE_CELLULAR:
418 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
424 err = __connman_device_disable_persistent(element->device);
425 if (err == 0 || (err < 0 && err == -EINPROGRESS))
431 int __connman_element_disable_technology(enum connman_service_type type)
433 struct find_data data = { .type = type, .device = NULL, .error = TRUE };
435 g_node_traverse(element_root, G_PRE_ORDER,
436 G_TRAVERSE_ALL, -1, disable_technology, &data);
438 if (data.error == TRUE)
444 static gint compare_priority(gconstpointer a, gconstpointer b)
446 const struct connman_driver *driver1 = a;
447 const struct connman_driver *driver2 = b;
449 return driver2->priority - driver1->priority;
452 static gboolean match_driver(struct connman_element *element,
453 struct connman_driver *driver)
455 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
458 if (element->type == driver->type ||
459 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
465 static gboolean probe_driver(GNode *node, gpointer data)
467 struct connman_element *element = node->data;
468 struct connman_driver *driver = data;
470 DBG("element %p name %s", element, element->name);
472 if (!element->driver && match_driver(element, driver) == TRUE) {
473 if (driver->probe(element) < 0)
476 element->driver = driver;
482 void __connman_driver_rescan(struct connman_driver *driver)
484 DBG("driver %p name %s", driver, driver->name);
489 if (element_root != NULL)
490 g_node_traverse(element_root, G_PRE_ORDER,
491 G_TRAVERSE_ALL, -1, probe_driver, driver);
495 * connman_driver_register:
496 * @driver: driver definition
498 * Register a new driver
500 * Returns: %0 on success
502 int connman_driver_register(struct connman_driver *driver)
504 DBG("driver %p name %s", driver, driver->name);
506 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
512 driver_list = g_slist_insert_sorted(driver_list, driver,
515 if (started == FALSE)
518 if (element_root != NULL)
519 g_node_traverse(element_root, G_PRE_ORDER,
520 G_TRAVERSE_ALL, -1, probe_driver, driver);
525 static gboolean remove_driver(GNode *node, gpointer data)
527 struct connman_element *element = node->data;
528 struct connman_driver *driver = data;
530 DBG("element %p name %s", element, element->name);
532 if (element->driver == driver) {
534 driver->remove(element);
536 element->driver = NULL;
543 * connman_driver_unregister:
544 * @driver: driver definition
546 * Remove a previously registered driver
548 void connman_driver_unregister(struct connman_driver *driver)
550 DBG("driver %p name %s", driver, driver->name);
552 driver_list = g_slist_remove(driver_list, driver);
554 if (element_root != NULL)
555 g_node_traverse(element_root, G_POST_ORDER,
556 G_TRAVERSE_ALL, -1, remove_driver, driver);
559 static void unregister_property(gpointer data)
561 struct connman_property *property = data;
563 DBG("property %p", property);
565 g_free(property->value);
569 static void unregister_child(gpointer data)
571 struct connman_element *element = data;
573 DBG("element %p", element);
575 connman_element_unref(element);
578 void __connman_element_initialize(struct connman_element *element)
580 DBG("element %p", element);
582 element->refcount = 1;
584 element->name = NULL;
585 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
586 element->state = CONNMAN_ELEMENT_STATE_UNKNOWN;
587 element->error = CONNMAN_ELEMENT_ERROR_UNKNOWN;
589 element->enabled = FALSE;
591 element->children = g_hash_table_new_full(g_str_hash, g_str_equal,
592 NULL, unregister_child);
594 element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
595 g_free, unregister_property);
599 * connman_element_create:
600 * @name: element name
602 * Allocate a new element and assign the given #name to it. If the name
603 * is #NULL, it will be later on created based on the element type.
605 * Returns: a newly-allocated #connman_element structure
607 struct connman_element *connman_element_create(const char *name)
609 struct connman_element *element;
611 element = g_try_new0(struct connman_element, 1);
615 DBG("element %p", element);
617 __connman_element_initialize(element);
622 struct connman_element *connman_element_ref(struct connman_element *element)
624 DBG("element %p name %s refcount %d", element, element->name,
625 g_atomic_int_get(&element->refcount) + 1);
627 g_atomic_int_inc(&element->refcount);
632 static void free_properties(struct connman_element *element)
634 DBG("element %p name %s", element, element->name);
636 g_hash_table_destroy(element->properties);
637 element->properties = NULL;
640 static void free_children(struct connman_element *element)
642 DBG("element %p name %s", element, element->name);
644 g_hash_table_destroy(element->children);
645 element->children = NULL;
648 void connman_element_unref(struct connman_element *element)
650 DBG("element %p name %s refcount %d", element, element->name,
651 g_atomic_int_get(&element->refcount) - 1);
653 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
654 if (element->destruct)
655 element->destruct(element);
656 free_children(element);
657 free_properties(element);
658 g_free(element->hostname);
659 g_free(element->domainname);
660 g_free(element->ipv4.address);
661 g_free(element->ipv4.netmask);
662 g_free(element->ipv4.gateway);
663 g_free(element->ipv4.network);
664 g_free(element->ipv4.broadcast);
665 g_free(element->ipv4.nameserver);
666 g_free(element->ipv4.timeserver);
667 g_free(element->ipv4.pac);
668 g_free(element->ipv6.address);
669 g_free(element->ipv6.network);
670 g_free(element->devname);
671 g_free(element->path);
672 g_free(element->name);
677 static int set_static_property(struct connman_element *element,
678 const char *name, int type, const void *value)
680 struct connman_property *property;
682 DBG("element %p name %s", element, element->name);
684 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
687 property = g_try_new0(struct connman_property, 1);
688 if (property == NULL)
691 property->id = CONNMAN_PROPERTY_ID_INVALID;
692 property->type = type;
694 DBG("name %s type %d value %p", name, type, value);
697 case DBUS_TYPE_STRING:
698 property->value = g_strdup(*((const char **) value));
700 case DBUS_TYPE_BOOLEAN:
702 property->value = g_try_malloc(1);
703 if (property->value != NULL)
704 memcpy(property->value, value, 1);
708 g_hash_table_replace(element->properties, g_strdup(name), property);
713 static int set_static_array_property(struct connman_element *element,
714 const char *name, int type, const void *value, int len)
716 struct connman_property *property;
718 DBG("element %p name %s", element, element->name);
720 if (type != DBUS_TYPE_BYTE)
723 property = g_try_new0(struct connman_property, 1);
724 if (property == NULL)
727 property->id = CONNMAN_PROPERTY_ID_INVALID;
728 property->type = DBUS_TYPE_ARRAY;
729 property->subtype = type;
731 DBG("name %s type %d value %p", name, type, value);
735 property->value = g_try_malloc(len);
736 if (property->value != NULL) {
737 memcpy(property->value,
738 *((const unsigned char **) value), len);
739 property->size = len;
744 g_hash_table_replace(element->properties, g_strdup(name), property);
749 int connman_element_get_value(struct connman_element *element,
750 enum connman_property_id id, void *value)
752 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
756 case CONNMAN_PROPERTY_ID_HOSTNAME:
757 if (element->hostname == NULL)
758 return connman_element_get_value(element->parent,
760 *((char **) value) = element->hostname;
762 case CONNMAN_PROPERTY_ID_DOMAINNAME:
763 if (element->domainname == NULL)
764 return connman_element_get_value(element->parent,
766 *((char **) value) = element->domainname;
768 case CONNMAN_PROPERTY_ID_IPV4_METHOD:
769 if (element->ipv4.method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
770 return connman_element_get_value(element->parent,
772 *((const char **) value) = __connman_ipconfig_method2string(element->ipv4.method);
774 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
775 if (element->ipv4.address == NULL)
776 return connman_element_get_value(element->parent,
778 *((char **) value) = element->ipv4.address;
780 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
781 if (element->ipv4.netmask == NULL)
782 return connman_element_get_value(element->parent,
784 *((char **) value) = element->ipv4.netmask;
786 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
787 if (element->ipv4.gateway == NULL)
788 return connman_element_get_value(element->parent,
790 *((char **) value) = element->ipv4.gateway;
792 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
793 if (element->ipv4.broadcast == NULL)
794 return connman_element_get_value(element->parent,
796 *((char **) value) = element->ipv4.broadcast;
798 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
799 if (element->ipv4.nameserver == NULL)
800 return connman_element_get_value(element->parent,
802 *((char **) value) = element->ipv4.nameserver;
804 case CONNMAN_PROPERTY_ID_IPV4_TIMESERVER:
805 if (element->ipv4.timeserver == NULL)
806 return connman_element_get_value(element->parent,
808 *((char **) value) = element->ipv4.timeserver;
810 case CONNMAN_PROPERTY_ID_IPV4_PAC:
811 if (element->ipv4.pac == NULL)
812 return connman_element_get_value(element->parent,
814 *((char **) value) = element->ipv4.pac;
816 case CONNMAN_PROPERTY_ID_IPV6_GATEWAY:
817 if (element->ipv6.gateway == NULL)
818 return connman_element_get_value(element->parent,
820 *((char **) value) = element->ipv6.gateway;
830 static gboolean get_static_property(struct connman_element *element,
831 const char *name, void *value)
833 struct connman_property *property;
834 gboolean found = FALSE;
836 DBG("element %p name %s", element, element->name);
838 property = g_hash_table_lookup(element->properties, name);
839 if (property != NULL) {
840 switch (property->type) {
841 case DBUS_TYPE_STRING:
842 *((char **) value) = property->value;
845 case DBUS_TYPE_BOOLEAN:
847 memcpy(value, property->value, 1);
853 if (found == FALSE && element->parent != NULL)
854 return get_static_property(element->parent, name, value);
859 static gboolean get_static_array_property(struct connman_element *element,
860 const char *name, void *value, unsigned int *len)
862 struct connman_property *property;
863 gboolean found = FALSE;
865 DBG("element %p name %s", element, element->name);
867 property = g_hash_table_lookup(element->properties, name);
868 if (property != NULL) {
869 *((void **) value) = property->value;
870 *len = property->size;
878 * connman_element_set_string:
879 * @element: element structure
880 * @key: unique identifier
881 * @value: string value
883 * Set string value for specific key
885 int connman_element_set_string(struct connman_element *element,
886 const char *key, const char *value)
888 return set_static_property(element, key, DBUS_TYPE_STRING, &value);
892 * connman_element_get_string:
893 * @element: element structure
894 * @key: unique identifier
896 * Get string value for specific key
898 const char *connman_element_get_string(struct connman_element *element,
903 if (get_static_property(element, key, &value) == FALSE)
910 * connman_element_set_bool:
911 * @element: element structure
912 * @key: unique identifier
913 * @value: boolean value
915 * Set boolean value for specific key
917 int connman_element_set_bool(struct connman_element *element,
918 const char *key, connman_bool_t value)
920 return set_static_property(element, key, DBUS_TYPE_BOOLEAN, &value);
924 * connman_element_get_bool:
925 * @element: element structure
926 * @key: unique identifier
928 * Get boolean value for specific key
930 connman_bool_t connman_element_get_bool(struct connman_element *element,
933 connman_bool_t value;
935 if (get_static_property(element, key, &value) == FALSE)
942 * connman_element_set_uint8:
943 * @element: element structure
944 * @key: unique identifier
945 * @value: integer value
947 * Set integer value for specific key
949 int connman_element_set_uint8(struct connman_element *element,
950 const char *key, connman_uint8_t value)
952 return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
956 * connman_element_get_uint8:
957 * @element: element structure
958 * @key: unique identifier
960 * Get integer value for specific key
962 connman_uint8_t connman_element_get_uint8(struct connman_element *element,
965 connman_uint8_t value;
967 if (get_static_property(element, key, &value) == FALSE)
974 * connman_element_set_blob:
975 * @element: element structure
976 * @key: unique identifier
980 * Set binary blob value for specific key
982 int connman_element_set_blob(struct connman_element *element,
983 const char *key, const void *data, unsigned int size)
985 return set_static_array_property(element, key,
986 DBUS_TYPE_BYTE, &data, size);
990 * connman_element_get_blob:
991 * @element: element structure
992 * @key: unique identifier
993 * @size: pointer to blob size
995 * Get binary blob value for specific key
997 const void *connman_element_get_blob(struct connman_element *element,
998 const char *key, unsigned int *size)
1002 if (get_static_array_property(element, key, &value, size) == FALSE)
1008 static void probe_element(struct connman_element *element)
1012 DBG("element %p name %s", element, element->name);
1014 for (list = driver_list; list; list = list->next) {
1015 struct connman_driver *driver = list->data;
1017 if (match_driver(element, driver) == FALSE)
1020 DBG("driver %p name %s", driver, driver->name);
1022 if (driver->probe(element) == 0) {
1023 element->driver = driver;
1029 static void register_element(gpointer data, gpointer user_data)
1031 struct connman_element *element = data;
1032 const gchar *basepath;
1035 if (element->parent) {
1036 node = g_node_find(element_root, G_PRE_ORDER,
1037 G_TRAVERSE_ALL, element->parent);
1038 basepath = element->parent->path;
1040 element->parent = element_root->data;
1042 node = element_root;
1043 basepath = CONNMAN_PATH "/device";
1046 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1049 connman_error("Element registration for %s failed",
1054 DBG("element %p path %s", element, element->path);
1056 g_node_append_data(node, element);
1058 if (started == FALSE)
1061 probe_element(element);
1064 gboolean __connman_element_device_isfiltered(const char *devname)
1068 if (device_filter == NULL)
1071 for (pattern = device_filter; *pattern; pattern++) {
1072 if (g_pattern_match_simple(*pattern, devname) == FALSE) {
1073 DBG("ignoring device %s (match)", devname);
1079 if (nodevice_filter == NULL)
1082 for (pattern = nodevice_filter; *pattern; pattern++) {
1083 if (g_pattern_match_simple(*pattern, devname) == TRUE) {
1084 DBG("ignoring device %s (no match)", devname);
1093 * connman_element_register:
1094 * @element: the element to register
1095 * @parent: the parent to register the element with
1097 * Register an element with the core. It will be register under the given
1098 * parent of if %NULL is provided under the root element.
1100 * Returns: %0 on success
1102 int connman_element_register(struct connman_element *element,
1103 struct connman_element *parent)
1105 DBG("element %p name %s parent %p", element, element->name, parent);
1107 if (element->devname == NULL)
1108 element->devname = g_strdup(element->name);
1110 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
1113 if (__connman_element_device_isfiltered(element->devname) == TRUE)
1117 if (connman_element_ref(element) == NULL)
1120 if (element->name == NULL) {
1121 element->name = g_strdup(type2string(element->type));
1122 if (element->name == NULL) {
1127 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
1128 element->ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
1130 element->parent = parent;
1132 register_element(element, NULL);
1137 static gboolean remove_element(GNode *node, gpointer user_data)
1139 struct connman_element *element = node->data;
1140 struct connman_element *root = user_data;
1142 DBG("element %p name %s", element, element->name);
1144 if (element == root)
1147 g_node_unlink(node);
1149 if (element->driver) {
1150 if (element->driver->remove)
1151 element->driver->remove(element);
1153 element->driver = NULL;
1156 g_node_destroy(node);
1158 connman_element_unref(element);
1163 struct unregister_type {
1164 struct connman_element *root;
1165 enum connman_element_type type;
1168 static gboolean remove_element_type(GNode *node, gpointer user_data)
1170 struct unregister_type *children_type = user_data;
1171 struct connman_element *root = children_type->root;
1172 struct connman_element *element = node->data;
1173 enum connman_element_type type = children_type->type;
1175 DBG("element %p name %s", element, element->name);
1177 if (element == root)
1180 if(element->type != type)
1183 g_node_unlink(node);
1185 if (element->driver) {
1186 if (element->driver->remove)
1187 element->driver->remove(element);
1189 element->driver = NULL;
1192 g_node_destroy(node);
1194 connman_element_unref(element);
1200 void connman_element_unregister(struct connman_element *element)
1204 DBG("element %p name %s", element, element->name);
1206 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1209 g_node_traverse(node, G_POST_ORDER,
1210 G_TRAVERSE_ALL, -1, remove_element, NULL);
1213 void connman_element_unregister_children(struct connman_element *element)
1217 DBG("element %p name %s", element, element->name);
1219 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1222 g_node_traverse(node, G_POST_ORDER,
1223 G_TRAVERSE_ALL, -1, remove_element, element);
1226 void connman_element_unregister_children_type(struct connman_element *element, enum connman_element_type type)
1230 DBG("element %p name %s", element, element->name);
1232 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1235 struct unregister_type children_type;
1237 children_type.root = element;
1238 children_type.type = type;
1239 g_node_traverse(node, G_POST_ORDER,
1240 G_TRAVERSE_ALL, -1, remove_element_type, &children_type);
1245 static gboolean update_element(GNode *node, gpointer user_data)
1247 struct connman_element *element = node->data;
1249 DBG("element %p name %s", element, element->name);
1251 if (element->driver && element->driver->update)
1252 element->driver->update(element);
1257 void connman_element_update(struct connman_element *element)
1261 DBG("element %p name %s", element, element->name);
1263 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1266 g_node_traverse(node, G_PRE_ORDER,
1267 G_TRAVERSE_ALL, -1, update_element, element);
1270 int connman_element_set_enabled(struct connman_element *element,
1273 if (element->enabled == enabled)
1276 element->enabled = enabled;
1278 connman_element_update(element);
1283 static enum connman_service_error convert_error(enum connman_element_error error)
1286 case CONNMAN_ELEMENT_ERROR_UNKNOWN:
1287 case CONNMAN_ELEMENT_ERROR_FAILED:
1289 case CONNMAN_ELEMENT_ERROR_DHCP_FAILED:
1290 return CONNMAN_SERVICE_ERROR_DHCP_FAILED;
1291 case CONNMAN_ELEMENT_ERROR_CONNECT_FAILED:
1292 return CONNMAN_SERVICE_ERROR_CONNECT_FAILED;
1295 return CONNMAN_SERVICE_ERROR_UNKNOWN;
1299 * connman_element_set_error:
1300 * @element: element structure
1301 * @error: error identifier
1303 * Set error state and specific error identifier
1305 void connman_element_set_error(struct connman_element *element,
1306 enum connman_element_error error)
1308 struct connman_service *service;
1310 DBG("element %p error %d", element, error);
1312 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1315 element->state = CONNMAN_ELEMENT_STATE_ERROR;
1316 element->error = error;
1318 if (element->driver && element->driver->change)
1319 element->driver->change(element);
1321 service = __connman_element_get_service(element);
1322 __connman_service_indicate_error(service, convert_error(error));
1325 int __connman_element_init(const char *device, const char *nodevice)
1327 struct connman_element *element;
1331 connection = connman_dbus_get_connection();
1332 if (connection == NULL)
1336 device_filter = g_strsplit(device, ",", -1);
1339 nodevice_filter = g_strsplit(nodevice, ",", -1);
1341 element = connman_element_create("root");
1343 element->path = g_strdup("/");
1344 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1346 element_root = g_node_new(element);
1348 __connman_technology_init();
1349 __connman_notifier_init();
1350 __connman_location_init();
1351 __connman_service_init();
1352 __connman_provider_init();
1353 __connman_network_init();
1354 __connman_device_init();
1359 static gboolean probe_node(GNode *node, gpointer data)
1361 struct connman_element *element = node->data;
1363 DBG("element %p name %s", element, element->name);
1365 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1368 if (element->driver)
1371 probe_element(element);
1376 void __connman_element_start(void)
1380 __connman_storage_init_profile();
1382 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1387 __connman_rtnl_start();
1389 __connman_connection_init();
1390 __connman_ipv4_init();
1391 __connman_dhcp_init();
1392 __connman_wpad_init();
1394 __connman_rfkill_init();
1397 void __connman_element_stop(void)
1401 __connman_rfkill_cleanup();
1403 __connman_wpad_cleanup();
1404 __connman_dhcp_cleanup();
1405 __connman_ipv4_cleanup();
1406 __connman_provider_cleanup();
1407 __connman_connection_cleanup();
1410 static gboolean free_driver(GNode *node, gpointer data)
1412 struct connman_element *element = node->data;
1414 DBG("element %p name %s", element, element->name);
1416 if (element->driver) {
1417 if (element->driver->remove)
1418 element->driver->remove(element);
1420 element->driver = NULL;
1426 static gboolean free_node(GNode *node, gpointer data)
1428 struct connman_element *element = node->data;
1430 DBG("element %p name %s", element, element->name);
1432 if (g_node_depth(node) > 1)
1433 connman_element_unregister(element);
1438 void __connman_element_cleanup(void)
1442 __connman_device_cleanup();
1443 __connman_network_cleanup();
1444 __connman_service_cleanup();
1445 __connman_location_cleanup();
1446 __connman_notifier_cleanup();
1447 __connman_technology_cleanup();
1449 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1452 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1455 g_node_destroy(element_root);
1456 element_root = NULL;
1458 g_strfreev(nodevice_filter);
1459 g_strfreev(device_filter);
1461 if (connection == NULL)
1464 dbus_connection_unref(connection);