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;
44 enum connman_property_id id;
49 { CONNMAN_PROPERTY_ID_IPV4_METHOD,
50 DBUS_TYPE_STRING, "IPv4.Method", "dhcp" },
51 { CONNMAN_PROPERTY_ID_IPV4_ADDRESS,
52 DBUS_TYPE_STRING, "IPv4.Address" },
53 { CONNMAN_PROPERTY_ID_IPV4_NETMASK,
54 DBUS_TYPE_STRING, "IPv4.Netmask" },
55 { CONNMAN_PROPERTY_ID_IPV4_GATEWAY,
56 DBUS_TYPE_STRING, "IPv4.Gateway" },
57 { CONNMAN_PROPERTY_ID_IPV4_BROADCAST,
58 DBUS_TYPE_STRING, "IPv4.Broadcast" },
59 { CONNMAN_PROPERTY_ID_IPV4_NAMESERVER,
60 DBUS_TYPE_STRING, "IPv4.Nameserver" },
62 { CONNMAN_PROPERTY_ID_WIFI_SECURITY,
63 DBUS_TYPE_STRING, "WiFi.Security" },
64 { CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE,
65 DBUS_TYPE_STRING, "WiFi.Passphrase" },
70 static int propid2type(enum connman_property_id id)
74 for (i = 0; propid_table[i].name; i++) {
75 if (propid_table[i].id == id)
76 return propid_table[i].type;
79 return DBUS_TYPE_INVALID;
82 static const char *propid2name(enum connman_property_id id)
86 for (i = 0; propid_table[i].name; i++) {
87 if (propid_table[i].id == id)
88 return propid_table[i].name;
94 static const char *type2string(enum connman_element_type type)
97 case CONNMAN_ELEMENT_TYPE_UNKNOWN:
99 case CONNMAN_ELEMENT_TYPE_ROOT:
101 case CONNMAN_ELEMENT_TYPE_PROFILE:
103 case CONNMAN_ELEMENT_TYPE_DEVICE:
105 case CONNMAN_ELEMENT_TYPE_NETWORK:
107 case CONNMAN_ELEMENT_TYPE_SERVICE:
109 case CONNMAN_ELEMENT_TYPE_PPP:
111 case CONNMAN_ELEMENT_TYPE_IPV4:
113 case CONNMAN_ELEMENT_TYPE_IPV6:
115 case CONNMAN_ELEMENT_TYPE_DHCP:
117 case CONNMAN_ELEMENT_TYPE_BOOTP:
119 case CONNMAN_ELEMENT_TYPE_ZEROCONF:
121 case CONNMAN_ELEMENT_TYPE_CONNECTION:
123 case CONNMAN_ELEMENT_TYPE_VENDOR:
130 const char *__connman_ipv4_method2string(enum connman_ipv4_method method)
133 case CONNMAN_IPV4_METHOD_UNKNOWN:
135 case CONNMAN_IPV4_METHOD_OFF:
137 case CONNMAN_IPV4_METHOD_STATIC:
139 case CONNMAN_IPV4_METHOD_DHCP:
146 enum connman_ipv4_method __connman_ipv4_string2method(const char *method)
148 if (strcasecmp(method, "off") == 0)
149 return CONNMAN_IPV4_METHOD_OFF;
150 else if (strcasecmp(method, "static") == 0)
151 return CONNMAN_IPV4_METHOD_STATIC;
152 else if (strcasecmp(method, "dhcp") == 0)
153 return CONNMAN_IPV4_METHOD_DHCP;
155 return CONNMAN_IPV4_METHOD_UNKNOWN;
159 static void append_property(DBusMessageIter *dict,
160 struct connman_property *property)
162 if (property->value == NULL)
165 switch (property->type) {
166 case DBUS_TYPE_ARRAY:
167 connman_dbus_dict_append_array(dict, property->name,
168 property->subtype, &property->value, property->size);
170 case DBUS_TYPE_STRING:
171 connman_dbus_dict_append_variant(dict, property->name,
172 property->type, &property->value);
175 connman_dbus_dict_append_variant(dict, property->name,
176 property->type, property->value);
181 static void add_common_properties(struct connman_element *element,
182 DBusMessageIter *dict)
184 const char *address = NULL, *netmask = NULL, *gateway = NULL;
187 connman_element_get_value(element,
188 CONNMAN_PROPERTY_ID_IPV4_ADDRESS, &address);
189 connman_element_get_value(element,
190 CONNMAN_PROPERTY_ID_IPV4_NETMASK, &netmask);
191 connman_element_get_value(element,
192 CONNMAN_PROPERTY_ID_IPV4_GATEWAY, &gateway);
194 if (element->priority > 0)
195 connman_dbus_dict_append_variant(dict, "Priority",
196 DBUS_TYPE_UINT16, &element->priority);
199 connman_dbus_dict_append_variant(dict, "IPv4.Address",
200 DBUS_TYPE_STRING, &address);
202 connman_dbus_dict_append_variant(dict, "IPv4.Netmask",
203 DBUS_TYPE_STRING, &netmask);
205 connman_dbus_dict_append_variant(dict, "IPv4.Gateway",
206 DBUS_TYPE_STRING, &gateway);
208 if (element->wifi.security != NULL) {
209 const char *passphrase = "";
211 connman_dbus_dict_append_variant(dict, "WiFi.Security",
212 DBUS_TYPE_STRING, &element->wifi.security);
214 if (element->wifi.passphrase != NULL)
215 passphrase = element->wifi.passphrase;
217 connman_dbus_dict_append_variant(dict, "WiFi.Passphrase",
218 DBUS_TYPE_STRING, &passphrase);
221 __connman_element_lock(element);
223 for (list = element->properties; list; list = list->next) {
224 struct connman_property *property = list->data;
226 append_property(dict, property);
229 __connman_element_unlock(element);
232 static void set_common_property(struct connman_element *element,
233 const char *name, DBusMessageIter *value)
237 if (g_str_equal(name, "Priority") == TRUE) {
238 dbus_message_iter_get_basic(value, &element->priority);
242 __connman_element_lock(element);
244 for (list = element->properties; list; list = list->next) {
245 struct connman_property *property = list->data;
248 if (g_str_equal(property->name, name) == FALSE)
251 if (property->flags & CONNMAN_PROPERTY_FLAG_STATIC)
254 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
256 if (property->type == DBUS_TYPE_STRING) {
257 dbus_message_iter_get_basic(value, &str);
258 g_free(property->value);
259 property->value = g_strdup(str);
261 property->value = NULL;
264 __connman_element_unlock(element);
268 static void emit_element_signal(DBusConnection *conn, const char *member,
269 struct connman_element *element)
273 if (__connman_debug_enabled() == FALSE)
276 DBG("conn %p member %s", conn, member);
281 signal = dbus_message_new_signal(element->path,
282 CONNMAN_DEBUG_INTERFACE, member);
286 g_dbus_send_message(conn, signal);
289 struct foreach_data {
290 enum connman_element_type type;
291 element_cb_t callback;
295 static gboolean foreach_callback(GNode *node, gpointer user_data)
297 struct connman_element *element = node->data;
298 struct foreach_data *data = user_data;
300 DBG("element %p name %s", element, element->name);
302 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
305 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
306 data->type != element->type)
310 data->callback(element, data->user_data);
315 void __connman_element_foreach(struct connman_element *element,
316 enum connman_element_type type,
317 element_cb_t callback, gpointer user_data)
319 struct foreach_data data = { type, callback, user_data };
324 if (element != NULL) {
325 node = g_node_find(element_root, G_PRE_ORDER,
326 G_TRAVERSE_ALL, element);
332 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
333 foreach_callback, &data);
336 struct append_filter {
337 enum connman_element_type type;
338 DBusMessageIter *iter;
341 static gboolean append_path(GNode *node, gpointer user_data)
343 struct connman_element *element = node->data;
344 struct append_filter *filter = user_data;
346 DBG("element %p name %s", element, element->name);
348 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
351 if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
352 filter->type != element->type)
355 if (filter->type == CONNMAN_ELEMENT_TYPE_DEVICE &&
356 __connman_device_has_driver(element->device) == FALSE)
359 if (filter->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
360 __connman_network_has_driver(element->network) == FALSE)
363 dbus_message_iter_append_basic(filter->iter,
364 DBUS_TYPE_OBJECT_PATH, &element->path);
369 void __connman_element_list(struct connman_element *element,
370 enum connman_element_type type,
371 DBusMessageIter *iter)
373 struct append_filter filter = { type, iter };
378 if (element != NULL) {
379 node = g_node_find(element_root, G_PRE_ORDER,
380 G_TRAVERSE_ALL, element);
386 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
387 append_path, &filter);
391 enum connman_element_type type;
395 static gboolean count_element(GNode *node, gpointer user_data)
397 struct connman_element *element = node->data;
398 struct count_data *data = user_data;
400 DBG("element %p name %s", element, element->name);
402 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
405 if (data->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
406 data->type != element->type)
414 int __connman_element_count(struct connman_element *element,
415 enum connman_element_type type)
417 struct count_data data = { type, 0 };
422 if (element != NULL) {
423 node = g_node_find(element_root, G_PRE_ORDER,
424 G_TRAVERSE_ALL, element);
430 g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
431 count_element, &data);
436 static gint compare_priority(gconstpointer a, gconstpointer b)
438 const struct connman_driver *driver1 = a;
439 const struct connman_driver *driver2 = b;
441 return driver2->priority - driver1->priority;
444 static gboolean match_driver(struct connman_element *element,
445 struct connman_driver *driver)
447 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
450 if (element->type == driver->type ||
451 driver->type == CONNMAN_ELEMENT_TYPE_UNKNOWN)
457 static gboolean probe_driver(GNode *node, gpointer data)
459 struct connman_element *element = node->data;
460 struct connman_driver *driver = data;
462 DBG("element %p name %s", element, element->name);
464 if (!element->driver && match_driver(element, driver) == TRUE) {
465 if (driver->probe(element) < 0)
468 __connman_element_lock(element);
469 element->driver = driver;
470 __connman_element_unlock(element);
476 void __connman_driver_rescan(struct connman_driver *driver)
478 DBG("driver %p name %s", driver, driver->name);
483 if (element_root != NULL)
484 g_node_traverse(element_root, G_PRE_ORDER,
485 G_TRAVERSE_ALL, -1, probe_driver, driver);
489 * connman_driver_register:
490 * @driver: driver definition
492 * Register a new driver
494 * Returns: %0 on success
496 int connman_driver_register(struct connman_driver *driver)
498 DBG("driver %p name %s", driver, driver->name);
500 if (driver->type == CONNMAN_ELEMENT_TYPE_ROOT)
506 driver_list = g_slist_insert_sorted(driver_list, driver,
509 if (started == FALSE)
512 if (element_root != NULL)
513 g_node_traverse(element_root, G_PRE_ORDER,
514 G_TRAVERSE_ALL, -1, probe_driver, driver);
519 static gboolean remove_driver(GNode *node, gpointer data)
521 struct connman_element *element = node->data;
522 struct connman_driver *driver = data;
524 DBG("element %p name %s", element, element->name);
526 if (element->driver == driver) {
528 driver->remove(element);
530 __connman_element_lock(element);
531 element->driver = NULL;
532 __connman_element_unlock(element);
539 * connman_driver_unregister:
540 * @driver: driver definition
542 * Remove a previously registered driver
544 void connman_driver_unregister(struct connman_driver *driver)
546 DBG("driver %p name %s", driver, driver->name);
548 driver_list = g_slist_remove(driver_list, driver);
550 if (element_root != NULL)
551 g_node_traverse(element_root, G_POST_ORDER,
552 G_TRAVERSE_ALL, -1, remove_driver, driver);
556 * connman_element_create:
557 * @name: element name
559 * Allocate a new element and assign the given #name to it. If the name
560 * is #NULL, it will be later on created based on the element type.
562 * Returns: a newly-allocated #connman_element structure
564 struct connman_element *connman_element_create(const char *name)
566 struct connman_element *element;
568 element = g_try_new0(struct connman_element, 1);
572 DBG("element %p", element);
574 element->refcount = 1;
576 element->name = g_strdup(name);
577 element->type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
579 element->enabled = FALSE;
584 struct connman_element *connman_element_ref(struct connman_element *element)
586 DBG("element %p name %s refcount %d", element, element->name,
587 g_atomic_int_get(&element->refcount) + 1);
589 g_atomic_int_inc(&element->refcount);
594 static void free_properties(struct connman_element *element)
598 DBG("element %p name %s", element, element->name);
600 __connman_element_lock(element);
602 for (list = element->properties; list; list = list->next) {
603 struct connman_property *property = list->data;
605 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
606 g_free(property->value);
608 g_free(property->name);
612 g_slist_free(element->properties);
614 element->properties = NULL;
616 __connman_element_unlock(element);
619 void connman_element_unref(struct connman_element *element)
621 DBG("element %p name %s refcount %d", element, element->name,
622 g_atomic_int_get(&element->refcount) - 1);
624 if (g_atomic_int_dec_and_test(&element->refcount) == TRUE) {
625 if (element->destruct)
626 element->destruct(element);
627 free_properties(element);
628 g_free(element->ipv4.address);
629 g_free(element->ipv4.netmask);
630 g_free(element->ipv4.gateway);
631 g_free(element->ipv4.network);
632 g_free(element->ipv4.broadcast);
633 g_free(element->ipv4.nameserver);
634 g_free(element->devname);
635 g_free(element->devpath);
636 g_free(element->path);
637 g_free(element->name);
642 int connman_element_add_static_property(struct connman_element *element,
643 const char *name, int type, const void *value)
645 struct connman_property *property;
647 DBG("element %p name %s", element, element->name);
649 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
652 property = g_try_new0(struct connman_property, 1);
653 if (property == NULL)
656 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
657 property->id = CONNMAN_PROPERTY_ID_INVALID;
658 property->name = g_strdup(name);
659 property->type = type;
661 DBG("name %s type %d value %p", name, type, value);
664 case DBUS_TYPE_STRING:
665 property->value = g_strdup(*((const char **) value));
668 property->value = g_try_malloc(1);
669 if (property->value != NULL)
670 memcpy(property->value, value, 1);
674 __connman_element_lock(element);
675 element->properties = g_slist_append(element->properties, property);
676 __connman_element_unlock(element);
681 int connman_element_set_static_property(struct connman_element *element,
682 const char *name, int type, const void *value)
686 DBG("element %p name %s", element, element->name);
688 if (type != DBUS_TYPE_STRING && type != DBUS_TYPE_BYTE)
691 __connman_element_lock(element);
693 for (list = element->properties; list; list = list->next) {
694 struct connman_property *property = list->data;
696 if (g_str_equal(property->name, name) == FALSE)
699 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
702 property->type = type;
703 g_free(property->value);
706 case DBUS_TYPE_STRING:
707 property->value = g_strdup(*((const char **) value));
710 property->value = g_try_malloc(1);
711 if (property->value != NULL)
712 memcpy(property->value, value, 1);
717 __connman_element_unlock(element);
722 int connman_element_add_static_array_property(struct connman_element *element,
723 const char *name, int type, const void *value, int len)
725 struct connman_property *property;
727 DBG("element %p name %s", element, element->name);
729 if (type != DBUS_TYPE_BYTE)
732 property = g_try_new0(struct connman_property, 1);
733 if (property == NULL)
736 property->flags = CONNMAN_PROPERTY_FLAG_STATIC;
737 property->id = CONNMAN_PROPERTY_ID_INVALID;
738 property->name = g_strdup(name);
739 property->type = DBUS_TYPE_ARRAY;
740 property->subtype = type;
742 DBG("name %s type %d value %p", name, type, value);
746 property->value = g_try_malloc(len);
747 if (property->value != NULL) {
748 memcpy(property->value,
749 *((const unsigned char **) value), len);
750 property->size = len;
755 __connman_element_lock(element);
756 element->properties = g_slist_append(element->properties, property);
757 __connman_element_unlock(element);
762 static void *get_reference_value(struct connman_element *element,
763 enum connman_property_id id)
767 DBG("element %p name %s", element, element->name);
769 for (list = element->properties; list; list = list->next) {
770 struct connman_property *property = list->data;
772 if (property->id != id)
775 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
776 return property->value;
779 if (element->parent == NULL)
782 return get_reference_value(element->parent, id);
785 static void set_reference_properties(struct connman_element *element)
789 DBG("element %p name %s", element, element->name);
791 for (list = element->properties; list; list = list->next) {
792 struct connman_property *property = list->data;
794 if (!(property->flags & CONNMAN_PROPERTY_FLAG_REFERENCE))
797 property->value = get_reference_value(element->parent,
802 static struct connman_property *create_property(struct connman_element *element,
803 enum connman_property_id id)
805 struct connman_property *property;
808 DBG("element %p name %s", element, element->name);
810 __connman_element_lock(element);
812 for (list = element->properties; list; list = list->next) {
813 property = list->data;
815 if (property->id == id)
819 property = g_try_new0(struct connman_property, 1);
820 if (property == NULL)
823 property->flags = CONNMAN_PROPERTY_FLAG_REFERENCE;
825 property->name = g_strdup(propid2name(id));
826 property->type = propid2type(id);
828 if (property->name == NULL) {
834 element->properties = g_slist_append(element->properties, property);
837 __connman_element_unlock(element);
842 static void create_default_properties(struct connman_element *element)
844 struct connman_property *property;
847 DBG("element %p name %s", element, element->name);
849 for (i = 0; propid_table[i].name; i++) {
850 DBG("property %s", propid_table[i].name);
852 property = create_property(element, propid_table[i].id);
854 property->flags &= ~CONNMAN_PROPERTY_FLAG_REFERENCE;
856 if (propid_table[i].type != DBUS_TYPE_STRING)
859 if (propid_table[i].value)
860 property->value = g_strdup(propid_table[i].value);
862 property->value = g_strdup("");
866 static int define_properties_valist(struct connman_element *element,
869 enum connman_property_id id;
871 DBG("element %p name %s", element, element->name);
873 id = va_arg(args, enum connman_property_id);
875 while (id != CONNMAN_PROPERTY_ID_INVALID) {
877 DBG("property %d", id);
879 create_property(element, id);
881 id = va_arg(args, enum connman_property_id);
888 * connman_element_define_properties:
889 * @element: an element
890 * @varargs: list of property identifiers
892 * Define the valid properties for an element.
894 * Returns: %0 on success
896 int connman_element_define_properties(struct connman_element *element, ...)
901 DBG("element %p name %s", element, element->name);
903 va_start(args, element);
905 err = define_properties_valist(element, args);
912 int connman_element_create_property(struct connman_element *element,
913 const char *name, int type)
918 int connman_element_set_property(struct connman_element *element,
919 enum connman_property_id id, const void *value)
922 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
923 __connman_element_lock(element);
924 g_free(element->ipv4.address);
925 element->ipv4.address = g_strdup(*((const char **) value));
926 __connman_element_unlock(element);
928 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
929 __connman_element_lock(element);
930 g_free(element->ipv4.netmask);
931 element->ipv4.netmask = g_strdup(*((const char **) value));
932 __connman_element_unlock(element);
934 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
935 __connman_element_lock(element);
936 g_free(element->ipv4.gateway);
937 element->ipv4.gateway = g_strdup(*((const char **) value));
938 __connman_element_unlock(element);
940 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
941 __connman_element_lock(element);
942 g_free(element->ipv4.broadcast);
943 element->ipv4.broadcast = g_strdup(*((const char **) value));
944 __connman_element_unlock(element);
946 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
947 __connman_element_lock(element);
948 g_free(element->ipv4.nameserver);
949 element->ipv4.nameserver = g_strdup(*((const char **) value));
950 __connman_element_unlock(element);
952 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
953 __connman_element_lock(element);
954 g_free(element->wifi.security);
955 element->wifi.security = g_strdup(*((const char **) value));
956 __connman_element_unlock(element);
958 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
959 __connman_element_lock(element);
960 g_free(element->wifi.passphrase);
961 element->wifi.passphrase = g_strdup(*((const char **) value));
962 __connman_element_unlock(element);
971 int connman_element_get_value(struct connman_element *element,
972 enum connman_property_id id, void *value)
974 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
978 case CONNMAN_PROPERTY_ID_IPV4_METHOD:
979 if (element->ipv4.method == CONNMAN_IPV4_METHOD_UNKNOWN)
980 return connman_element_get_value(element->parent,
982 __connman_element_lock(element);
983 *((const char **) value) = __connman_ipv4_method2string(element->ipv4.method);
984 __connman_element_unlock(element);
986 case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
987 if (element->ipv4.address == NULL)
988 return connman_element_get_value(element->parent,
990 __connman_element_lock(element);
991 *((char **) value) = element->ipv4.address;
992 __connman_element_unlock(element);
994 case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
995 if (element->ipv4.netmask == NULL)
996 return connman_element_get_value(element->parent,
998 __connman_element_lock(element);
999 *((char **) value) = element->ipv4.netmask;
1000 __connman_element_unlock(element);
1002 case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
1003 if (element->ipv4.gateway == NULL)
1004 return connman_element_get_value(element->parent,
1006 __connman_element_lock(element);
1007 *((char **) value) = element->ipv4.gateway;
1008 __connman_element_unlock(element);
1010 case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
1011 if (element->ipv4.broadcast == NULL)
1012 return connman_element_get_value(element->parent,
1014 __connman_element_lock(element);
1015 *((char **) value) = element->ipv4.broadcast;
1016 __connman_element_unlock(element);
1018 case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
1019 if (element->ipv4.nameserver == NULL)
1020 return connman_element_get_value(element->parent,
1022 __connman_element_lock(element);
1023 *((char **) value) = element->ipv4.nameserver;
1024 __connman_element_unlock(element);
1026 case CONNMAN_PROPERTY_ID_WIFI_SECURITY:
1027 if (element->wifi.security == NULL)
1028 return connman_element_get_value(element->parent,
1030 __connman_element_lock(element);
1031 *((char **) value) = element->wifi.security;
1032 __connman_element_unlock(element);
1034 case CONNMAN_PROPERTY_ID_WIFI_PASSPHRASE:
1035 if (element->wifi.passphrase == NULL)
1036 return connman_element_get_value(element->parent,
1038 __connman_element_lock(element);
1039 *((char **) value) = element->wifi.passphrase;
1040 __connman_element_unlock(element);
1049 gboolean connman_element_get_static_property(struct connman_element *element,
1050 const char *name, void *value)
1053 gboolean found = FALSE;
1055 DBG("element %p name %s", element, element->name);
1057 __connman_element_lock(element);
1059 for (list = element->properties; list; list = list->next) {
1060 struct connman_property *property = list->data;
1062 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1065 if (g_str_equal(property->name, name) == TRUE) {
1066 switch (property->type) {
1067 case DBUS_TYPE_STRING:
1068 *((char **) value) = property->value;
1076 __connman_element_unlock(element);
1081 gboolean connman_element_get_static_array_property(struct connman_element *element,
1082 const char *name, void *value, int *len)
1085 gboolean found = FALSE;
1087 DBG("element %p name %s", element, element->name);
1089 __connman_element_lock(element);
1091 for (list = element->properties; list; list = list->next) {
1092 struct connman_property *property = list->data;
1094 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1097 if (g_str_equal(property->name, name) == TRUE) {
1098 *((char **) value) = property->value;
1099 *len = property->size;
1105 __connman_element_unlock(element);
1110 gboolean connman_element_match_static_property(struct connman_element *element,
1111 const char *name, const void *value)
1114 gboolean result = FALSE;
1116 DBG("element %p name %s", element, element->name);
1118 __connman_element_lock(element);
1120 for (list = element->properties; list; list = list->next) {
1121 struct connman_property *property = list->data;
1123 if (!(property->flags & CONNMAN_PROPERTY_FLAG_STATIC))
1126 if (g_str_equal(property->name, name) == FALSE)
1129 if (property->type == DBUS_TYPE_STRING)
1130 result = g_str_equal(property->value,
1131 *((const char **) value));
1137 __connman_element_unlock(element);
1142 static void append_connections(DBusMessageIter *entry)
1144 DBusMessageIter value, iter;
1145 const char *key = "Connections";
1147 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1149 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1150 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
1153 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
1154 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
1155 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
1156 dbus_message_iter_close_container(&value, &iter);
1158 dbus_message_iter_close_container(entry, &value);
1161 static void emit_connections_signal(DBusConnection *conn)
1163 DBusMessage *signal;
1164 DBusMessageIter entry;
1166 DBG("conn %p", conn);
1168 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1169 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1173 dbus_message_iter_init_append(signal, &entry);
1175 append_connections(&entry);
1177 g_dbus_send_message(conn, signal);
1180 static void append_state(DBusMessageIter *entry, const char *state)
1182 DBusMessageIter value;
1183 const char *key = "State";
1185 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
1187 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
1188 DBUS_TYPE_STRING_AS_STRING, &value);
1189 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &state);
1190 dbus_message_iter_close_container(entry, &value);
1193 static void emit_state_change(DBusConnection *conn, const char *state)
1195 DBusMessage *signal;
1196 DBusMessageIter entry;
1198 DBG("conn %p", conn);
1200 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1201 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
1205 dbus_message_iter_init_append(signal, &entry);
1207 append_state(&entry, state);
1209 g_dbus_send_message(conn, signal);
1212 static void set_signal_strength(struct connman_element *connection)
1214 struct connman_element *element = connection;
1216 while (element != NULL) {
1217 if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1218 connection->strength = element->strength;
1222 element = element->parent;
1226 static void probe_element(struct connman_element *element)
1230 DBG("element %p name %s", element, element->name);
1232 for (list = driver_list; list; list = list->next) {
1233 struct connman_driver *driver = list->data;
1235 if (match_driver(element, driver) == FALSE)
1238 DBG("driver %p name %s", driver, driver->name);
1240 if (driver->probe(element) == 0) {
1241 __connman_element_lock(element);
1242 element->driver = driver;
1243 __connman_element_unlock(element);
1249 static void register_element(gpointer data, gpointer user_data)
1251 struct connman_element *element = data;
1252 const gchar *basepath;
1255 __connman_element_lock(element);
1257 if (element->parent) {
1258 node = g_node_find(element_root, G_PRE_ORDER,
1259 G_TRAVERSE_ALL, element->parent);
1260 basepath = element->parent->path;
1262 element->parent = element_root->data;
1264 node = element_root;
1268 element->path = g_strdup_printf("%s/%s", basepath, element->name);
1270 set_reference_properties(element);
1272 __connman_element_unlock(element);
1274 DBG("element %p path %s", element, element->path);
1276 g_node_append_data(node, element);
1278 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1279 set_signal_strength(element);
1280 emit_connections_signal(connection);
1281 emit_state_change(connection, "online");
1284 emit_element_signal(connection, "ElementAdded", element);
1286 if (started == FALSE)
1289 probe_element(element);
1293 * connman_element_register:
1294 * @element: the element to register
1295 * @parent: the parent to register the element with
1297 * Register an element with the core. It will be register under the given
1298 * parent of if %NULL is provided under the root element.
1300 * Returns: %0 on success
1302 int connman_element_register(struct connman_element *element,
1303 struct connman_element *parent)
1305 DBG("element %p name %s parent %p", element, element->name, parent);
1307 if (element->devname == NULL)
1308 element->devname = g_strdup(element->name);
1310 if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
1311 if (g_pattern_match_simple(device_filter,
1312 element->devname) == FALSE) {
1313 DBG("ignoring %s [%s] device", element->name,
1319 if (connman_element_ref(element) == NULL)
1322 __connman_element_lock(element);
1324 if (element->name == NULL) {
1325 element->name = g_strdup(type2string(element->type));
1326 if (element->name == NULL) {
1327 __connman_element_unlock(element);
1332 if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
1333 element->ipv4.method = CONNMAN_IPV4_METHOD_DHCP;
1335 element->parent = parent;
1337 __connman_element_unlock(element);
1339 register_element(element, NULL);
1344 static gboolean remove_element(GNode *node, gpointer user_data)
1346 struct connman_element *element = node->data;
1347 struct connman_element *root = user_data;
1349 DBG("element %p name %s", element, element->name);
1351 if (element == root)
1355 g_node_unlink(node);
1357 if (element->driver) {
1358 if (element->driver->remove)
1359 element->driver->remove(element);
1361 __connman_element_lock(element);
1362 element->driver = NULL;
1363 __connman_element_unlock(element);
1367 g_node_destroy(node);
1369 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION) {
1370 if (__connman_element_count(NULL,
1371 CONNMAN_ELEMENT_TYPE_CONNECTION) == 0)
1372 emit_state_change(connection, "offline");
1373 emit_connections_signal(connection);
1376 emit_element_signal(connection, "ElementRemoved", element);
1378 connman_element_unref(element);
1383 void connman_element_unregister(struct connman_element *element)
1387 DBG("element %p name %s", element, element->name);
1389 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1392 g_node_traverse(node, G_POST_ORDER,
1393 G_TRAVERSE_ALL, -1, remove_element, NULL);
1396 void connman_element_unregister_children(struct connman_element *element)
1400 DBG("element %p name %s", element, element->name);
1402 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1405 g_node_traverse(node, G_POST_ORDER,
1406 G_TRAVERSE_ALL, -1, remove_element, element);
1409 static gboolean update_element(GNode *node, gpointer user_data)
1411 struct connman_element *element = node->data;
1412 struct connman_element *root = user_data;
1414 DBG("element %p name %s", element, element->name);
1416 if (element->driver && element->driver->update)
1417 element->driver->update(element);
1419 if (element->type == CONNMAN_ELEMENT_TYPE_CONNECTION &&
1420 root->type == CONNMAN_ELEMENT_TYPE_NETWORK) {
1421 if (element->strength != root->strength)
1422 element->strength = root->strength;
1425 emit_element_signal(connection, "ElementUpdated", element);
1430 void connman_element_update(struct connman_element *element)
1434 DBG("element %p name %s", element, element->name);
1436 node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
1439 g_node_traverse(node, G_PRE_ORDER,
1440 G_TRAVERSE_ALL, -1, update_element, element);
1443 int connman_element_set_enabled(struct connman_element *element,
1446 if (element->enabled == enabled)
1449 element->enabled = enabled;
1454 int __connman_element_init(DBusConnection *conn, const char *device)
1456 struct connman_element *element;
1458 DBG("conn %p", conn);
1460 connection = dbus_connection_ref(conn);
1461 if (connection == NULL)
1464 device_filter = g_strdup(device);
1466 element = connman_element_create("root");
1468 element->path = g_strdup("/");
1469 element->type = CONNMAN_ELEMENT_TYPE_ROOT;
1471 create_default_properties(element);
1473 element_root = g_node_new(element);
1475 __connman_network_init();
1476 __connman_device_init();
1481 static gboolean probe_node(GNode *node, gpointer data)
1483 struct connman_element *element = node->data;
1485 DBG("element %p name %s", element, element->name);
1487 if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
1490 if (element->driver)
1493 probe_element(element);
1498 void __connman_element_start(void)
1502 g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
1507 __connman_connection_init();
1508 __connman_ipv4_init();
1509 __connman_detect_init();
1512 void __connman_element_stop(void)
1516 __connman_detect_cleanup();
1517 __connman_ipv4_cleanup();
1518 __connman_connection_cleanup();
1521 static gboolean free_driver(GNode *node, gpointer data)
1523 struct connman_element *element = node->data;
1525 DBG("element %p name %s", element, element->name);
1527 if (element->driver) {
1528 if (element->driver->remove)
1529 element->driver->remove(element);
1531 __connman_element_lock(element);
1532 element->driver = NULL;
1533 __connman_element_unlock(element);
1539 static gboolean free_node(GNode *node, gpointer data)
1541 struct connman_element *element = node->data;
1543 DBG("element %p name %s", element, element->name);
1545 if (g_node_depth(node) > 1)
1546 connman_element_unregister(element);
1551 void __connman_element_cleanup(void)
1555 __connman_device_cleanup();
1556 __connman_network_cleanup();
1558 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1561 g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
1564 g_node_destroy(element_root);
1565 element_root = NULL;
1567 g_free(device_filter);
1569 dbus_connection_unref(connection);