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;
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_PPP:
61 case CONNMAN_ELEMENT_TYPE_IPV4:
63 case CONNMAN_ELEMENT_TYPE_IPV6:
65 case CONNMAN_ELEMENT_TYPE_DHCP:
67 case CONNMAN_ELEMENT_TYPE_BOOTP:
69 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
71 case CONNMAN_ELEMENT_TYPE_CONNECTION:
73 case CONNMAN_ELEMENT_TYPE_VENDOR:
81 enum connman_element_type type;
82 element_cb_t callback;
86 static gboolean foreach_callback(GNode *node, gpointer user_data)
88 struct connman_element *element = node->data;
89 struct foreach_data *data = user_data;
91 DBG("element %p name %s", element, element->name);
93 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
96 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
97 data->type != element->type)
101 data->callback(element, data->user_data);
106 void __connman_element_foreach(struct connman_element *element,
107 enum connman_element_type type,
108 element_cb_t callback, gpointer user_data)
110 struct foreach_data data = { type, callback, user_data };
115 if (element != NULL) {
116 node = g_node_find(element_root, G_PRE_ORDER,
117 G_TRAVERSE_ALL, element);
123 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
124 foreach_callback, &data);
127 struct append_filter {
128 enum connman_element_type type;
129 DBusMessageIter *iter;
132 static gboolean append_path(GNode *node, gpointer user_data)
134 struct connman_element *element = node->data;
135 struct append_filter *filter = user_data;
137 DBG("element %p name %s", element, element->name);
139 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
142 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
143 filter->type != element->type)
146 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
147 __connman_device_has_driver(element->device) == FALSE)
150 if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
151 __connman_network_has_driver(element->network) == FALSE)
154 dbus_message_iter_append_basic(filter->iter,
155 DBUS_TYPE_OBJECT_PATH, &element->path);
160 void __connman_element_list(struct connman_element *element,
161 enum connman_element_type type,
162 DBusMessageIter *iter)
164 struct append_filter filter = { type, iter };
169 if (element != NULL) {
170 node = g_node_find(element_root, G_PRE_ORDER,
171 G_TRAVERSE_ALL, element);
177 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
178 append_path, &filter);
182 enum connman_element_type type;
186 static gboolean count_element(GNode *node, gpointer user_data)
188 struct connman_element *element = node->data;
189 struct count_data *data = user_data;
191 DBG("element %p name %s", element, element->name);
193 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
196 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
197 data->type != element->type)
205 int __connman_element_count(struct connman_element *element,
206 enum connman_element_type type)
208 struct count_data data = { type, 0 };
213 if (element != NULL) {
214 node = g_node_find(element_root, G_PRE_ORDER,
215 G_TRAVERSE_ALL, element);
221 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
222 count_element, &data);
227 static struct connman_network *__connman_element_get_network(struct connman_element *element)
229 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
230 element->network != NULL)
231 return element->network;
233 if (element->parent == NULL)
236 return __connman_element_get_network(element->parent);
239 struct connman_service *__connman_element_get_service(struct connman_element *element)
241 struct connman_service *service = NULL;
242 struct connman_network *network;
243 struct connman_device *device;
244 enum connman_device_type type;
246 device = __connman_element_get_device(element);
250 type = connman_device_get_type(device);
253 case CONNMAN_DEVICE_TYPE_UNKNOWN:
254 case CONNMAN_DEVICE_TYPE_VENDOR:
255 case CONNMAN_DEVICE_TYPE_GPS:
256 case CONNMAN_DEVICE_TYPE_NOZOMI:
257 case CONNMAN_DEVICE_TYPE_HUAWEI:
258 case CONNMAN_DEVICE_TYPE_NOVATEL:
260 case CONNMAN_DEVICE_TYPE_ETHERNET:
261 service = __connman_service_lookup_from_device(device);
263 case CONNMAN_DEVICE_TYPE_WIFI:
264 case CONNMAN_DEVICE_TYPE_WIMAX:
265 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
266 case CONNMAN_DEVICE_TYPE_MBM:
267 case CONNMAN_DEVICE_TYPE_CELLULAR:
268 case CONNMAN_DEVICE_TYPE_HSO:
269 network = __connman_element_get_network(element);
272 service = __connman_service_lookup_from_network(network);
279 struct connman_device *__connman_element_get_device(struct connman_element *element)
281 if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
282 element->device != NULL)
283 return element->device;
285 if (element->parent == NULL)
288 return __connman_element_get_device(element->parent);
291 const char *__connman_element_get_device_path(struct connman_element *element)
293 struct connman_device *device;
295 device = __connman_element_get_device(element);
299 return connman_device_get_path(device);
302 const char *__connman_element_get_network_path(struct connman_element *element)
304 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
305 element->network != NULL)
306 return element->path;
308 if (element->parent == NULL)
311 return __connman_element_get_network_path(element->parent);
315 enum connman_service_type type;
316 struct connman_device *device;
319 static gboolean find_device(GNode *node, gpointer user_data)
321 struct connman_element *element = node->data;
322 struct find_data *data = user_data;
324 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
327 if (element->device == NULL)
330 if (data->type != connman_device_get_type(element->device))
333 data->device = element->device;
338 struct connman_device *__connman_element_find_device(enum connman_service_type type)
340 struct find_data data = { .type = type, .device = NULL };
342 g_node_traverse(element_root, G_PRE_ORDER,
343 G_TRAVERSE_ALL, -1, find_device, &data);
348 static gboolean request_scan(GNode *node, gpointer user_data)
350 struct connman_element *element = node->data;
351 struct find_data *data = user_data;
352 enum connman_service_type type;
354 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
357 if (element->device == NULL)
360 type = __connman_device_get_service_type(element->device);
363 case CONNMAN_SERVICE_TYPE_UNKNOWN:
364 case CONNMAN_SERVICE_TYPE_ETHERNET:
365 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
366 case CONNMAN_SERVICE_TYPE_CELLULAR:
368 case CONNMAN_SERVICE_TYPE_WIFI:
369 case CONNMAN_SERVICE_TYPE_WIMAX:
370 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
376 __connman_device_scan(element->device);
381 int __connman_element_request_scan(enum connman_service_type type)
383 struct find_data data = { .type = type, .device = NULL };
385 g_node_traverse(element_root, G_PRE_ORDER,
386 G_TRAVERSE_ALL, -1, request_scan, &data);
391 static gboolean enable_technology(GNode *node, gpointer user_data)
393 struct connman_element *element = node->data;
394 struct find_data *data = user_data;
395 enum connman_service_type type;
397 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
400 if (element->device == NULL)
403 type = __connman_device_get_service_type(element->device);
406 case CONNMAN_SERVICE_TYPE_UNKNOWN:
408 case CONNMAN_SERVICE_TYPE_ETHERNET:
409 case CONNMAN_SERVICE_TYPE_WIFI:
410 case CONNMAN_SERVICE_TYPE_WIMAX:
411 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
412 case CONNMAN_SERVICE_TYPE_CELLULAR:
413 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
419 __connman_device_enable_persistent(element->device);
424 int __connman_element_enable_technology(enum connman_service_type type)
426 struct find_data data = { .type = type, .device = NULL };
428 g_node_traverse(element_root, G_PRE_ORDER,
429 G_TRAVERSE_ALL, -1, enable_technology, &data);
434 static gboolean disable_technology(GNode *node, gpointer user_data)
436 struct connman_element *element = node->data;
437 struct find_data *data = user_data;
438 enum connman_service_type type;
440 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
443 if (element->device == NULL)
446 type = __connman_device_get_service_type(element->device);
449 case CONNMAN_SERVICE_TYPE_UNKNOWN:
451 case CONNMAN_SERVICE_TYPE_ETHERNET:
452 case CONNMAN_SERVICE_TYPE_WIFI:
453 case CONNMAN_SERVICE_TYPE_WIMAX:
454 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
455 case CONNMAN_SERVICE_TYPE_CELLULAR:
456 if (data->type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
462 __connman_device_disable_persistent(element->device);
467 int __connman_element_disable_technology(enum connman_service_type type)
469 struct find_data data = { .type = type, .device = NULL };
471 g_node_traverse(element_root, G_PRE_ORDER,
472 G_TRAVERSE_ALL, -1, disable_technology, &data);
477 static gint compare_priority(gconstpointer a, gconstpointer b)
479 const struct connman_driver *driver1 = a;
480 const struct connman_driver *driver2 = b;
482 return driver2->priority - driver1->priority;
485 static gboolean match_driver(struct connman_element *element,
486 struct connman_driver *driver)
488 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
491 if (element->type == driver->type ||
492 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
498 static gboolean probe_driver(GNode *node, gpointer data)
500 struct connman_element *element = node->data;
501 struct connman_driver *driver = data;
503 DBG("element %p name %s", element, element->name);
505 if (!element->driver && match_driver(element, driver) == TRUE) {
506 if (driver->probe(element) < 0)
509 __connman_element_lock(element);
510 element->driver = driver;
511 __connman_element_unlock(element);
517 void __connman_driver_rescan(struct connman_driver *driver)
519 DBG("driver %p name %s", driver, driver->name);
524 if (element_root != NULL)
525 g_node_traverse(element_root, G_PRE_ORDER,
526 G_TRAVERSE_ALL, -1, probe_driver, driver);
530 * connman_driver_register:
531 * @driver: driver definition
533 * Register a new driver
535 * Returns: %0 on success
537 int connman_driver_register(struct connman_driver *driver)
539 DBG("driver %p name %s", driver, driver->name);
541 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
547 driver_list = g_slist_insert_sorted(driver_list, driver,
550 if (started == FALSE)
553 if (element_root != NULL)
554 g_node_traverse(element_root, G_PRE_ORDER,
555 G_TRAVERSE_ALL, -1, probe_driver, driver);
560 static gboolean remove_driver(GNode *node, gpointer data)
562 struct connman_element *element = node->data;
563 struct connman_driver *driver = data;
565 DBG("element %p name %s", element, element->name);
567 if (element->driver == driver) {
569 driver->remove(element);
571 __connman_element_lock(element);
572 element->driver = NULL;
573 __connman_element_unlock(element);
580 * connman_driver_unregister:
581 * @driver: driver definition
583 * Remove a previously registered driver
585 void connman_driver_unregister(struct connman_driver *driver)
587 DBG("driver %p name %s", driver, driver->name);
589 driver_list = g_slist_remove(driver_list, driver);
591 if (element_root != NULL)
592 g_node_traverse(element_root, G_POST_ORDER,
593 G_TRAVERSE_ALL, -1, remove_driver, driver);
596 static void unregister_property(gpointer data)
598 struct connman_property *property = data;
600 DBG("property %p", property);
602 g_free(property->value);
606 void __connman_element_initialize(struct connman_element *element)
608 DBG("element %p", element);
610 element->refcount = 1;
612 element->name = NULL;
613 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
614 element->state = CONNMAN_ELEMENT_STATE_UNKNOWN;
615 element->error = CONNMAN_ELEMENT_ERROR_UNKNOWN;
617 element->enabled = FALSE;
619 element->configuring = FALSE;
621 element->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
622 g_free, unregister_property);
626 * connman_element_create:
627 * @name: element name
629 * Allocate a new element and assign the given #name to it. If the name
630 * is #NULL, it will be later on created based on the element type.
632 * Returns: a newly-allocated #connman_element structure
634 struct connman_element *connman_element_create(const char *name)
636 struct connman_element *element;
638 element = g_try_new0(struct connman_element, 1);
642 DBG("element %p", element);
644 __connman_element_initialize(element);
649 struct connman_element *connman_element_ref(struct connman_element *element)
651 DBG("element %p name %s refcount %d", element, element->name,
652 g_atomic_int_get(&element->refcount) + 1);
654 g_atomic_int_inc(&element->refcount);
659 static void free_properties(struct connman_element *element)
661 DBG("element %p name %s", element, element->name);
663 __connman_element_lock(element);
665 g_hash_table_destroy(element->properties);
666 element->properties = NULL;
668 __connman_element_unlock(element);
671 void connman_element_unref(struct connman_element *element)
673 DBG("element %p name %s refcount %d", element, element->name,
674 g_atomic_int_get(&element->refcount) - 1);
676 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
677 if (element->destruct)
678 element->destruct(element);
679 free_properties(element);
680 g_free(element->ipv4.address);
681 g_free(element->ipv4.netmask);
682 g_free(element->ipv4.gateway);
683 g_free(element->ipv4.network);
684 g_free(element->ipv4.broadcast);
685 g_free(element->ipv4.nameserver);
686 g_free(element->devname);
687 g_free(element->path);
688 g_free(element->name);
693 static int set_static_property(struct connman_element *element,
694 const char *name, int type, const void *value)
696 struct connman_property *property;
698 DBG("element %p name %s", element, element->name);
700 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
703 property = g_try_new0(struct connman_property, 1);
704 if (property == NULL)
707 property->id = CONNMAN_PROPERTY_ID_INVALID;
708 property->type = type;
710 DBG("name %s type %d value %p", name, type, value);
713 case DBUS_TYPE_STRING:
714 property->value = g_strdup(*((const char **) value));
716 case DBUS_TYPE_BOOLEAN:
718 property->value = g_try_malloc(1);
719 if (property->value != NULL)
720 memcpy(property->value, value, 1);
724 __connman_element_lock(element);
726 g_hash_table_replace(element->properties, g_strdup(name), property);
728 __connman_element_unlock(element);
733 static int set_static_array_property(struct connman_element *element,
734 const char *name, int type, const void *value, int len)
736 struct connman_property *property;
738 DBG("element %p name %s", element, element->name);
740 if (type != DBUS_TYPE_BYTE)
743 property = g_try_new0(struct connman_property, 1);
744 if (property == NULL)
747 property->id = CONNMAN_PROPERTY_ID_INVALID;
748 property->type = DBUS_TYPE_ARRAY;
749 property->subtype = type;
751 DBG("name %s type %d value %p", name, type, value);
755 property->value = g_try_malloc(len);
756 if (property->value != NULL) {
757 memcpy(property->value,
758 *((const unsigned char **) value), len);
759 property->size = len;
764 __connman_element_lock(element);
766 g_hash_table_replace(element->properties, g_strdup(name), property);
768 __connman_element_unlock(element);
774 static int set_property(struct connman_element *element,
775 enum connman_property_id id, const void *value)
778 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
779 __connman_element_lock(element);
780 g_free(element->ipv4.address);
781 element->ipv4.address = g_strdup(*((const char **) value));
782 __connman_element_unlock(element);
784 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
785 __connman_element_lock(element);
786 g_free(element->ipv4.netmask);
787 element->ipv4.netmask = g_strdup(*((const char **) value));
788 __connman_element_unlock(element);
790 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
791 __connman_element_lock(element);
792 g_free(element->ipv4.gateway);
793 element->ipv4.gateway = g_strdup(*((const char **) value));
794 __connman_element_unlock(element);
796 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
797 __connman_element_lock(element);
798 g_free(element->ipv4.broadcast);
799 element->ipv4.broadcast = g_strdup(*((const char **) value));
800 __connman_element_unlock(element);
802 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
803 __connman_element_lock(element);
804 g_free(element->ipv4.nameserver);
805 element->ipv4.nameserver = g_strdup(*((const char **) value));
806 __connman_element_unlock(element);
816 int connman_element_get_value(struct connman_element *element,
817 enum connman_property_id id, void *value)
819 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
823 case CONNMAN_PROPERTY_ID_IPV4_METHOD:
824 if (element->ipv4.method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
825 return connman_element_get_value(element->parent,
827 __connman_element_lock(element);
828 *((const char **) value) = __connman_ipconfig_method2string(element->ipv4.method);
829 __connman_element_unlock(element);
831 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
832 if (element->ipv4.address == NULL)
833 return connman_element_get_value(element->parent,
835 __connman_element_lock(element);
836 *((char **) value) = element->ipv4.address;
837 __connman_element_unlock(element);
839 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
840 if (element->ipv4.netmask == NULL)
841 return connman_element_get_value(element->parent,
843 __connman_element_lock(element);
844 *((char **) value) = element->ipv4.netmask;
845 __connman_element_unlock(element);
847 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
848 if (element->ipv4.gateway == NULL)
849 return connman_element_get_value(element->parent,
851 __connman_element_lock(element);
852 *((char **) value) = element->ipv4.gateway;
853 __connman_element_unlock(element);
855 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
856 if (element->ipv4.broadcast == NULL)
857 return connman_element_get_value(element->parent,
859 __connman_element_lock(element);
860 *((char **) value) = element->ipv4.broadcast;
861 __connman_element_unlock(element);
863 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
864 if (element->ipv4.nameserver == NULL)
865 return connman_element_get_value(element->parent,
867 __connman_element_lock(element);
868 *((char **) value) = element->ipv4.nameserver;
869 __connman_element_unlock(element);
878 static gboolean get_static_property(struct connman_element *element,
879 const char *name, void *value)
881 struct connman_property *property;
882 gboolean found = FALSE;
884 DBG("element %p name %s", element, element->name);
886 __connman_element_lock(element);
888 property = g_hash_table_lookup(element->properties, name);
889 if (property != NULL) {
890 switch (property->type) {
891 case DBUS_TYPE_STRING:
892 *((char **) value) = property->value;
895 case DBUS_TYPE_BOOLEAN:
897 memcpy(value, property->value, 1);
903 __connman_element_unlock(element);
905 if (found == FALSE && element->parent != NULL)
906 return get_static_property(element->parent, name, value);
911 static gboolean get_static_array_property(struct connman_element *element,
912 const char *name, void *value, unsigned int *len)
914 struct connman_property *property;
915 gboolean found = FALSE;
917 DBG("element %p name %s", element, element->name);
919 __connman_element_lock(element);
921 property = g_hash_table_lookup(element->properties, name);
922 if (property != NULL) {
923 *((void **) value) = property->value;
924 *len = property->size;
928 __connman_element_unlock(element);
934 static gboolean match_static_property(struct connman_element *element,
935 const char *name, const void *value)
937 struct connman_property *property;
938 gboolean result = FALSE;
940 DBG("element %p name %s", element, element->name);
942 __connman_element_lock(element);
944 property = g_hash_table_lookup(element->properties, name);
945 if (property != NULL) {
946 if (property->type == DBUS_TYPE_STRING)
947 result = g_str_equal(property->value,
948 *((const char **) value));
951 __connman_element_unlock(element);
958 * connman_element_set_string:
959 * @element: element structure
960 * @key: unique identifier
961 * @value: string value
963 * Set string value for specific key
965 int connman_element_set_string(struct connman_element *element,
966 const char *key, const char *value)
968 return set_static_property(element, key, DBUS_TYPE_STRING, &value);
972 * connman_element_get_string:
973 * @element: element structure
974 * @key: unique identifier
976 * Get string value for specific key
978 const char *connman_element_get_string(struct connman_element *element,
983 if (get_static_property(element, key, &value) == FALSE)
990 * connman_element_set_bool:
991 * @element: element structure
992 * @key: unique identifier
993 * @value: boolean value
995 * Set boolean value for specific key
997 int connman_element_set_bool(struct connman_element *element,
998 const char *key, connman_bool_t value)
1000 return set_static_property(element, key, DBUS_TYPE_BOOLEAN, &value);
1004 * connman_element_get_bool:
1005 * @element: element structure
1006 * @key: unique identifier
1008 * Get boolean value for specific key
1010 connman_bool_t connman_element_get_bool(struct connman_element *element,
1013 connman_bool_t value;
1015 if (get_static_property(element, key, &value) == FALSE)
1022 * connman_element_set_uint8:
1023 * @element: element structure
1024 * @key: unique identifier
1025 * @value: integer value
1027 * Set integer value for specific key
1029 int connman_element_set_uint8(struct connman_element *element,
1030 const char *key, connman_uint8_t value)
1032 return set_static_property(element, key, DBUS_TYPE_BYTE, &value);
1036 * connman_element_get_uint8:
1037 * @element: element structure
1038 * @key: unique identifier
1040 * Get integer value for specific key
1042 connman_uint8_t connman_element_get_uint8(struct connman_element *element,
1045 connman_uint8_t value;
1047 if (get_static_property(element, key, &value) == FALSE)
1054 * connman_element_set_blob:
1055 * @element: element structure
1056 * @key: unique identifier
1060 * Set binary blob value for specific key
1062 int connman_element_set_blob(struct connman_element *element,
1063 const char *key, const void *data, unsigned int size)
1065 return set_static_array_property(element, key,
1066 DBUS_TYPE_BYTE, &data, size);
1070 * connman_element_get_blob:
1071 * @element: element structure
1072 * @key: unique identifier
1073 * @size: pointer to blob size
1075 * Get binary blob value for specific key
1077 const void *connman_element_get_blob(struct connman_element *element,
1078 const char *key, unsigned int *size)
1082 if (get_static_array_property(element, key, &value, size) == FALSE)
1088 int __connman_element_append_ipv4(struct connman_element *element,
1089 DBusMessageIter *dict)
1091 const char *method = NULL;
1092 const char *address = NULL, *netmask = NULL, *gateway = NULL;
1093 const char *broadcast = NULL, *nameserver = NULL;
1095 connman_element_get_value(element,
1096 CONNMAN_PROPERTY_ID_IPV4_METHOD, &method);
1098 connman_element_get_value(element,
1099 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
1100 connman_element_get_value(element,
1101 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
1102 connman_element_get_value(element,
1103 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
1104 connman_element_get_value(element,
1105 CONNMAN_PROPERTY_ID_IPV4_BROADCAST, &broadcast);
1106 connman_element_get_value(element,
1107 CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
1110 connman_dbus_dict_append_variant(dict, "IPv4.Method",
1111 DBUS_TYPE_STRING, &method);
1113 if (address != NULL)
1114 connman_dbus_dict_append_variant(dict, "IPv4.Address",
1115 DBUS_TYPE_STRING, &address);
1117 if (netmask != NULL)
1118 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
1119 DBUS_TYPE_STRING, &netmask);
1121 if (gateway != NULL)
1122 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
1123 DBUS_TYPE_STRING, &gateway);
1125 if (broadcast != NULL)
1126 connman_dbus_dict_append_variant(dict, "IPv4.Broadcast",
1127 DBUS_TYPE_STRING, &broadcast);
1129 if (nameserver != NULL)
1130 connman_dbus_dict_append_variant(dict, "IPv4.Nameserver",
1131 DBUS_TYPE_STRING, &nameserver);
1136 int __connman_element_set_ipv4(struct connman_element *element,
1137 const char *name, DBusMessageIter *value)
1141 type = dbus_message_iter_get_arg_type(value);
1143 if (g_str_equal(name, "IPv4.Method") == TRUE) {
1144 enum connman_ipconfig_method method;
1147 if (type != DBUS_TYPE_STRING)
1150 dbus_message_iter_get_basic(value, &str);
1151 method = __connman_ipconfig_string2method(str);
1152 if (method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
1155 if (method == element->ipv4.method)
1158 element->ipv4.method = method;
1160 connman_element_update(element);
1161 } else if (g_str_equal(name, "IPv4.Address") == TRUE) {
1162 const char *address;
1164 if (type != DBUS_TYPE_STRING)
1167 dbus_message_iter_get_basic(value, &address);
1169 g_free(element->ipv4.address);
1170 element->ipv4.address = g_strdup(address);
1172 connman_element_update(element);
1173 } else if (g_str_equal(name, "IPv4.Netmask") == TRUE) {
1174 const char *netmask;
1176 if (type != DBUS_TYPE_STRING)
1179 dbus_message_iter_get_basic(value, &netmask);
1181 g_free(element->ipv4.netmask);
1182 element->ipv4.netmask = g_strdup(netmask);
1184 connman_element_update(element);
1185 } else if (g_str_equal(name, "IPv4.Gateway") == TRUE) {
1186 const char *gateway;
1188 if (type != DBUS_TYPE_STRING)
1191 dbus_message_iter_get_basic(value, &gateway);
1193 g_free(element->ipv4.gateway);
1194 element->ipv4.gateway = g_strdup(gateway);
1196 connman_element_update(element);
1197 } else if (g_str_equal(name, "IPv4.Broadcast") == TRUE) {
1198 const char *broadcast;
1200 if (type != DBUS_TYPE_STRING)
1203 dbus_message_iter_get_basic(value, &broadcast);
1205 g_free(element->ipv4.broadcast);
1206 element->ipv4.broadcast = g_strdup(broadcast);
1208 connman_element_update(element);
1209 } else if (g_str_equal(name, "IPv4.Nameserver") == TRUE) {
1210 const char *nameserver;
1212 if (type != DBUS_TYPE_STRING)
1215 dbus_message_iter_get_basic(value, &nameserver);
1217 g_free(element->ipv4.nameserver);
1218 element->ipv4.nameserver = g_strdup(nameserver);
1220 connman_element_update(element);
1226 static void append_state(DBusMessageIter *entry, const char *state)
1228 DBusMessageIter value;
1229 const char *key = "State";
1231 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1233 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1234 DBUS_TYPE_STRING_AS_STRING, &value);
1235 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1236 dbus_message_iter_close_container(entry, &value);
1239 static void emit_state_change(DBusConnection *conn, const char *state)
1241 DBusMessage *signal;
1242 DBusMessageIter entry;
1244 DBG("conn %p", conn);
1246 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1247 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1251 dbus_message_iter_init_append(signal, &entry);
1253 append_state(&entry, state);
1255 g_dbus_send_message(conn, signal);
1257 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1258 CONNMAN_MANAGER_INTERFACE, "StateChanged");
1262 dbus_message_iter_init_append(signal, &entry);
1263 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &state);
1265 g_dbus_send_message(conn, signal);
1268 static void probe_element(struct connman_element *element)
1272 DBG("element %p name %s", element, element->name);
1274 for (list = driver_list; list; list = list->next) {
1275 struct connman_driver *driver = list->data;
1277 if (match_driver(element, driver) == FALSE)
1280 DBG("driver %p name %s", driver, driver->name);
1282 if (driver->probe(element) == 0) {
1283 __connman_element_lock(element);
1284 element->driver = driver;
1285 __connman_element_unlock(element);
1291 static void register_element(gpointer data, gpointer user_data)
1293 struct connman_element *element = data;
1294 const gchar *basepath;
1297 __connman_element_lock(element);
1299 if (element->parent) {
1300 node = g_node_find(element_root, G_PRE_ORDER,
1301 G_TRAVERSE_ALL, element->parent);
1302 basepath = element->parent->path;
1304 element->parent = element_root->data;
1306 node = element_root;
1307 basepath = "/device";
1310 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1312 __connman_element_unlock(element);
1315 connman_error("Element registration for %s failed",
1320 DBG("element %p path %s", element, element->path);
1322 g_node_append_data(node, element);
1324 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP) {
1325 element->parent->configuring = TRUE;
1328 if (__connman_element_count(NULL,
1329 CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
1330 emit_state_change(connection, "connecting");
1334 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1335 struct connman_element *parent = element->parent;
1338 parent->configuring = FALSE;
1339 parent = parent->parent;
1342 if (__connman_element_count(NULL,
1343 CONNMAN_ELEMENT_TYPE_CONNECTION) == 1)
1344 emit_state_change(connection, "online");
1347 if (started == FALSE)
1350 probe_element(element);
1353 gboolean __connman_element_device_isfiltered(const char *devname)
1355 if (device_filter == NULL)
1358 if (g_pattern_match_simple(device_filter, devname) == FALSE) {
1359 DBG("ignoring device %s (match)", devname);
1364 if (nodevice_filter == NULL)
1367 if (g_pattern_match_simple(nodevice_filter, devname) == TRUE) {
1368 DBG("ignoring device %s (no match)", devname);
1376 * connman_element_register:
1377 * @element: the element to register
1378 * @parent: the parent to register the element with
1380 * Register an element with the core. It will be register under the given
1381 * parent of if %NULL is provided under the root element.
1383 * Returns: %0 on success
1385 int connman_element_register(struct connman_element *element,
1386 struct connman_element *parent)
1388 DBG("element %p name %s parent %p", element, element->name, parent);
1390 if (element->devname == NULL)
1391 element->devname = g_strdup(element->name);
1393 if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
1396 if (__connman_element_device_isfiltered(element->devname) == TRUE)
1400 if (connman_element_ref(element) == NULL)
1403 __connman_element_lock(element);
1405 if (element->name == NULL) {
1406 element->name = g_strdup(type2string(element->type));
1407 if (element->name == NULL) {
1408 __connman_element_unlock(element);
1413 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
1414 element->ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
1416 element->parent = parent;
1418 __connman_element_unlock(element);
1420 register_element(element, NULL);
1425 static gboolean remove_element(GNode *node, gpointer user_data)
1427 struct connman_element *element = node->data;
1428 struct connman_element *root = user_data;
1430 DBG("element %p name %s", element, element->name);
1432 if (element == root)
1436 g_node_unlink(node);
1438 if (element->driver) {
1439 if (element->driver->remove)
1440 element->driver->remove(element);
1442 __connman_element_lock(element);
1443 element->driver = NULL;
1444 __connman_element_unlock(element);
1448 g_node_destroy(node);
1450 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1451 if (__connman_element_count(NULL,
1452 CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
1453 emit_state_change(connection, "offline");
1456 connman_element_unref(element);
1461 void connman_element_unregister(struct connman_element *element)
1465 DBG("element %p name %s", element, element->name);
1467 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1470 g_node_traverse(node, G_POST_ORDER,
1471 G_TRAVERSE_ALL, -1, remove_element, NULL);
1474 void connman_element_unregister_children(struct connman_element *element)
1478 DBG("element %p name %s", element, element->name);
1480 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1483 g_node_traverse(node, G_POST_ORDER,
1484 G_TRAVERSE_ALL, -1, remove_element, element);
1487 static gboolean update_element(GNode *node, gpointer user_data)
1489 struct connman_element *element = node->data;
1491 DBG("element %p name %s", element, element->name);
1493 if (element->driver && element->driver->update)
1494 element->driver->update(element);
1499 void connman_element_update(struct connman_element *element)
1503 DBG("element %p name %s", element, element->name);
1505 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1508 g_node_traverse(node, G_PRE_ORDER,
1509 G_TRAVERSE_ALL, -1, update_element, element);
1512 int connman_element_set_enabled(struct connman_element *element,
1515 if (element->enabled == enabled)
1518 element->enabled = enabled;
1520 connman_element_update(element);
1525 static enum connman_service_error convert_error(enum connman_element_error error)
1528 case CONNMAN_ELEMENT_ERROR_UNKNOWN:
1529 case CONNMAN_ELEMENT_ERROR_FAILED:
1531 case CONNMAN_ELEMENT_ERROR_DHCP_FAILED:
1532 return CONNMAN_SERVICE_ERROR_DHCP_FAILED;
1533 case CONNMAN_ELEMENT_ERROR_CONNECT_FAILED:
1534 return CONNMAN_SERVICE_ERROR_CONNECT_FAILED;
1537 return CONNMAN_SERVICE_ERROR_UNKNOWN;
1541 * connman_element_set_error:
1542 * @element: element structure
1543 * @error: error identifier
1545 * Set error state and specific error identifier
1547 void connman_element_set_error(struct connman_element *element,
1548 enum connman_element_error error)
1550 struct connman_service *service;
1552 DBG("element %p error %d", element, error);
1554 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1557 element->state = CONNMAN_ELEMENT_STATE_ERROR;
1558 element->error = error;
1560 if (element->driver && element->driver->change)
1561 element->driver->change(element);
1563 service = __connman_element_get_service(element);
1564 __connman_service_indicate_error(service, convert_error(error));
1567 int __connman_element_init(const char *device, const char *nodevice)
1569 struct connman_element *element;
1573 connection = connman_dbus_get_connection();
1574 if (connection == NULL)
1577 device_filter = g_strdup(device);
1578 nodevice_filter = g_strdup(nodevice);
1580 element = connman_element_create("root");
1582 element->path = g_strdup("/");
1583 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1585 element_root = g_node_new(element);
1587 __connman_notifier_init();
1588 __connman_service_init();
1589 __connman_network_init();
1590 __connman_device_init();
1595 static gboolean probe_node(GNode *node, gpointer data)
1597 struct connman_element *element = node->data;
1599 DBG("element %p name %s", element, element->name);
1601 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1604 if (element->driver)
1607 probe_element(element);
1612 void __connman_element_start(void)
1616 __connman_storage_init_profile();
1618 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1623 __connman_rtnl_start();
1624 __connman_udev_start();
1626 __connman_connection_init();
1627 __connman_ipv4_init();
1629 if (__connman_rfkill_init() < 0)
1630 __connman_udev_enable_rfkill_processing();
1633 void __connman_element_stop(void)
1637 __connman_rfkill_cleanup();
1639 __connman_ipv4_cleanup();
1640 __connman_connection_cleanup();
1643 static gboolean free_driver(GNode *node, gpointer data)
1645 struct connman_element *element = node->data;
1647 DBG("element %p name %s", element, element->name);
1649 if (element->driver) {
1650 if (element->driver->remove)
1651 element->driver->remove(element);
1653 __connman_element_lock(element);
1654 element->driver = NULL;
1655 __connman_element_unlock(element);
1661 static gboolean free_node(GNode *node, gpointer data)
1663 struct connman_element *element = node->data;
1665 DBG("element %p name %s", element, element->name);
1667 if (g_node_depth(node) > 1)
1668 connman_element_unregister(element);
1673 void __connman_element_cleanup(void)
1677 __connman_device_cleanup();
1678 __connman_network_cleanup();
1679 __connman_service_cleanup();
1680 __connman_notifier_cleanup();
1682 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1685 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1688 g_node_destroy(element_root);
1689 element_root = NULL;
1691 g_free(nodevice_filter);
1692 g_free(device_filter);
1694 if (connection == NULL)
1697 dbus_connection_unref(connection);