5 * Copyright (C) 2007-2009 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;
41 static gboolean started = FALSE;
43 static const char *type2string(enum connman_element_type type)
46 case CONNMAN_ELEMENT_TYPE_UNKNOWN:
48 case CONNMAN_ELEMENT_TYPE_ROOT:
50 case CONNMAN_ELEMENT_TYPE_PROFILE:
52 case CONNMAN_ELEMENT_TYPE_DEVICE:
54 case CONNMAN_ELEMENT_TYPE_NETWORK:
56 case CONNMAN_ELEMENT_TYPE_SERVICE:
58 case CONNMAN_ELEMENT_TYPE_PPP:
60 case CONNMAN_ELEMENT_TYPE_IPV4:
62 case CONNMAN_ELEMENT_TYPE_IPV6:
64 case CONNMAN_ELEMENT_TYPE_DHCP:
66 case CONNMAN_ELEMENT_TYPE_BOOTP:
68 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
70 case CONNMAN_ELEMENT_TYPE_CONNECTION:
72 case CONNMAN_ELEMENT_TYPE_VENDOR:
79 const char *__connman_ipv4_method2string(enum connman_ipv4_method method)
82 case CONNMAN_IPV4_METHOD_UNKNOWN:
84 case CONNMAN_IPV4_METHOD_OFF:
86 case CONNMAN_IPV4_METHOD_STATIC:
88 case CONNMAN_IPV4_METHOD_DHCP:
95 enum connman_ipv4_method __connman_ipv4_string2method(const char *method)
97 if (strcasecmp(method, "off") == 0)
98 return CONNMAN_IPV4_METHOD_OFF;
99 else if (strcasecmp(method, "static") == 0)
100 return CONNMAN_IPV4_METHOD_STATIC;
101 else if (strcasecmp(method, "dhcp") == 0)
102 return CONNMAN_IPV4_METHOD_DHCP;
104 return CONNMAN_IPV4_METHOD_UNKNOWN;
107 static void emit_element_signal(DBusConnection *conn, const char *member,
108 struct connman_element *element)
112 if (__connman_debug_enabled() == FALSE)
115 DBG("conn %p member %s", conn, member);
120 signal = dbus_message_new_signal(element->path,
121 CONNMAN_DEBUG_INTERFACE, member);
125 g_dbus_send_message(conn, signal);
128 struct foreach_data {
129 enum connman_element_type type;
130 element_cb_t callback;
134 static gboolean foreach_callback(GNode *node, gpointer user_data)
136 struct connman_element *element = node->data;
137 struct foreach_data *data = user_data;
139 DBG("element %p name %s", element, element->name);
141 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
144 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
145 data->type != element->type)
149 data->callback(element, data->user_data);
154 void __connman_element_foreach(struct connman_element *element,
155 enum connman_element_type type,
156 element_cb_t callback, gpointer user_data)
158 struct foreach_data data = { type, callback, user_data };
163 if (element != NULL) {
164 node = g_node_find(element_root, G_PRE_ORDER,
165 G_TRAVERSE_ALL, element);
171 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
172 foreach_callback, &data);
175 struct append_filter {
176 enum connman_element_type type;
177 DBusMessageIter *iter;
180 static gboolean append_path(GNode *node, gpointer user_data)
182 struct connman_element *element = node->data;
183 struct append_filter *filter = user_data;
185 DBG("element %p name %s", element, element->name);
187 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
190 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
191 filter->type != element->type)
194 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
195 __connman_device_has_driver(element->device) == FALSE)
198 if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
199 __connman_network_has_driver(element->network) == FALSE)
202 dbus_message_iter_append_basic(filter->iter,
203 DBUS_TYPE_OBJECT_PATH, &element->path);
208 void __connman_element_list(struct connman_element *element,
209 enum connman_element_type type,
210 DBusMessageIter *iter)
212 struct append_filter filter = { type, iter };
217 if (element != NULL) {
218 node = g_node_find(element_root, G_PRE_ORDER,
219 G_TRAVERSE_ALL, element);
225 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
226 append_path, &filter);
230 enum connman_element_type type;
234 static gboolean count_element(GNode *node, gpointer user_data)
236 struct connman_element *element = node->data;
237 struct count_data *data = user_data;
239 DBG("element %p name %s", element, element->name);
241 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
244 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
245 data->type != element->type)
253 int __connman_element_count(struct connman_element *element,
254 enum connman_element_type type)
256 struct count_data data = { type, 0 };
261 if (element != NULL) {
262 node = g_node_find(element_root, G_PRE_ORDER,
263 G_TRAVERSE_ALL, element);
269 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
270 count_element, &data);
275 struct connman_service *__connman_element_get_service(struct connman_element *element)
277 struct connman_service *service;
278 struct connman_device *device;
279 enum connman_device_type type;
281 device = __connman_element_get_device(element);
285 type = connman_device_get_type(device);
288 case CONNMAN_DEVICE_TYPE_UNKNOWN:
289 case CONNMAN_DEVICE_TYPE_VENDOR:
290 case CONNMAN_DEVICE_TYPE_WIFI:
291 case CONNMAN_DEVICE_TYPE_WIMAX:
292 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
293 case CONNMAN_DEVICE_TYPE_GPS:
294 case CONNMAN_DEVICE_TYPE_HSO:
295 case CONNMAN_DEVICE_TYPE_NOZOMI:
296 case CONNMAN_DEVICE_TYPE_HUAWEI:
297 case CONNMAN_DEVICE_TYPE_NOVATEL:
299 case CONNMAN_DEVICE_TYPE_ETHERNET:
300 service = __connman_service_lookup_from_device(device);
307 struct connman_device *__connman_element_get_device(struct connman_element *element)
309 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
310 element->device != NULL)
311 return element->device;
313 if (element->parent == NULL)
316 return __connman_element_get_device(element->parent);
319 const char *__connman_element_get_device_path(struct connman_element *element)
321 struct connman_device *device;
323 device = __connman_element_get_device(element);
327 return element->path;
330 const char *__connman_element_get_network_path(struct connman_element *element)
332 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
333 element->network != NULL)
334 return element->path;
336 if (element->parent == NULL)
339 return __connman_element_get_network_path(element->parent);
342 static gint compare_priority(gconstpointer a, gconstpointer b)
344 const struct connman_driver *driver1 = a;
345 const struct connman_driver *driver2 = b;
347 return driver2->priority - driver1->priority;
350 static gboolean match_driver(struct connman_element *element,
351 struct connman_driver *driver)
353 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
356 if (element->type == driver->type ||
357 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
363 static gboolean probe_driver(GNode *node, gpointer data)
365 struct connman_element *element = node->data;
366 struct connman_driver *driver = data;
368 DBG("element %p name %s", element, element->name);
370 if (!element->driver && match_driver(element, driver) == TRUE) {
371 if (driver->probe(element) < 0)
374 __connman_element_lock(element);
375 element->driver = driver;
376 __connman_element_unlock(element);
382 void __connman_driver_rescan(struct connman_driver *driver)
384 DBG("driver %p name %s", driver, driver->name);
389 if (element_root != NULL)
390 g_node_traverse(element_root, G_PRE_ORDER,
391 G_TRAVERSE_ALL, -1, probe_driver, driver);
395 * connman_driver_register:
396 * @driver: driver definition
398 * Register a new driver
400 * Returns: %0 on success
402 int connman_driver_register(struct connman_driver *driver)
404 DBG("driver %p name %s", driver, driver->name);
406 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
412 driver_list = g_slist_insert_sorted(driver_list, driver,
415 if (started == FALSE)
418 if (element_root != NULL)
419 g_node_traverse(element_root, G_PRE_ORDER,
420 G_TRAVERSE_ALL, -1, probe_driver, driver);
425 static gboolean remove_driver(GNode *node, gpointer data)
427 struct connman_element *element = node->data;
428 struct connman_driver *driver = data;
430 DBG("element %p name %s", element, element->name);
432 if (element->driver == driver) {
434 driver->remove(element);
436 __connman_element_lock(element);
437 element->driver = NULL;
438 __connman_element_unlock(element);
445 * connman_driver_unregister:
446 * @driver: driver definition
448 * Remove a previously registered driver
450 void connman_driver_unregister(struct connman_driver *driver)
452 DBG("driver %p name %s", driver, driver->name);
454 driver_list = g_slist_remove(driver_list, driver);
456 if (element_root != NULL)
457 g_node_traverse(element_root, G_POST_ORDER,
458 G_TRAVERSE_ALL, -1, remove_driver, driver);
461 static void unregister_property(gpointer data)
463 struct connman_property *property = data;
465 DBG("property %p", property);
467 g_free(property->value);
471 void __connman_element_initialize(struct connman_element *element)
473 DBG("element %p", element);
475 element->refcount = 1;
477 element->name = NULL;
478 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
479 element->state = CONNMAN_ELEMENT_STATE_UNKNOWN;
480 element->error = CONNMAN_ELEMENT_ERROR_UNKNOWN;
482 element->enabled = FALSE;
484 element->configuring = FALSE;
486 element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
487 g_free, unregister_property);
491 * connman_element_create:
492 * @name: element name
494 * Allocate a new element and assign the given #name to it. If the name
495 * is #NULL, it will be later on created based on the element type.
497 * Returns: a newly-allocated #connman_element structure
499 struct connman_element *connman_element_create(const char *name)
501 struct connman_element *element;
503 element = g_try_new0(struct connman_element, 1);
507 DBG("element %p", element);
509 __connman_element_initialize(element);
514 struct connman_element *connman_element_ref(struct connman_element *element)
516 DBG("element %p name %s refcount %d", element, element->name,
517 g_atomic_int_get(&element->refcount) + 1);
519 g_atomic_int_inc(&element->refcount);
524 static void free_properties(struct connman_element *element)
526 DBG("element %p name %s", element, element->name);
528 __connman_element_lock(element);
530 g_hash_table_destroy(element->properties);
531 element->properties = NULL;
533 __connman_element_unlock(element);
536 void connman_element_unref(struct connman_element *element)
538 DBG("element %p name %s refcount %d", element, element->name,
539 g_atomic_int_get(&element->refcount) - 1);
541 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
542 if (element->destruct)
543 element->destruct(element);
544 free_properties(element);
545 g_free(element->ipv4.address);
546 g_free(element->ipv4.netmask);
547 g_free(element->ipv4.gateway);
548 g_free(element->ipv4.network);
549 g_free(element->ipv4.broadcast);
550 g_free(element->ipv4.nameserver);
551 g_free(element->devname);
552 g_free(element->path);
553 g_free(element->name);
558 static int set_static_property(struct connman_element *element,
559 const char *name, int type, const void *value)
561 struct connman_property *property;
563 DBG("element %p name %s", element, element->name);
565 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
568 property = g_try_new0(struct connman_property, 1);
569 if (property == NULL)
572 property->id = CONNMAN_PROPERTY_ID_INVALID;
573 property->type = type;
575 DBG("name %s type %d value %p", name, type, value);
578 case DBUS_TYPE_STRING:
579 property->value = g_strdup(*((const char **) value));
582 property->value = g_try_malloc(1);
583 if (property->value != NULL)
584 memcpy(property->value, value, 1);
588 __connman_element_lock(element);
590 g_hash_table_replace(element->properties, g_strdup(name), property);
592 __connman_element_unlock(element);
597 static int set_static_array_property(struct connman_element *element,
598 const char *name, int type, const void *value, int len)
600 struct connman_property *property;
602 DBG("element %p name %s", element, element->name);
604 if (type != DBUS_TYPE_BYTE)
607 property = g_try_new0(struct connman_property, 1);
608 if (property == NULL)
611 property->id = CONNMAN_PROPERTY_ID_INVALID;
612 property->type = DBUS_TYPE_ARRAY;
613 property->subtype = type;
615 DBG("name %s type %d value %p", name, type, value);
619 property->value = g_try_malloc(len);
620 if (property->value != NULL) {
621 memcpy(property->value,
622 *((const unsigned char **) value), len);
623 property->size = len;
628 __connman_element_lock(element);
630 g_hash_table_replace(element->properties, g_strdup(name), property);
632 __connman_element_unlock(element);
638 static int set_property(struct connman_element *element,
639 enum connman_property_id id, const void *value)
642 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
643 __connman_element_lock(element);
644 g_free(element->ipv4.address);
645 element->ipv4.address = g_strdup(*((const char **) value));
646 __connman_element_unlock(element);
648 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
649 __connman_element_lock(element);
650 g_free(element->ipv4.netmask);
651 element->ipv4.netmask = g_strdup(*((const char **) value));
652 __connman_element_unlock(element);
654 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
655 __connman_element_lock(element);
656 g_free(element->ipv4.gateway);
657 element->ipv4.gateway = g_strdup(*((const char **) value));
658 __connman_element_unlock(element);
660 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
661 __connman_element_lock(element);
662 g_free(element->ipv4.broadcast);
663 element->ipv4.broadcast = g_strdup(*((const char **) value));
664 __connman_element_unlock(element);
666 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
667 __connman_element_lock(element);
668 g_free(element->ipv4.nameserver);
669 element->ipv4.nameserver = g_strdup(*((const char **) value));
670 __connman_element_unlock(element);
680 int connman_element_get_value(struct connman_element *element,
681 enum connman_property_id id, void *value)
683 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
687 case CONNMAN_PROPERTY_ID_IPV4_METHOD:
688 if (element->ipv4.method == CONNMAN_IPV4_METHOD_UNKNOWN)
689 return connman_element_get_value(element->parent,
691 __connman_element_lock(element);
692 *((const char **) value) = __connman_ipv4_method2string(element->ipv4.method);
693 __connman_element_unlock(element);
695 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
696 if (element->ipv4.address == NULL)
697 return connman_element_get_value(element->parent,
699 __connman_element_lock(element);
700 *((char **) value) = element->ipv4.address;
701 __connman_element_unlock(element);
703 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
704 if (element->ipv4.netmask == NULL)
705 return connman_element_get_value(element->parent,
707 __connman_element_lock(element);
708 *((char **) value) = element->ipv4.netmask;
709 __connman_element_unlock(element);
711 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
712 if (element->ipv4.gateway == NULL)
713 return connman_element_get_value(element->parent,
715 __connman_element_lock(element);
716 *((char **) value) = element->ipv4.gateway;
717 __connman_element_unlock(element);
719 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
720 if (element->ipv4.broadcast == NULL)
721 return connman_element_get_value(element->parent,
723 __connman_element_lock(element);
724 *((char **) value) = element->ipv4.broadcast;
725 __connman_element_unlock(element);
727 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
728 if (element->ipv4.nameserver == NULL)
729 return connman_element_get_value(element->parent,
731 __connman_element_lock(element);
732 *((char **) value) = element->ipv4.nameserver;
733 __connman_element_unlock(element);
742 static gboolean get_static_property(struct connman_element *element,
743 const char *name, void *value)
745 struct connman_property *property;
746 gboolean found = FALSE;
748 DBG("element %p name %s", element, element->name);
750 __connman_element_lock(element);
752 property = g_hash_table_lookup(element->properties, name);
753 if (property != NULL) {
754 switch (property->type) {
755 case DBUS_TYPE_STRING:
756 *((char **) value) = property->value;
760 memcpy(value, property->value, 1);
766 __connman_element_unlock(element);
768 if (found == FALSE && element->parent != NULL)
769 return get_static_property(element->parent, name, value);
774 static gboolean get_static_array_property(struct connman_element *element,
775 const char *name, void *value, unsigned int *len)
777 struct connman_property *property;
778 gboolean found = FALSE;
780 DBG("element %p name %s", element, element->name);
782 __connman_element_lock(element);
784 property = g_hash_table_lookup(element->properties, name);
785 if (property != NULL) {
786 *((char **) value) = property->value;
787 *len = property->size;
791 __connman_element_unlock(element);
797 static gboolean match_static_property(struct connman_element *element,
798 const char *name, const void *value)
800 struct connman_property *property;
801 gboolean result = FALSE;
803 DBG("element %p name %s", element, element->name);
805 __connman_element_lock(element);
807 property = g_hash_table_lookup(element->properties, name);
808 if (property != NULL) {
809 if (property->type == DBUS_TYPE_STRING)
810 result = g_str_equal(property->value,
811 *((const char **) value));
814 __connman_element_unlock(element);
821 * connman_element_set_string:
822 * @element: element structure
823 * @key: unique identifier
824 * @value: string value
826 * Set string value for specific key
828 int connman_element_set_string(struct connman_element *element,
829 const char *key, const char *value)
831 return set_static_property(element, key, DBUS_TYPE_STRING, &value);
835 * connman_element_get_string:
836 * @element: element structure
837 * @key: unique identifier
839 * Get string value for specific key
841 const char *connman_element_get_string(struct connman_element *element,
846 if (get_static_property(element, key, &value) == FALSE)
853 * connman_element_set_uint8:
854 * @element: element structure
855 * @key: unique identifier
856 * @value: integer value
858 * Set integer value for specific key
860 int connman_element_set_uint8(struct connman_element *element,
861 const char *key, connman_uint8_t value)
863 return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
867 * connman_element_get_uint8:
868 * @element: element structure
869 * @key: unique identifier
871 * Get integer value for specific key
873 connman_uint8_t connman_element_get_uint8(struct connman_element *element,
876 connman_uint8_t value;
878 if (get_static_property(element, key, &value) == FALSE)
885 * connman_element_set_blob:
886 * @element: element structure
887 * @key: unique identifier
891 * Set binary blob value for specific key
893 int connman_element_set_blob(struct connman_element *element,
894 const char *key, const void *data, unsigned int size)
896 return set_static_array_property(element, key,
897 DBUS_TYPE_BYTE, &data, size);
901 * connman_element_get_blob:
902 * @element: element structure
903 * @key: unique identifier
904 * @size: pointer to blob size
906 * Get binary blob value for specific key
908 const void *connman_element_get_blob(struct connman_element *element,
909 const char *key, unsigned int *size)
913 if (get_static_array_property(element, key, &value, size) == FALSE)
919 int __connman_element_append_ipv4(struct connman_element *element,
920 DBusMessageIter *dict)
922 const char *method = NULL;
923 const char *address = NULL, *netmask = NULL, *gateway = NULL;
925 connman_element_get_value(element,
926 CONNMAN_PROPERTY_ID_IPV4_METHOD, &method);
928 connman_element_get_value(element,
929 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
930 connman_element_get_value(element,
931 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
932 connman_element_get_value(element,
933 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
936 connman_dbus_dict_append_variant(dict, "IPv4.Method",
937 DBUS_TYPE_STRING, &method);
940 connman_dbus_dict_append_variant(dict, "IPv4.Address",
941 DBUS_TYPE_STRING, &address);
944 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
945 DBUS_TYPE_STRING, &netmask);
948 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
949 DBUS_TYPE_STRING, &gateway);
954 int __connman_element_set_ipv4(struct connman_element *element,
955 const char *name, DBusMessageIter *value)
959 type = dbus_message_iter_get_arg_type(value);
961 if (g_str_equal(name, "IPv4.Method") == TRUE) {
962 enum connman_ipv4_method method;
965 if (type != DBUS_TYPE_STRING)
968 dbus_message_iter_get_basic(value, &str);
969 method = __connman_ipv4_string2method(str);
970 if (method == CONNMAN_IPV4_METHOD_UNKNOWN)
973 if (method == element->ipv4.method)
976 element->ipv4.method = method;
978 connman_element_update(element);
979 } else if (g_str_equal(name, "IPv4.Address") == TRUE) {
982 if (type != DBUS_TYPE_STRING)
985 dbus_message_iter_get_basic(value, &address);
987 g_free(element->ipv4.address);
988 element->ipv4.address = g_strdup(address);
990 connman_element_update(element);
991 } else if (g_str_equal(name, "IPv4.Netmask") == TRUE) {
994 if (type != DBUS_TYPE_STRING)
997 dbus_message_iter_get_basic(value, &netmask);
999 g_free(element->ipv4.netmask);
1000 element->ipv4.netmask = g_strdup(netmask);
1002 connman_element_update(element);
1003 } else if (g_str_equal(name, "IPv4.Gateway") == TRUE) {
1004 const char *gateway;
1006 if (type != DBUS_TYPE_STRING)
1009 dbus_message_iter_get_basic(value, &gateway);
1011 g_free(element->ipv4.gateway);
1012 element->ipv4.gateway = g_strdup(gateway);
1014 connman_element_update(element);
1020 static void append_state(DBusMessageIter *entry, const char *state)
1022 DBusMessageIter value;
1023 const char *key = "State";
1025 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1027 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1028 DBUS_TYPE_STRING_AS_STRING, &value);
1029 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1030 dbus_message_iter_close_container(entry, &value);
1033 static void emit_state_change(DBusConnection *conn, const char *state)
1035 DBusMessage *signal;
1036 DBusMessageIter entry;
1038 DBG("conn %p", conn);
1040 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1041 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1045 dbus_message_iter_init_append(signal, &entry);
1047 append_state(&entry, state);
1049 g_dbus_send_message(conn, signal);
1052 static void probe_element(struct connman_element *element)
1056 DBG("element %p name %s", element, element->name);
1058 for (list = driver_list; list; list = list->next) {
1059 struct connman_driver *driver = list->data;
1061 if (match_driver(element, driver) == FALSE)
1064 DBG("driver %p name %s", driver, driver->name);
1066 if (driver->probe(element) == 0) {
1067 __connman_element_lock(element);
1068 element->driver = driver;
1069 __connman_element_unlock(element);
1075 static void register_element(gpointer data, gpointer user_data)
1077 struct connman_element *element = data;
1078 const gchar *basepath;
1081 __connman_element_lock(element);
1083 if (element->parent) {
1084 node = g_node_find(element_root, G_PRE_ORDER,
1085 G_TRAVERSE_ALL, element->parent);
1086 basepath = element->parent->path;
1088 element->parent = element_root->data;
1090 node = element_root;
1094 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1096 __connman_element_unlock(element);
1098 DBG("element %p path %s", element, element->path);
1100 g_node_append_data(node, element);
1102 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP) {
1103 element->parent->configuring = TRUE;
1105 if (__connman_element_count(NULL,
1106 CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
1107 emit_state_change(connection, "connecting");
1110 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1111 struct connman_element *parent = element->parent;
1114 parent->configuring = FALSE;
1115 parent = parent->parent;
1118 if (__connman_element_count(NULL,
1119 CONNMAN_ELEMENT_TYPE_CONNECTION) == 1)
1120 emit_state_change(connection, "online");
1123 emit_element_signal(connection, "ElementAdded", element);
1125 if (started == FALSE)
1128 probe_element(element);
1132 * connman_element_register:
1133 * @element: the element to register
1134 * @parent: the parent to register the element with
1136 * Register an element with the core. It will be register under the given
1137 * parent of if %NULL is provided under the root element.
1139 * Returns: %0 on success
1141 int connman_element_register(struct connman_element *element,
1142 struct connman_element *parent)
1144 DBG("element %p name %s parent %p", element, element->name, parent);
1146 if (element->devname == NULL)
1147 element->devname = g_strdup(element->name);
1149 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1150 if (g_pattern_match_simple(device_filter,
1151 element->devname) == FALSE) {
1152 DBG("ignoring %s [%s] device", element->name,
1158 if (connman_element_ref(element) == NULL)
1161 __connman_element_lock(element);
1163 if (element->name == NULL) {
1164 element->name = g_strdup(type2string(element->type));
1165 if (element->name == NULL) {
1166 __connman_element_unlock(element);
1171 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
1172 element->ipv4.method = CONNMAN_IPV4_METHOD_DHCP;
1174 element->parent = parent;
1176 __connman_element_unlock(element);
1178 register_element(element, NULL);
1183 static gboolean remove_element(GNode *node, gpointer user_data)
1185 struct connman_element *element = node->data;
1186 struct connman_element *root = user_data;
1188 DBG("element %p name %s", element, element->name);
1190 if (element == root)
1194 g_node_unlink(node);
1196 if (element->driver) {
1197 if (element->driver->remove)
1198 element->driver->remove(element);
1200 __connman_element_lock(element);
1201 element->driver = NULL;
1202 __connman_element_unlock(element);
1206 g_node_destroy(node);
1208 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1209 if (__connman_element_count(NULL,
1210 CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
1211 emit_state_change(connection, "offline");
1214 emit_element_signal(connection, "ElementRemoved", element);
1216 connman_element_unref(element);
1221 void connman_element_unregister(struct connman_element *element)
1225 DBG("element %p name %s", element, element->name);
1227 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1230 g_node_traverse(node, G_POST_ORDER,
1231 G_TRAVERSE_ALL, -1, remove_element, NULL);
1234 void connman_element_unregister_children(struct connman_element *element)
1238 DBG("element %p name %s", element, element->name);
1240 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1243 g_node_traverse(node, G_POST_ORDER,
1244 G_TRAVERSE_ALL, -1, remove_element, element);
1247 static gboolean update_element(GNode *node, gpointer user_data)
1249 struct connman_element *element = node->data;
1251 DBG("element %p name %s", element, element->name);
1253 if (element->driver && element->driver->update)
1254 element->driver->update(element);
1256 emit_element_signal(connection, "ElementUpdated", element);
1261 void connman_element_update(struct connman_element *element)
1265 DBG("element %p name %s", element, element->name);
1267 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1270 g_node_traverse(node, G_PRE_ORDER,
1271 G_TRAVERSE_ALL, -1, update_element, element);
1274 int connman_element_set_enabled(struct connman_element *element,
1277 if (element->enabled == enabled)
1280 element->enabled = enabled;
1282 connman_element_update(element);
1288 * connman_element_set_error:
1289 * @element: element structure
1290 * @error: error identifier
1292 * Set error state and specific error identifier
1294 void connman_element_set_error(struct connman_element *element,
1295 enum connman_element_error error)
1297 DBG("element %p error %d", element, error);
1299 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1302 element->state = CONNMAN_ELEMENT_STATE_ERROR;
1303 element->error = error;
1305 if (element->driver && element->driver->change)
1306 element->driver->change(element);
1309 int __connman_element_init(DBusConnection *conn, const char *device,
1310 const char *nodevice)
1312 struct connman_element *element;
1314 DBG("conn %p", conn);
1316 connection = dbus_connection_ref(conn);
1317 if (connection == NULL)
1320 device_filter = g_strdup(device);
1322 element = connman_element_create("root");
1324 element->path = g_strdup("/");
1325 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1327 element_root = g_node_new(element);
1329 __connman_notifier_init();
1330 __connman_service_init();
1331 __connman_network_init();
1332 __connman_device_init();
1337 static gboolean probe_node(GNode *node, gpointer data)
1339 struct connman_element *element = node->data;
1341 DBG("element %p name %s", element, element->name);
1343 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1346 if (element->driver)
1349 probe_element(element);
1354 void __connman_element_start(void)
1358 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1363 __connman_storage_init_device();
1365 __connman_connection_init();
1366 __connman_ipv4_init();
1367 __connman_detect_init();
1370 void __connman_element_stop(void)
1374 __connman_detect_cleanup();
1375 __connman_ipv4_cleanup();
1376 __connman_connection_cleanup();
1379 static gboolean free_driver(GNode *node, gpointer data)
1381 struct connman_element *element = node->data;
1383 DBG("element %p name %s", element, element->name);
1385 if (element->driver) {
1386 if (element->driver->remove)
1387 element->driver->remove(element);
1389 __connman_element_lock(element);
1390 element->driver = NULL;
1391 __connman_element_unlock(element);
1397 static gboolean free_node(GNode *node, gpointer data)
1399 struct connman_element *element = node->data;
1401 DBG("element %p name %s", element, element->name);
1403 if (g_node_depth(node) > 1)
1404 connman_element_unregister(element);
1409 void __connman_element_cleanup(void)
1413 __connman_device_cleanup();
1414 __connman_network_cleanup();
1415 __connman_service_cleanup();
1416 __connman_notifier_cleanup();
1418 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1421 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1424 g_node_destroy(element_root);
1425 element_root = NULL;
1427 g_free(device_filter);
1429 dbus_connection_unref(connection);