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
33 static DBusConnection *connection = NULL;
35 struct connman_device {
36 struct connman_element element;
37 enum connman_device_type type;
38 enum connman_device_mode mode;
39 connman_bool_t secondary;
40 connman_bool_t offlinemode;
41 connman_bool_t blocked;
42 connman_bool_t powered;
43 connman_bool_t powered_persistent;
44 connman_bool_t carrier;
45 connman_bool_t scanning;
46 connman_bool_t disconnected;
47 connman_uint16_t scan_interval;
55 unsigned int connections;
57 struct connman_ipconfig *ipconfig;
59 struct connman_device_driver *driver;
62 connman_bool_t registered;
65 struct connman_network *network;
72 static gboolean device_scan_trigger(gpointer user_data)
74 struct connman_device *device = user_data;
76 DBG("device %p", device);
78 if (device->driver == NULL) {
79 device->scan_timeout = 0;
83 if (device->driver->scan)
84 device->driver->scan(device);
89 static void clear_scan_trigger(struct connman_device *device)
91 if (device->scan_timeout > 0) {
92 g_source_remove(device->scan_timeout);
93 device->scan_timeout = 0;
97 static void reset_scan_trigger(struct connman_device *device)
99 clear_scan_trigger(device);
101 if (device->scan_interval > 0) {
102 guint interval = device->scan_interval;
103 device->scan_timeout = g_timeout_add_seconds(interval,
104 device_scan_trigger, device);
108 static const char *type2description(enum connman_device_type type)
111 case CONNMAN_DEVICE_TYPE_UNKNOWN:
112 case CONNMAN_DEVICE_TYPE_VENDOR:
114 case CONNMAN_DEVICE_TYPE_ETHERNET:
116 case CONNMAN_DEVICE_TYPE_WIFI:
118 case CONNMAN_DEVICE_TYPE_WIMAX:
120 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
122 case CONNMAN_DEVICE_TYPE_GPS:
124 case CONNMAN_DEVICE_TYPE_MBM:
125 case CONNMAN_DEVICE_TYPE_HSO:
126 case CONNMAN_DEVICE_TYPE_NOZOMI:
127 case CONNMAN_DEVICE_TYPE_HUAWEI:
128 case CONNMAN_DEVICE_TYPE_NOVATEL:
135 static const char *type2string(enum connman_device_type type)
138 case CONNMAN_DEVICE_TYPE_UNKNOWN:
139 case CONNMAN_DEVICE_TYPE_VENDOR:
141 case CONNMAN_DEVICE_TYPE_ETHERNET:
143 case CONNMAN_DEVICE_TYPE_WIFI:
145 case CONNMAN_DEVICE_TYPE_WIMAX:
147 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
149 case CONNMAN_DEVICE_TYPE_GPS:
151 case CONNMAN_DEVICE_TYPE_MBM:
152 case CONNMAN_DEVICE_TYPE_HSO:
153 case CONNMAN_DEVICE_TYPE_HUAWEI:
154 case CONNMAN_DEVICE_TYPE_NOZOMI:
155 case CONNMAN_DEVICE_TYPE_NOVATEL:
162 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
164 enum connman_device_type type = connman_device_get_type(device);
167 case CONNMAN_DEVICE_TYPE_UNKNOWN:
168 case CONNMAN_DEVICE_TYPE_VENDOR:
169 case CONNMAN_DEVICE_TYPE_GPS:
170 case CONNMAN_DEVICE_TYPE_NOZOMI:
171 case CONNMAN_DEVICE_TYPE_HUAWEI:
172 case CONNMAN_DEVICE_TYPE_NOVATEL:
174 case CONNMAN_DEVICE_TYPE_ETHERNET:
175 return CONNMAN_SERVICE_TYPE_ETHERNET;
176 case CONNMAN_DEVICE_TYPE_WIFI:
177 return CONNMAN_SERVICE_TYPE_WIFI;
178 case CONNMAN_DEVICE_TYPE_WIMAX:
179 return CONNMAN_SERVICE_TYPE_WIMAX;
180 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
181 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
182 case CONNMAN_DEVICE_TYPE_MBM:
183 case CONNMAN_DEVICE_TYPE_HSO:
184 return CONNMAN_SERVICE_TYPE_CELLULAR;
187 return CONNMAN_SERVICE_TYPE_UNKNOWN;
190 static int set_connected(struct connman_device *device,
191 connman_bool_t connected)
193 if (connected == TRUE) {
194 enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
195 struct connman_element *element;
197 device->disconnected = TRUE;
199 switch (device->element.ipv4.method) {
200 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
201 case CONNMAN_IPCONFIG_METHOD_OFF:
203 case CONNMAN_IPCONFIG_METHOD_STATIC:
204 type = CONNMAN_ELEMENT_TYPE_IPV4;
206 case CONNMAN_IPCONFIG_METHOD_DHCP:
207 type = CONNMAN_ELEMENT_TYPE_DHCP;
211 element = connman_element_create(NULL);
212 if (element != NULL) {
213 struct connman_service *service;
215 element->type = type;
216 element->index = device->element.index;
218 if (connman_element_register(element,
219 &device->element) < 0)
220 connman_element_unref(element);
222 device->disconnected = FALSE;
224 service = __connman_service_lookup_from_device(device);
225 __connman_service_indicate_state(service,
226 CONNMAN_SERVICE_STATE_CONFIGURATION);
229 struct connman_service *service;
231 connman_element_unregister_children(&device->element);
233 device->disconnected = TRUE;
235 service = __connman_service_lookup_from_device(device);
236 __connman_service_indicate_state(service,
237 CONNMAN_SERVICE_STATE_IDLE);
240 if (connected == TRUE) {
241 enum connman_service_type type;
243 type = __connman_device_get_service_type(device);
244 __connman_notifier_connect(type);
246 enum connman_service_type type;
248 type = __connman_device_get_service_type(device);
249 __connman_notifier_disconnect(type);
255 static int set_carrier(struct connman_device *device, connman_bool_t carrier)
257 struct connman_service *service;
260 __connman_profile_add_device(device);
262 __connman_profile_remove_device(device);
264 service = __connman_service_lookup_from_device(device);
265 __connman_service_set_carrier(service, carrier);
267 return set_connected(device, carrier);
270 static int powered_changed(struct connman_device *device)
273 DBusMessageIter entry, value;
274 const char *key = "Powered";
276 signal = dbus_message_new_signal(device->element.path,
277 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
281 dbus_message_iter_init_append(signal, &entry);
283 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
285 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
286 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
287 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
289 dbus_message_iter_close_container(&entry, &value);
291 g_dbus_send_message(connection, signal);
296 static int set_powered(struct connman_device *device, connman_bool_t powered)
298 struct connman_device_driver *driver = device->driver;
299 enum connman_service_type type;
302 DBG("device %p powered %d", device, powered);
304 if (device->powered == powered)
310 type = __connman_device_get_service_type(device);
312 if (powered == TRUE) {
313 if (driver->enable) {
314 err = driver->enable(device);
316 __connman_notifier_enable(type);
320 clear_scan_trigger(device);
322 g_hash_table_remove_all(device->networks);
324 set_carrier(device, FALSE);
326 if (driver->disable) {
327 err = driver->disable(device);
329 __connman_notifier_disable(type);
335 device->powered = powered;
336 powered_changed(device);
342 static void append_path(gpointer key, gpointer value, gpointer user_data)
344 struct connman_element *element = value;
345 DBusMessageIter *iter = user_data;
347 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
351 static void append_networks(struct connman_device *device,
352 DBusMessageIter *entry)
354 DBusMessageIter value, iter;
355 const char *key = "Networks";
357 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
359 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
360 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
363 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
364 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
365 g_hash_table_foreach(device->networks, append_path, &iter);
366 dbus_message_iter_close_container(&value, &iter);
368 dbus_message_iter_close_container(entry, &value);
371 static DBusMessage *get_properties(DBusConnection *conn,
372 DBusMessage *msg, void *data)
374 struct connman_device *device = data;
376 DBusMessageIter array, dict, entry;
379 DBG("conn %p", conn);
381 if (__connman_security_check_privilege(msg,
382 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
383 return __connman_error_permission_denied(msg);
385 reply = dbus_message_new_method_return(msg);
389 dbus_message_iter_init_append(reply, &array);
391 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
392 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
393 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
394 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
396 if (device->name != NULL)
397 connman_dbus_dict_append_variant(&dict, "Name",
398 DBUS_TYPE_STRING, &device->name);
400 str = type2string(device->type);
402 connman_dbus_dict_append_variant(&dict, "Type",
403 DBUS_TYPE_STRING, &str);
405 if (device->address != NULL)
406 connman_dbus_dict_append_variant(&dict, "Address",
407 DBUS_TYPE_STRING, &device->address);
409 if (device->interface != NULL)
410 connman_dbus_dict_append_variant(&dict, "Interface",
411 DBUS_TYPE_STRING, &device->interface);
413 connman_dbus_dict_append_variant(&dict, "Powered",
414 DBUS_TYPE_BOOLEAN, &device->powered);
416 if (device->driver && device->driver->scan)
417 connman_dbus_dict_append_variant(&dict, "Scanning",
418 DBUS_TYPE_BOOLEAN, &device->scanning);
420 switch (device->mode) {
421 case CONNMAN_DEVICE_MODE_UNKNOWN:
423 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
424 __connman_element_append_ipv4(&device->element, &dict);
426 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
427 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
428 if (device->scan_interval > 0)
429 connman_dbus_dict_append_variant(&dict, "ScanInterval",
430 DBUS_TYPE_UINT16, &device->scan_interval);
432 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
434 append_networks(device, &entry);
435 dbus_message_iter_close_container(&dict, &entry);
439 dbus_message_iter_close_container(&array, &dict);
444 static gboolean powered_timeout(gpointer user_data)
446 struct connman_device *device = user_data;
448 DBG("device %p", device);
452 if (device->pending != NULL) {
455 reply = __connman_error_operation_timeout(device->pending);
457 g_dbus_send_message(connection, reply);
459 dbus_message_unref(device->pending);
460 device->pending = NULL;
466 static DBusMessage *set_property(DBusConnection *conn,
467 DBusMessage *msg, void *data)
469 struct connman_device *device = data;
470 DBusMessageIter iter, value;
474 DBG("conn %p", conn);
476 if (dbus_message_iter_init(msg, &iter) == FALSE)
477 return __connman_error_invalid_arguments(msg);
479 dbus_message_iter_get_basic(&iter, &name);
480 dbus_message_iter_next(&iter);
481 dbus_message_iter_recurse(&iter, &value);
483 if (__connman_security_check_privilege(msg,
484 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
485 return __connman_error_permission_denied(msg);
487 type = dbus_message_iter_get_arg_type(&value);
489 if (g_str_equal(name, "Powered") == TRUE) {
490 connman_bool_t powered;
493 if (type != DBUS_TYPE_BOOLEAN)
494 return __connman_error_invalid_arguments(msg);
496 dbus_message_iter_get_basic(&value, &powered);
498 device->powered_persistent = powered;
500 __connman_storage_save_device(device);
502 if (device->powered == powered)
503 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
505 if (device->pending != NULL)
506 return __connman_error_in_progress(msg);
508 err = set_powered(device, powered);
510 if (err != -EINPROGRESS)
511 return __connman_error_failed(msg, -err);
513 device->pending = dbus_message_ref(msg);
515 device->timeout = g_timeout_add_seconds(15,
516 powered_timeout, device);
520 } else if (g_str_equal(name, "ScanInterval") == TRUE) {
521 connman_uint16_t interval;
523 switch (device->mode) {
524 case CONNMAN_DEVICE_MODE_UNKNOWN:
525 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
526 return __connman_error_invalid_arguments(msg);
527 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
528 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
532 if (type != DBUS_TYPE_UINT16)
533 return __connman_error_invalid_arguments(msg);
535 dbus_message_iter_get_basic(&value, &interval);
537 if (device->scan_interval != interval) {
538 device->scan_interval = interval;
540 __connman_storage_save_device(device);
542 reset_scan_trigger(device);
544 } else if (g_str_has_prefix(name, "IPv4.") == TRUE) {
547 switch (device->mode) {
548 case CONNMAN_DEVICE_MODE_UNKNOWN:
549 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
550 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
551 return __connman_error_invalid_arguments(msg);
552 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
556 err = __connman_ipconfig_set_ipv4(device->ipconfig,
559 return __connman_error_failed(msg, -err);
561 return __connman_error_invalid_property(msg);
563 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
566 static DBusMessage *propose_scan(DBusConnection *conn,
567 DBusMessage *msg, void *data)
569 struct connman_device *device = data;
572 DBG("conn %p", conn);
574 switch (device->mode) {
575 case CONNMAN_DEVICE_MODE_UNKNOWN:
576 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
577 return __connman_error_not_supported(msg);
578 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
579 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
583 err = __connman_device_scan(device);
585 return __connman_error_failed(msg, -err);
587 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
590 static GDBusMethodTable device_methods[] = {
591 { "GetProperties", "", "a{sv}", get_properties },
592 { "SetProperty", "sv", "", set_property,
593 G_DBUS_METHOD_FLAG_ASYNC },
594 { "ProposeScan", "", "", propose_scan },
598 static GDBusSignalTable device_signals[] = {
599 { "PropertyChanged", "sv" },
603 static void append_devices(DBusMessageIter *entry)
605 DBusMessageIter value, iter;
606 const char *key = "Devices";
608 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
610 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
611 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
614 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
615 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
616 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
617 dbus_message_iter_close_container(&value, &iter);
619 dbus_message_iter_close_container(entry, &value);
622 static void emit_devices_signal(void)
625 DBusMessageIter entry;
627 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
628 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
632 dbus_message_iter_init_append(signal, &entry);
634 append_devices(&entry);
636 g_dbus_send_message(connection, signal);
639 static int register_interface(struct connman_element *element)
641 struct connman_device *device = element->device;
643 DBG("element %p name %s", element, element->name);
645 if (g_dbus_register_interface(connection, element->path,
646 CONNMAN_DEVICE_INTERFACE,
647 device_methods, device_signals,
648 NULL, device, NULL) == FALSE) {
649 connman_error("Failed to register %s device", element->path);
653 device->registered = TRUE;
655 emit_devices_signal();
660 static void unregister_interface(struct connman_element *element)
662 struct connman_device *device = element->device;
664 DBG("element %p name %s", element, element->name);
666 device->registered = FALSE;
668 emit_devices_signal();
670 g_dbus_unregister_interface(connection, element->path,
671 CONNMAN_DEVICE_INTERFACE);
674 static int setup_device(struct connman_device *device)
678 DBG("device %p", device);
680 err = register_interface(&device->element);
682 if (device->driver->remove)
683 device->driver->remove(device);
684 device->driver = NULL;
688 switch (device->mode) {
689 case CONNMAN_DEVICE_MODE_UNKNOWN:
690 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
691 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
693 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
694 if (device->carrier == TRUE && device->secondary == FALSE)
695 __connman_profile_add_device(device);
699 if (device->offlinemode == FALSE &&
700 device->powered_persistent == TRUE)
701 __connman_device_enable(device);
706 static void probe_driver(struct connman_element *element, gpointer user_data)
708 struct connman_device_driver *driver = user_data;
710 DBG("element %p name %s", element, element->name);
712 if (element->device == NULL)
715 if (element->device->driver != NULL)
718 if (driver->type != element->device->type)
721 if (driver->probe(element->device) < 0)
724 element->device->driver = driver;
726 setup_device(element->device);
729 static void remove_device(struct connman_device *device)
731 DBG("device %p", device);
733 __connman_device_disable(device);
735 switch (device->mode) {
736 case CONNMAN_DEVICE_MODE_UNKNOWN:
737 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
738 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
740 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
741 if (device->secondary == FALSE)
742 __connman_profile_remove_device(device);
746 unregister_interface(&device->element);
748 if (device->driver->remove)
749 device->driver->remove(device);
751 device->driver = NULL;
754 static void remove_driver(struct connman_element *element, gpointer user_data)
756 struct connman_device_driver *driver = user_data;
758 DBG("element %p name %s", element, element->name);
760 if (element->device == NULL)
763 if (element->device->driver == driver)
764 remove_device(element->device);
767 connman_bool_t __connman_device_has_driver(struct connman_device *device)
769 if (device == NULL || device->driver == NULL)
772 return device->registered;
775 static GSList *driver_list = NULL;
777 static gint compare_priority(gconstpointer a, gconstpointer b)
779 const struct connman_device_driver *driver1 = a;
780 const struct connman_device_driver *driver2 = b;
782 return driver2->priority - driver1->priority;
786 * connman_device_driver_register:
787 * @driver: device driver definition
789 * Register a new device driver
791 * Returns: %0 on success
793 int connman_device_driver_register(struct connman_device_driver *driver)
795 DBG("driver %p name %s", driver, driver->name);
797 driver_list = g_slist_insert_sorted(driver_list, driver,
800 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
801 probe_driver, driver);
807 * connman_device_driver_unregister:
808 * @driver: device driver definition
810 * Remove a previously registered device driver
812 void connman_device_driver_unregister(struct connman_device_driver *driver)
814 DBG("driver %p name %s", driver, driver->name);
816 driver_list = g_slist_remove(driver_list, driver);
818 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
819 remove_driver, driver);
822 static void unregister_network(gpointer data)
824 struct connman_network *network = data;
826 DBG("network %p", network);
828 connman_element_unregister((struct connman_element *) network);
830 connman_network_unref(network);
833 static void device_destruct(struct connman_element *element)
835 struct connman_device *device = element->device;
837 DBG("element %p name %s", element, element->name);
839 if (device->timeout > 0) {
840 g_source_remove(device->timeout);
844 if (device->pending != NULL) {
845 dbus_message_unref(device->pending);
846 device->pending = NULL;
849 g_free(device->ident);
850 g_free(device->node);
851 g_free(device->name);
852 g_free(device->address);
853 g_free(device->control);
854 g_free(device->interface);
856 connman_ipconfig_unref(device->ipconfig);
858 g_free(device->last_network);
860 g_hash_table_destroy(device->networks);
861 device->networks = NULL;
865 * connman_device_create:
866 * @node: device node name (for example an address)
869 * Allocate a new device of given #type and assign the #node name to it.
871 * Returns: a newly-allocated #connman_device structure
873 struct connman_device *connman_device_create(const char *node,
874 enum connman_device_type type)
876 struct connman_device *device;
879 DBG("node %s type %d", node, type);
881 device = g_try_new0(struct connman_device, 1);
885 DBG("device %p", device);
887 __connman_element_initialize(&device->element);
889 device->element.name = g_strdup(node);
890 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
892 device->element.device = device;
893 device->element.destruct = device_destruct;
895 str = type2string(type);
897 connman_element_set_string(&device->element,
898 CONNMAN_PROPERTY_ID_TYPE, str);
900 device->element.ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
903 device->name = g_strdup(type2description(device->type));
904 device->mode = CONNMAN_DEVICE_MODE_UNKNOWN;
905 device->secondary = FALSE;
907 device->powered_persistent = TRUE;
909 device->phyindex = -1;
912 case CONNMAN_DEVICE_TYPE_UNKNOWN:
913 case CONNMAN_DEVICE_TYPE_VENDOR:
914 device->scan_interval = 0;
916 case CONNMAN_DEVICE_TYPE_ETHERNET:
917 case CONNMAN_DEVICE_TYPE_WIFI:
918 device->scan_interval = 300;
920 case CONNMAN_DEVICE_TYPE_WIMAX:
921 device->scan_interval = 0;
923 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
924 device->scan_interval = 0;
926 case CONNMAN_DEVICE_TYPE_GPS:
927 device->scan_interval = 0;
929 case CONNMAN_DEVICE_TYPE_MBM:
930 case CONNMAN_DEVICE_TYPE_HSO:
931 case CONNMAN_DEVICE_TYPE_NOZOMI:
932 case CONNMAN_DEVICE_TYPE_HUAWEI:
933 case CONNMAN_DEVICE_TYPE_NOVATEL:
934 device->scan_interval = 0;
938 device->ipconfig = connman_ipconfig_create();
939 if (device->ipconfig == NULL) {
940 connman_device_unref(device);
944 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
945 g_free, unregister_network);
951 * connman_device_ref:
952 * @device: device structure
954 * Increase reference counter of device
956 struct connman_device *connman_device_ref(struct connman_device *device)
958 if (connman_element_ref(&device->element) == NULL)
965 * connman_device_unref:
966 * @device: device structure
968 * Decrease reference counter of device
970 void connman_device_unref(struct connman_device *device)
972 connman_element_unref(&device->element);
975 const char *__connman_device_get_type(struct connman_device *device)
977 return type2string(device->type);
981 * connman_device_get_type:
982 * @device: device structure
986 enum connman_device_type connman_device_get_type(struct connman_device *device)
992 * connman_device_get_name:
993 * @device: device structure
995 * Get unique name of device
997 const char *connman_device_get_name(struct connman_device *device)
999 return device->element.name;
1003 * connman_device_get_path:
1004 * @device: device structure
1006 * Get path name of device
1008 const char *connman_device_get_path(struct connman_device *device)
1010 return device->element.path;
1014 * connman_device_set_index:
1015 * @device: device structure
1016 * @index: index number
1018 * Set index number of device
1020 void connman_device_set_index(struct connman_device *device, int index)
1022 device->element.index = index;
1026 * connman_device_get_index:
1027 * @device: device structure
1029 * Get index number of device
1031 int connman_device_get_index(struct connman_device *device)
1033 return device->element.index;
1036 int __connman_device_get_phyindex(struct connman_device *device)
1038 return device->phyindex;
1041 void __connman_device_set_phyindex(struct connman_device *device,
1044 device->phyindex = phyindex;
1048 * connman_device_set_interface:
1049 * @device: device structure
1050 * @interface: interface name
1051 * @control: control interface
1053 * Set interface name of device
1055 void connman_device_set_interface(struct connman_device *device,
1056 const char *interface, const char *control)
1058 g_free(device->element.devname);
1059 device->element.devname = g_strdup(interface);
1061 g_free(device->interface);
1062 device->interface = g_strdup(interface);
1064 g_free(device->control);
1065 device->control = g_strdup(control);
1067 if (device->name == NULL) {
1068 const char *str = type2description(device->type);
1069 if (str != NULL && device->interface != NULL)
1070 device->name = g_strdup_printf("%s (%s)", str,
1075 const char *connman_device_get_control(struct connman_device *device)
1077 return device->control;
1081 * connman_device_set_ident:
1082 * @device: device structure
1083 * @ident: unique identifier
1085 * Set unique identifier of device
1087 void connman_device_set_ident(struct connman_device *device,
1090 g_free(device->ident);
1091 device->ident = g_strdup(ident);
1094 const char *__connman_device_get_ident(struct connman_device *device)
1096 return device->ident;
1100 * connman_device_set_mode:
1101 * @device: device structure
1102 * @mode: network mode
1104 * Change network mode of device
1106 void connman_device_set_mode(struct connman_device *device,
1107 enum connman_device_mode mode)
1109 device->mode = mode;
1113 * connman_device_get_mode:
1114 * @device: device structure
1116 * Get network mode of device
1118 enum connman_device_mode connman_device_get_mode(struct connman_device *device)
1120 return device->mode;
1124 * connman_device_set_secondary:
1125 * @device: device structure
1126 * @secondary: secondary value
1128 * Change secondary value of device
1130 void connman_device_set_secondary(struct connman_device *device,
1131 connman_bool_t secondary)
1133 device->secondary = secondary;
1137 * connman_device_get_secondary:
1138 * @device: device structure
1140 * Get secondary value of device
1142 connman_bool_t connman_device_get_secondary(struct connman_device *device)
1144 return device->secondary;
1148 * connman_device_set_powered:
1149 * @device: device structure
1150 * @powered: powered state
1152 * Change power state of device
1154 int connman_device_set_powered(struct connman_device *device,
1155 connman_bool_t powered)
1157 enum connman_service_type type;
1159 DBG("driver %p powered %d", device, powered);
1161 if (device->timeout > 0) {
1162 g_source_remove(device->timeout);
1163 device->timeout = 0;
1166 if (device->pending != NULL) {
1167 g_dbus_send_reply(connection, device->pending,
1170 dbus_message_unref(device->pending);
1171 device->pending = NULL;
1174 if (device->powered == powered)
1177 device->powered = powered;
1179 type = __connman_device_get_service_type(device);
1181 if (device->powered == TRUE)
1182 __connman_notifier_enable(type);
1184 __connman_notifier_disable(type);
1186 if (device->registered == FALSE)
1189 powered_changed(device);
1191 if (powered == FALSE)
1194 reset_scan_trigger(device);
1196 if (device->driver->scan)
1197 device->driver->scan(device);
1202 int __connman_device_set_blocked(struct connman_device *device,
1203 connman_bool_t blocked)
1205 connman_bool_t powered;
1207 DBG("device %p blocked %d", device, blocked);
1209 if (device->blocked == blocked)
1212 device->blocked = blocked;
1214 if (device->offlinemode == TRUE)
1217 if (blocked == FALSE)
1218 powered = device->powered_persistent;
1222 return set_powered(device, powered);
1226 * connman_device_set_carrier:
1227 * @device: device structure
1228 * @carrier: carrier state
1230 * Change carrier state of device (only for device without scanning)
1232 int connman_device_set_carrier(struct connman_device *device,
1233 connman_bool_t carrier)
1235 DBG("device %p carrier %d", device, carrier);
1237 switch (device->mode) {
1238 case CONNMAN_DEVICE_MODE_UNKNOWN:
1239 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1240 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1242 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1246 if (device->carrier == carrier)
1249 device->carrier = carrier;
1251 return set_carrier(device, device->carrier);
1254 int __connman_device_scan(struct connman_device *device)
1256 if (!device->driver || !device->driver->scan)
1259 if (device->powered == FALSE)
1262 return device->driver->scan(device);
1265 int __connman_device_enable(struct connman_device *device)
1267 enum connman_service_type type;
1270 DBG("device %p", device);
1272 if (!device->driver || !device->driver->enable)
1275 if (device->powered == TRUE)
1278 err = device->driver->enable(device);
1282 device->powered = TRUE;
1284 type = __connman_device_get_service_type(device);
1285 __connman_notifier_enable(type);
1290 int __connman_device_enable_persistent(struct connman_device *device)
1292 DBG("device %p", device);
1294 device->powered_persistent = TRUE;
1296 __connman_storage_save_device(device);
1298 return __connman_device_enable(device);
1301 int __connman_device_disable(struct connman_device *device)
1303 enum connman_service_type type;
1306 DBG("device %p", device);
1308 if (!device->driver || !device->driver->disable)
1311 if (device->powered == FALSE)
1314 clear_scan_trigger(device);
1316 g_hash_table_remove_all(device->networks);
1318 err = device->driver->disable(device);
1322 device->powered = FALSE;
1324 type = __connman_device_get_service_type(device);
1325 __connman_notifier_disable(type);
1330 int __connman_device_disable_persistent(struct connman_device *device)
1332 DBG("device %p", device);
1334 device->powered_persistent = FALSE;
1336 __connman_storage_save_device(device);
1338 return __connman_device_disable(device);
1341 int __connman_device_connect(struct connman_device *device)
1343 DBG("device %p", device);
1345 if (device->disconnected == FALSE)
1348 if (device->driver && device->driver->connect)
1349 device->driver->connect(device);
1354 int __connman_device_disconnect(struct connman_device *device)
1356 GHashTableIter iter;
1357 gpointer key, value;
1359 DBG("device %p", device);
1361 connman_device_set_disconnected(device, TRUE);
1363 g_hash_table_iter_init(&iter, device->networks);
1365 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1366 struct connman_network *network = value;
1368 __connman_network_disconnect(network);
1371 if (device->driver && device->driver->disconnect)
1372 device->driver->disconnect(device);
1377 static void mark_network_unavailable(gpointer key, gpointer value,
1380 struct connman_network *network = value;
1382 if (connman_network_get_connected(network) == TRUE)
1385 connman_network_set_available(network, FALSE);
1388 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1391 struct connman_network *network = value;
1393 if (connman_network_get_connected(network) == TRUE)
1396 if (connman_network_get_available(network) == TRUE)
1402 void __connman_device_cleanup_networks(struct connman_device *device)
1404 g_hash_table_foreach_remove(device->networks,
1405 remove_unavailable_network, NULL);
1409 * connman_device_set_scanning:
1410 * @device: device structure
1411 * @scanning: scanning state
1413 * Change scanning state of device
1415 int connman_device_set_scanning(struct connman_device *device,
1416 connman_bool_t scanning)
1418 DBusMessage *signal;
1419 DBusMessageIter entry, value;
1420 const char *key = "Scanning";
1422 DBG("device %p scanning %d", device, scanning);
1424 if (!device->driver || !device->driver->scan)
1427 if (device->scanning == scanning)
1430 device->scanning = scanning;
1432 signal = dbus_message_new_signal(device->element.path,
1433 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
1437 dbus_message_iter_init_append(signal, &entry);
1439 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1441 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
1442 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
1443 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &scanning);
1444 dbus_message_iter_close_container(&entry, &value);
1446 g_dbus_send_message(connection, signal);
1448 if (scanning == TRUE) {
1449 reset_scan_trigger(device);
1451 g_hash_table_foreach(device->networks,
1452 mark_network_unavailable, NULL);
1457 __connman_device_cleanup_networks(device);
1459 if (device->connections > 0)
1462 if (device->disconnected == TRUE)
1465 __connman_service_auto_connect();
1471 * connman_device_set_disconnected:
1472 * @device: device structure
1473 * @disconnected: disconnected state
1475 * Change disconnected state of device (only for device with networks)
1477 int connman_device_set_disconnected(struct connman_device *device,
1478 connman_bool_t disconnected)
1480 DBG("device %p disconnected %d", device, disconnected);
1482 switch (device->mode) {
1483 case CONNMAN_DEVICE_MODE_UNKNOWN:
1484 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1486 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1487 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1491 if (device->disconnected == disconnected)
1494 device->disconnected = disconnected;
1500 * connman_device_get_disconnected:
1501 * @device: device structure
1503 * Get device disconnected state
1505 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
1507 return device->disconnected;
1511 * connman_device_set_connected:
1512 * @device: device structure
1513 * @connected: connected state
1515 * Change connected state of device (for Ethernet like devices)
1517 int connman_device_set_connected(struct connman_device *device,
1518 connman_bool_t connected)
1520 DBG("device %p connected %d", device, connected);
1522 switch (device->mode) {
1523 case CONNMAN_DEVICE_MODE_UNKNOWN:
1524 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1525 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1527 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1531 if (device->carrier == FALSE)
1534 return set_connected(device, connected);
1538 * connman_device_set_string:
1539 * @device: device structure
1540 * @key: unique identifier
1541 * @value: string value
1543 * Set string value for specific key
1545 int connman_device_set_string(struct connman_device *device,
1546 const char *key, const char *value)
1548 DBG("device %p key %s value %s", device, key, value);
1550 if (g_str_equal(key, "Address") == TRUE) {
1551 g_free(device->address);
1552 device->address = g_strdup(value);
1553 } else if (g_str_equal(key, "Name") == TRUE) {
1554 g_free(device->name);
1555 device->name = g_strdup(value);
1556 } else if (g_str_equal(key, "Node") == TRUE) {
1557 g_free(device->node);
1558 device->node = g_strdup(value);
1561 return connman_element_set_string(&device->element, key, value);
1565 * connman_device_get_string:
1566 * @device: device structure
1567 * @key: unique identifier
1569 * Get string value for specific key
1571 const char *connman_device_get_string(struct connman_device *device,
1574 DBG("device %p key %s", device, key);
1576 if (g_str_equal(key, "Address") == TRUE)
1577 return device->address;
1578 else if (g_str_equal(key, "Name") == TRUE)
1579 return device->name;
1580 else if (g_str_equal(key, "Node") == TRUE)
1581 return device->node;
1583 return connman_element_get_string(&device->element, key);
1586 static void set_offlinemode(struct connman_element *element, gpointer user_data)
1588 struct connman_device *device = element->device;
1589 connman_bool_t offlinemode = GPOINTER_TO_UINT(user_data);
1590 connman_bool_t powered;
1592 DBG("element %p name %s", element, element->name);
1597 device->offlinemode = offlinemode;
1599 powered = (offlinemode == TRUE) ? FALSE : TRUE;
1601 if (device->powered == powered)
1604 if (device->powered_persistent == FALSE)
1607 set_powered(device, powered);
1610 int __connman_device_set_offlinemode(connman_bool_t offlinemode)
1612 DBG("offlinmode %d", offlinemode);
1614 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
1615 set_offlinemode, GUINT_TO_POINTER(offlinemode));
1617 __connman_notifier_offlinemode(offlinemode);
1622 void __connman_device_increase_connections(struct connman_device *device)
1624 enum connman_service_type type;
1626 device->connections++;
1628 type = __connman_device_get_service_type(device);
1629 __connman_notifier_connect(type);
1632 void __connman_device_decrease_connections(struct connman_device *device)
1634 enum connman_service_type type;
1636 device->connections--;
1638 type = __connman_device_get_service_type(device);
1639 __connman_notifier_disconnect(type);
1643 * connman_device_add_network:
1644 * @device: device structure
1645 * @network: network structure
1647 * Add new network to the device
1649 int connman_device_add_network(struct connman_device *device,
1650 struct connman_network *network)
1652 const char *identifier = connman_network_get_identifier(network);
1655 DBG("device %p network %p", device, network);
1657 switch (device->mode) {
1658 case CONNMAN_DEVICE_MODE_UNKNOWN:
1659 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1661 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1662 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1666 __connman_network_set_device(network, device);
1668 err = connman_element_register((struct connman_element *) network,
1671 __connman_network_set_device(network, NULL);
1675 g_hash_table_insert(device->networks, g_strdup(identifier),
1682 * connman_device_get_network:
1683 * @device: device structure
1684 * @identifier: network identifier
1686 * Get network for given identifier
1688 struct connman_network *connman_device_get_network(struct connman_device *device,
1689 const char *identifier)
1691 DBG("device %p identifier %s", device, identifier);
1693 return g_hash_table_lookup(device->networks, identifier);
1697 * connman_device_remove_network:
1698 * @device: device structure
1699 * @identifier: network identifier
1701 * Remove network for given identifier
1703 int connman_device_remove_network(struct connman_device *device,
1704 const char *identifier)
1706 DBG("device %p identifier %s", device, identifier);
1708 g_hash_table_remove(device->networks, identifier);
1713 void __connman_device_set_network(struct connman_device *device,
1714 struct connman_network *network)
1718 if (device->network == network)
1721 if (device->network != NULL)
1722 connman_network_unref(device->network);
1724 if (network != NULL) {
1725 name = connman_network_get_string(network,
1726 CONNMAN_PROPERTY_ID_NAME);
1727 g_free(device->last_network);
1728 device->last_network = g_strdup(name);
1730 device->network = connman_network_ref(network);
1732 g_free(device->last_network);
1733 device->last_network = NULL;
1735 device->network = NULL;
1740 * connman_device_register:
1741 * @device: device structure
1743 * Register device with the system
1745 int connman_device_register(struct connman_device *device)
1747 enum connman_service_type type;
1749 __connman_storage_load_device(device);
1751 device->offlinemode = __connman_manager_get_offlinemode();
1753 type = __connman_device_get_service_type(device);
1754 __connman_notifier_register(type);
1756 return connman_element_register(&device->element, NULL);
1760 * connman_device_unregister:
1761 * @device: device structure
1763 * Unregister device with the system
1765 void connman_device_unregister(struct connman_device *device)
1767 enum connman_service_type type;
1769 __connman_storage_save_device(device);
1771 type = __connman_device_get_service_type(device);
1772 __connman_notifier_unregister(type);
1774 connman_element_unregister(&device->element);
1778 * connman_device_get_data:
1779 * @device: device structure
1781 * Get private device data pointer
1783 void *connman_device_get_data(struct connman_device *device)
1785 return device->driver_data;
1789 * connman_device_set_data:
1790 * @device: device structure
1791 * @data: data pointer
1793 * Set private device data pointer
1795 void connman_device_set_data(struct connman_device *device, void *data)
1797 device->driver_data = data;
1800 static gboolean match_driver(struct connman_device *device,
1801 struct connman_device_driver *driver)
1803 if (device->type == driver->type ||
1804 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1810 static int device_probe(struct connman_element *element)
1812 struct connman_device *device = element->device;
1815 DBG("element %p name %s", element, element->name);
1820 if (device->driver != NULL)
1823 for (list = driver_list; list; list = list->next) {
1824 struct connman_device_driver *driver = list->data;
1826 if (match_driver(device, driver) == FALSE)
1829 DBG("driver %p name %s", driver, driver->name);
1831 if (driver->probe(device) == 0) {
1832 device->driver = driver;
1837 if (device->driver == NULL)
1840 return setup_device(device);
1843 static void device_remove(struct connman_element *element)
1845 struct connman_device *device = element->device;
1847 DBG("element %p name %s", element, element->name);
1852 if (device->driver == NULL)
1855 remove_device(device);
1858 static struct connman_driver device_driver = {
1860 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
1861 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
1862 .probe = device_probe,
1863 .remove = device_remove,
1866 static int device_load(struct connman_device *device)
1869 GError *error = NULL;
1871 connman_bool_t powered;
1874 DBG("device %p", device);
1876 keyfile = __connman_storage_open();
1877 if (keyfile == NULL)
1880 identifier = g_strdup_printf("device_%s", device->element.name);
1881 if (identifier == NULL)
1884 powered = g_key_file_get_boolean(keyfile, identifier,
1887 device->powered_persistent = powered;
1888 g_clear_error(&error);
1890 switch (device->mode) {
1891 case CONNMAN_DEVICE_MODE_UNKNOWN:
1892 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1894 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1895 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1896 val = g_key_file_get_integer(keyfile, identifier,
1897 "ScanInterval", &error);
1898 if (error == NULL && val > 0)
1899 device->scan_interval = val;
1900 g_clear_error(&error);
1907 __connman_storage_close(keyfile, FALSE);
1912 static int device_save(struct connman_device *device)
1917 DBG("device %p", device);
1919 keyfile = __connman_storage_open();
1920 if (keyfile == NULL)
1923 identifier = g_strdup_printf("device_%s", device->element.name);
1924 if (identifier == NULL)
1927 g_key_file_set_boolean(keyfile, identifier,
1928 "Powered", device->powered_persistent);
1930 switch (device->mode) {
1931 case CONNMAN_DEVICE_MODE_UNKNOWN:
1932 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1934 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1935 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1936 if (device->scan_interval > 0)
1937 g_key_file_set_integer(keyfile, identifier,
1938 "ScanInterval", device->scan_interval);
1945 __connman_storage_close(keyfile, TRUE);
1950 static struct connman_storage device_storage = {
1952 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
1953 .device_load = device_load,
1954 .device_save = device_save,
1957 int __connman_device_init(void)
1961 connection = connman_dbus_get_connection();
1963 if (connman_storage_register(&device_storage) < 0)
1964 connman_error("Failed to register device storage");
1966 return connman_driver_register(&device_driver);
1969 void __connman_device_cleanup(void)
1973 connman_driver_unregister(&device_driver);
1975 connman_storage_unregister(&device_storage);
1977 dbus_connection_unref(connection);