5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 static DBusConnection *connection = NULL;
35 struct connman_device {
36 struct connman_element element;
37 enum connman_device_type type;
38 connman_bool_t offlinemode;
39 connman_bool_t blocked;
40 connman_bool_t powered;
41 connman_bool_t powered_pending;
42 connman_bool_t powered_persistent;
43 connman_bool_t scanning;
44 connman_bool_t disconnected;
45 connman_bool_t reconnect;
46 connman_uint16_t scan_interval;
54 unsigned int connections;
57 struct connman_device_driver *driver;
60 connman_bool_t registered;
63 struct connman_network *network;
70 static gboolean device_scan_trigger(gpointer user_data)
72 struct connman_device *device = user_data;
74 DBG("device %p", device);
76 if (device->driver == NULL) {
77 device->scan_timeout = 0;
81 if (device->driver->scan)
82 device->driver->scan(device);
87 static void clear_scan_trigger(struct connman_device *device)
89 if (device->scan_timeout > 0) {
90 g_source_remove(device->scan_timeout);
91 device->scan_timeout = 0;
95 static void reset_scan_trigger(struct connman_device *device)
97 clear_scan_trigger(device);
99 if (device->scan_interval > 0) {
100 guint interval = device->scan_interval;
101 device->scan_timeout = g_timeout_add_seconds(interval,
102 device_scan_trigger, device);
106 static void force_scan_trigger(struct connman_device *device)
108 clear_scan_trigger(device);
110 device->scan_timeout = g_timeout_add_seconds(5,
111 device_scan_trigger, device);
114 void connman_device_schedule_scan(struct connman_device *device)
116 reset_scan_trigger(device);
119 static const char *type2description(enum connman_device_type type)
122 case CONNMAN_DEVICE_TYPE_UNKNOWN:
123 case CONNMAN_DEVICE_TYPE_VENDOR:
125 case CONNMAN_DEVICE_TYPE_ETHERNET:
127 case CONNMAN_DEVICE_TYPE_WIFI:
129 case CONNMAN_DEVICE_TYPE_WIMAX:
131 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
133 case CONNMAN_DEVICE_TYPE_GPS:
135 case CONNMAN_DEVICE_TYPE_CELLULAR:
142 static const char *type2string(enum connman_device_type type)
145 case CONNMAN_DEVICE_TYPE_UNKNOWN:
146 case CONNMAN_DEVICE_TYPE_VENDOR:
148 case CONNMAN_DEVICE_TYPE_ETHERNET:
150 case CONNMAN_DEVICE_TYPE_WIFI:
152 case CONNMAN_DEVICE_TYPE_WIMAX:
154 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
156 case CONNMAN_DEVICE_TYPE_GPS:
158 case CONNMAN_DEVICE_TYPE_CELLULAR:
165 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
167 enum connman_device_type type = connman_device_get_type(device);
170 case CONNMAN_DEVICE_TYPE_UNKNOWN:
171 case CONNMAN_DEVICE_TYPE_VENDOR:
172 case CONNMAN_DEVICE_TYPE_GPS:
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_CELLULAR:
183 return CONNMAN_SERVICE_TYPE_CELLULAR;
186 return CONNMAN_SERVICE_TYPE_UNKNOWN;
189 static void powered_changed(struct connman_device *device)
191 connman_dbus_property_changed_basic(device->element.path,
192 CONNMAN_DEVICE_INTERFACE, "Powered",
193 DBUS_TYPE_BOOLEAN, &device->powered);
196 static void blocked_changed(struct connman_device *device)
198 connman_dbus_property_changed_basic(device->element.path,
199 CONNMAN_DEVICE_INTERFACE, "Blocked",
200 DBUS_TYPE_BOOLEAN, &device->blocked);
203 int __connman_device_enable(struct connman_device *device)
207 DBG("device %p %d", device, device->blocked);
209 if (!device->driver || !device->driver->enable)
212 if (device->powered_pending == TRUE)
215 if (device->blocked == TRUE)
218 err = device->driver->enable(device);
220 if (err == -EINPROGRESS) {
221 device->powered_pending = TRUE;
222 device->offlinemode = FALSE;
223 if (__connman_profile_get_offlinemode() == TRUE)
224 __connman_profile_set_offlinemode(FALSE, FALSE);
229 device->powered_pending = TRUE;
230 device->powered = TRUE;
231 device->offlinemode = FALSE;
232 if (__connman_profile_get_offlinemode() == TRUE)
233 __connman_profile_set_offlinemode(FALSE, FALSE);
235 __connman_technology_enable_device(device);
240 int __connman_device_disable(struct connman_device *device)
244 DBG("device %p", device);
246 if (!device->driver || !device->driver->disable)
249 if (device->powered == FALSE)
252 if (device->powered_pending == FALSE)
255 device->reconnect = FALSE;
257 clear_scan_trigger(device);
259 g_hash_table_remove_all(device->networks);
261 err = device->driver->disable(device);
263 if (err == -EINPROGRESS)
264 device->powered_pending = FALSE;
268 device->powered_pending = FALSE;
269 device->powered = FALSE;
271 __connman_technology_disable_device(device);
276 static int set_powered(struct connman_device *device, connman_bool_t powered)
278 DBG("device %p powered %d", device, powered);
281 return __connman_device_enable(device);
283 return __connman_device_disable(device);
286 void __connman_device_list(DBusMessageIter *iter, void *user_data)
288 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, iter);
291 static void append_path(gpointer key, gpointer value, gpointer user_data)
293 struct connman_element *element = value;
294 DBusMessageIter *iter = user_data;
296 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
300 static void append_networks(DBusMessageIter *iter, void *user_data)
302 struct connman_device *device = user_data;
304 g_hash_table_foreach(device->networks, append_path, iter);
307 static DBusMessage *get_properties(DBusConnection *conn,
308 DBusMessage *msg, void *data)
310 struct connman_device *device = data;
312 DBusMessageIter array, dict;
315 DBG("conn %p", conn);
317 reply = dbus_message_new_method_return(msg);
321 dbus_message_iter_init_append(reply, &array);
323 connman_dbus_dict_open(&array, &dict);
325 if (device->name != NULL)
326 connman_dbus_dict_append_basic(&dict, "Name",
327 DBUS_TYPE_STRING, &device->name);
329 str = type2string(device->type);
331 connman_dbus_dict_append_basic(&dict, "Type",
332 DBUS_TYPE_STRING, &str);
334 if (device->address != NULL)
335 connman_dbus_dict_append_basic(&dict, "Address",
336 DBUS_TYPE_STRING, &device->address);
338 if (device->interface != NULL)
339 connman_dbus_dict_append_basic(&dict, "Interface",
340 DBUS_TYPE_STRING, &device->interface);
342 connman_dbus_dict_append_basic(&dict, "Powered",
343 DBUS_TYPE_BOOLEAN, &device->powered);
345 connman_dbus_dict_append_basic(&dict, "Blocked",
346 DBUS_TYPE_BOOLEAN, &device->blocked);
348 if (device->driver && device->driver->scan)
349 connman_dbus_dict_append_basic(&dict, "Scanning",
350 DBUS_TYPE_BOOLEAN, &device->scanning);
352 if (device->scan_interval > 0)
353 connman_dbus_dict_append_basic(&dict, "ScanInterval",
354 DBUS_TYPE_UINT16, &device->scan_interval);
356 connman_dbus_dict_append_array(&dict, "Networks",
357 DBUS_TYPE_OBJECT_PATH, append_networks, device);
359 connman_dbus_dict_close(&array, &dict);
364 static gboolean powered_timeout(gpointer user_data)
366 struct connman_device *device = user_data;
368 DBG("device %p", device);
372 if (device->pending != NULL) {
375 reply = __connman_error_operation_timeout(device->pending);
377 g_dbus_send_message(connection, reply);
379 dbus_message_unref(device->pending);
380 device->pending = NULL;
386 static DBusMessage *set_property(DBusConnection *conn,
387 DBusMessage *msg, void *data)
389 struct connman_device *device = data;
390 DBusMessageIter iter, value;
394 DBG("conn %p", conn);
396 if (dbus_message_iter_init(msg, &iter) == FALSE)
397 return __connman_error_invalid_arguments(msg);
399 dbus_message_iter_get_basic(&iter, &name);
400 dbus_message_iter_next(&iter);
401 dbus_message_iter_recurse(&iter, &value);
403 type = dbus_message_iter_get_arg_type(&value);
405 if (g_str_equal(name, "Powered") == TRUE) {
406 connman_bool_t powered;
409 if (type != DBUS_TYPE_BOOLEAN)
410 return __connman_error_invalid_arguments(msg);
412 dbus_message_iter_get_basic(&value, &powered);
414 device->powered_persistent = powered;
416 __connman_storage_save_device(device);
418 if (device->powered == powered)
419 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
421 if (device->pending != NULL)
422 return __connman_error_in_progress(msg);
424 err = set_powered(device, powered);
426 if (err != -EINPROGRESS)
427 return __connman_error_failed(msg, -err);
429 device->pending = dbus_message_ref(msg);
431 device->timeout = g_timeout_add_seconds(15,
432 powered_timeout, device);
436 } else if (g_str_equal(name, "ScanInterval") == TRUE) {
437 connman_uint16_t interval;
439 if (type != DBUS_TYPE_UINT16)
440 return __connman_error_invalid_arguments(msg);
442 dbus_message_iter_get_basic(&value, &interval);
444 if (device->scan_interval != interval) {
445 device->scan_interval = interval;
447 __connman_storage_save_device(device);
449 reset_scan_trigger(device);
452 return __connman_error_invalid_property(msg);
454 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
457 static DBusMessage *propose_scan(DBusConnection *conn,
458 DBusMessage *msg, void *data)
460 struct connman_device *device = data;
463 DBG("conn %p", conn);
465 err = __connman_device_scan(device);
467 return __connman_error_failed(msg, -err);
469 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
472 static GDBusMethodTable device_methods[] = {
473 { "GetProperties", "", "a{sv}", get_properties },
474 { "SetProperty", "sv", "", set_property,
475 G_DBUS_METHOD_FLAG_ASYNC },
476 { "ProposeScan", "", "", propose_scan },
480 static GDBusSignalTable device_signals[] = {
481 { "PropertyChanged", "sv" },
485 static int register_interface(struct connman_element *element)
487 struct connman_device *device = element->device;
489 DBG("element %p name %s", element, element->name);
491 if (g_dbus_register_interface(connection, element->path,
492 CONNMAN_DEVICE_INTERFACE,
493 device_methods, device_signals,
494 NULL, device, NULL) == FALSE) {
495 connman_error("Failed to register %s device", element->path);
499 device->registered = TRUE;
504 static void unregister_interface(struct connman_element *element)
506 struct connman_device *device = element->device;
508 DBG("element %p name %s", element, element->name);
510 device->registered = FALSE;
512 g_dbus_unregister_interface(connection, element->path,
513 CONNMAN_DEVICE_INTERFACE);
516 static int setup_device(struct connman_device *device)
520 DBG("device %p", device);
522 err = register_interface(&device->element);
524 if (device->driver->remove)
525 device->driver->remove(device);
526 device->driver = NULL;
530 __connman_technology_add_device(device);
532 if (device->offlinemode == FALSE &&
533 device->powered_persistent == TRUE)
534 __connman_device_enable(device);
539 static void probe_driver(struct connman_element *element, gpointer user_data)
541 struct connman_device_driver *driver = user_data;
543 DBG("element %p name %s", element, element->name);
545 if (element->device == NULL)
548 if (element->device->driver != NULL)
551 if (driver->type != element->device->type)
554 if (driver->probe(element->device) < 0)
557 element->device->driver = driver;
559 __connman_element_set_driver(element);
561 setup_device(element->device);
564 static void remove_device(struct connman_device *device)
568 DBG("device %p", device);
570 err = __connman_device_disable(device);
571 if (err < 0 && err == -EINPROGRESS)
572 __connman_technology_disable_device(device);
574 __connman_technology_remove_device(device);
576 unregister_interface(&device->element);
578 if (device->driver->remove)
579 device->driver->remove(device);
581 device->driver = NULL;
584 static void remove_driver(struct connman_element *element, gpointer user_data)
586 struct connman_device_driver *driver = user_data;
588 DBG("element %p name %s", element, element->name);
590 if (element->device == NULL)
593 if (element->device->driver == driver)
594 remove_device(element->device);
597 connman_bool_t __connman_device_has_driver(struct connman_device *device)
599 if (device == NULL || device->driver == NULL)
602 return device->registered;
605 static GSList *driver_list = NULL;
607 static gint compare_priority(gconstpointer a, gconstpointer b)
609 const struct connman_device_driver *driver1 = a;
610 const struct connman_device_driver *driver2 = b;
612 return driver2->priority - driver1->priority;
616 * connman_device_driver_register:
617 * @driver: device driver definition
619 * Register a new device driver
621 * Returns: %0 on success
623 int connman_device_driver_register(struct connman_device_driver *driver)
625 DBG("driver %p name %s", driver, driver->name);
627 driver_list = g_slist_insert_sorted(driver_list, driver,
630 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
631 probe_driver, driver);
637 * connman_device_driver_unregister:
638 * @driver: device driver definition
640 * Remove a previously registered device driver
642 void connman_device_driver_unregister(struct connman_device_driver *driver)
644 DBG("driver %p name %s", driver, driver->name);
646 driver_list = g_slist_remove(driver_list, driver);
648 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
649 remove_driver, driver);
652 static void unregister_network(gpointer data)
654 struct connman_network *network = data;
656 DBG("network %p", network);
658 connman_element_unregister((struct connman_element *) network);
660 __connman_network_set_device(network, NULL);
662 connman_network_unref(network);
665 static void device_destruct(struct connman_element *element)
667 struct connman_device *device = element->device;
669 DBG("element %p name %s", element, element->name);
671 if (device->timeout > 0) {
672 g_source_remove(device->timeout);
676 clear_scan_trigger(device);
678 if (device->pending != NULL) {
679 dbus_message_unref(device->pending);
680 device->pending = NULL;
683 g_free(device->ident);
684 g_free(device->node);
685 g_free(device->name);
686 g_free(device->address);
687 g_free(device->control);
688 g_free(device->interface);
690 g_free(device->last_network);
692 g_hash_table_destroy(device->networks);
693 device->networks = NULL;
697 * connman_device_create:
698 * @node: device node name (for example an address)
701 * Allocate a new device of given #type and assign the #node name to it.
703 * Returns: a newly-allocated #connman_device structure
705 struct connman_device *connman_device_create(const char *node,
706 enum connman_device_type type)
708 struct connman_device *device;
710 enum connman_service_type service_type;
712 DBG("node %s type %d", node, type);
714 device = g_try_new0(struct connman_device, 1);
718 DBG("device %p", device);
720 __connman_element_initialize(&device->element);
722 device->element.name = g_strdup(node);
723 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
725 device->element.device = device;
726 device->element.destruct = device_destruct;
728 str = type2string(type);
730 connman_element_set_string(&device->element,
731 CONNMAN_PROPERTY_ID_TYPE, str);
733 device->element.ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
736 device->name = g_strdup(type2description(device->type));
738 device->powered_persistent = TRUE;
740 device->phyindex = -1;
742 service_type = __connman_device_get_service_type(device);
743 device->blocked = __connman_technology_get_blocked(service_type);
746 case CONNMAN_DEVICE_TYPE_UNKNOWN:
747 case CONNMAN_DEVICE_TYPE_VENDOR:
748 device->scan_interval = 0;
750 case CONNMAN_DEVICE_TYPE_ETHERNET:
751 case CONNMAN_DEVICE_TYPE_WIFI:
752 device->scan_interval = 300;
754 case CONNMAN_DEVICE_TYPE_WIMAX:
755 device->scan_interval = 0;
757 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
758 device->scan_interval = 0;
760 case CONNMAN_DEVICE_TYPE_GPS:
761 device->scan_interval = 0;
763 case CONNMAN_DEVICE_TYPE_CELLULAR:
764 device->scan_interval = 0;
768 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
769 g_free, unregister_network);
775 * connman_device_ref:
776 * @device: device structure
778 * Increase reference counter of device
780 struct connman_device *connman_device_ref(struct connman_device *device)
782 if (connman_element_ref(&device->element) == NULL)
789 * connman_device_unref:
790 * @device: device structure
792 * Decrease reference counter of device
794 void connman_device_unref(struct connman_device *device)
796 connman_element_unref(&device->element);
799 const char *__connman_device_get_type(struct connman_device *device)
801 return type2string(device->type);
805 * connman_device_get_type:
806 * @device: device structure
810 enum connman_device_type connman_device_get_type(struct connman_device *device)
816 * connman_device_get_name:
817 * @device: device structure
819 * Get unique name of device
821 const char *connman_device_get_name(struct connman_device *device)
823 return device->element.name;
827 * connman_device_get_path:
828 * @device: device structure
830 * Get path name of device
832 const char *connman_device_get_path(struct connman_device *device)
834 return device->element.path;
838 * connman_device_set_index:
839 * @device: device structure
840 * @index: index number
842 * Set index number of device
844 void connman_device_set_index(struct connman_device *device, int index)
846 device->element.index = index;
850 * connman_device_get_index:
851 * @device: device structure
853 * Get index number of device
855 int connman_device_get_index(struct connman_device *device)
857 return device->element.index;
860 int __connman_device_get_phyindex(struct connman_device *device)
862 return device->phyindex;
865 void __connman_device_set_phyindex(struct connman_device *device,
868 device->phyindex = phyindex;
872 * connman_device_set_interface:
873 * @device: device structure
874 * @interface: interface name
875 * @control: control interface
877 * Set interface name of device
879 void connman_device_set_interface(struct connman_device *device,
880 const char *interface, const char *control)
882 g_free(device->element.devname);
883 device->element.devname = g_strdup(interface);
885 g_free(device->interface);
886 device->interface = g_strdup(interface);
888 g_free(device->control);
889 device->control = g_strdup(control);
891 if (device->name == NULL) {
892 const char *str = type2description(device->type);
893 if (str != NULL && device->interface != NULL)
894 device->name = g_strdup_printf("%s (%s)", str,
899 const char *connman_device_get_control(struct connman_device *device)
901 return device->control;
905 * connman_device_set_ident:
906 * @device: device structure
907 * @ident: unique identifier
909 * Set unique identifier of device
911 void connman_device_set_ident(struct connman_device *device,
914 g_free(device->ident);
915 device->ident = g_strdup(ident);
918 const char *connman_device_get_ident(struct connman_device *device)
920 return device->ident;
924 * connman_device_set_powered:
925 * @device: device structure
926 * @powered: powered state
928 * Change power state of device
930 int connman_device_set_powered(struct connman_device *device,
931 connman_bool_t powered)
933 DBG("driver %p powered %d", device, powered);
935 if (device->timeout > 0) {
936 g_source_remove(device->timeout);
940 if (device->pending != NULL) {
941 g_dbus_send_reply(connection, device->pending,
944 dbus_message_unref(device->pending);
945 device->pending = NULL;
948 if (device->powered == powered) {
949 device->powered_pending = powered;
954 __connman_device_enable(device);
956 __connman_device_disable(device);
958 device->powered = powered;
959 device->powered_pending = powered;
961 if (device->powered == TRUE)
962 __connman_technology_enable_device(device);
964 __connman_technology_disable_device(device);
966 if (device->offlinemode == TRUE && powered == TRUE) {
967 powered_changed(device);
968 return connman_device_set_powered(device, FALSE);
971 if (device->registered == FALSE)
974 powered_changed(device);
976 if (powered == FALSE)
979 reset_scan_trigger(device);
981 if (device->driver->scan)
982 device->driver->scan(device);
987 int __connman_device_set_blocked(struct connman_device *device,
988 connman_bool_t blocked)
990 connman_bool_t powered;
992 DBG("device %p blocked %d", device, blocked);
994 device->blocked = blocked;
996 blocked_changed(device);
998 if (device->offlinemode == TRUE)
1001 connman_info("%s {rfkill} blocked %d", device->interface, blocked);
1003 if (blocked == FALSE)
1004 powered = device->powered_persistent;
1008 return set_powered(device, powered);
1011 connman_bool_t __connman_device_get_blocked(struct connman_device *device)
1013 return device->blocked;
1016 int __connman_device_scan(struct connman_device *device)
1018 if (!device->driver || !device->driver->scan)
1021 if (device->powered == FALSE)
1024 reset_scan_trigger(device);
1026 return device->driver->scan(device);
1029 int __connman_device_enable_persistent(struct connman_device *device)
1033 DBG("device %p", device);
1035 device->powered_persistent = TRUE;
1037 __connman_storage_save_device(device);
1039 err = __connman_device_enable(device);
1040 if (err == 0 || err == -EINPROGRESS) {
1041 device->offlinemode = FALSE;
1042 if (__connman_profile_get_offlinemode() == TRUE) {
1043 __connman_profile_set_offlinemode(FALSE, FALSE);
1045 __connman_profile_save_default();
1052 int __connman_device_disable_persistent(struct connman_device *device)
1054 DBG("device %p", device);
1056 device->powered_persistent = FALSE;
1058 __connman_storage_save_device(device);
1060 return __connman_device_disable(device);
1063 int __connman_device_disconnect(struct connman_device *device)
1065 GHashTableIter iter;
1066 gpointer key, value;
1068 DBG("device %p", device);
1070 connman_device_set_disconnected(device, TRUE);
1072 g_hash_table_iter_init(&iter, device->networks);
1074 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1075 struct connman_network *network = value;
1077 if (__connman_network_get_connecting(network) == TRUE) {
1079 * Skip network in the process of connecting.
1080 * This is a workaround for WiFi networks serviced
1081 * by the supplicant plugin that hold a reference
1082 * to the network. If we disconnect the network
1083 * here then the referenced object will not be
1084 * registered and usage (like launching DHCP client)
1085 * will fail. There is nothing to be gained by
1086 * removing the network here anyway.
1088 connman_warn("Skipping disconnect of %s",
1089 connman_network_get_identifier(network));
1093 __connman_network_disconnect(network);
1099 static void mark_network_unavailable(gpointer key, gpointer value,
1102 struct connman_network *network = value;
1104 if (connman_network_get_connected(network) == TRUE)
1107 connman_network_set_available(network, FALSE);
1110 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1113 struct connman_network *network = value;
1115 if (connman_network_get_connected(network) == TRUE)
1118 if (connman_network_get_available(network) == TRUE)
1124 void __connman_device_cleanup_networks(struct connman_device *device)
1126 g_hash_table_foreach_remove(device->networks,
1127 remove_unavailable_network, NULL);
1130 static void scanning_changed(struct connman_device *device)
1132 connman_dbus_property_changed_basic(device->element.path,
1133 CONNMAN_DEVICE_INTERFACE, "Scanning",
1134 DBUS_TYPE_BOOLEAN, &device->scanning);
1138 * connman_device_set_scanning:
1139 * @device: device structure
1140 * @scanning: scanning state
1142 * Change scanning state of device
1144 int connman_device_set_scanning(struct connman_device *device,
1145 connman_bool_t scanning)
1147 DBG("device %p scanning %d", device, scanning);
1149 if (!device->driver || !device->driver->scan)
1152 if (device->scanning == scanning)
1155 device->scanning = scanning;
1157 scanning_changed(device);
1159 if (scanning == TRUE) {
1160 reset_scan_trigger(device);
1162 g_hash_table_foreach(device->networks,
1163 mark_network_unavailable, NULL);
1168 __connman_device_cleanup_networks(device);
1170 if (device->connections > 0)
1173 if (device->disconnected == TRUE)
1176 __connman_service_auto_connect();
1182 * connman_device_set_disconnected:
1183 * @device: device structure
1184 * @disconnected: disconnected state
1186 * Change disconnected state of device (only for device with networks)
1188 int connman_device_set_disconnected(struct connman_device *device,
1189 connman_bool_t disconnected)
1191 DBG("device %p disconnected %d", device, disconnected);
1193 if (device->disconnected == disconnected)
1196 device->disconnected = disconnected;
1198 if (disconnected == TRUE)
1199 force_scan_trigger(device);
1205 * connman_device_get_disconnected:
1206 * @device: device structure
1208 * Get device disconnected state
1210 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
1212 return device->disconnected;
1216 * connman_device_set_string:
1217 * @device: device structure
1218 * @key: unique identifier
1219 * @value: string value
1221 * Set string value for specific key
1223 int connman_device_set_string(struct connman_device *device,
1224 const char *key, const char *value)
1226 DBG("device %p key %s value %s", device, key, value);
1228 if (g_str_equal(key, "Address") == TRUE) {
1229 g_free(device->address);
1230 device->address = g_strdup(value);
1231 } else if (g_str_equal(key, "Name") == TRUE) {
1232 g_free(device->name);
1233 device->name = g_strdup(value);
1234 } else if (g_str_equal(key, "Node") == TRUE) {
1235 g_free(device->node);
1236 device->node = g_strdup(value);
1239 return connman_element_set_string(&device->element, key, value);
1243 * connman_device_get_string:
1244 * @device: device structure
1245 * @key: unique identifier
1247 * Get string value for specific key
1249 const char *connman_device_get_string(struct connman_device *device,
1252 DBG("device %p key %s", device, key);
1254 if (g_str_equal(key, "Address") == TRUE)
1255 return device->address;
1256 else if (g_str_equal(key, "Name") == TRUE)
1257 return device->name;
1258 else if (g_str_equal(key, "Node") == TRUE)
1259 return device->node;
1260 else if (g_str_equal(key, "Interface") == TRUE)
1261 return device->interface;
1263 return connman_element_get_string(&device->element, key);
1266 static void set_offlinemode(struct connman_element *element, gpointer user_data)
1268 struct connman_device *device = element->device;
1269 connman_bool_t offlinemode = GPOINTER_TO_UINT(user_data);
1270 connman_bool_t powered;
1272 DBG("element %p name %s", element, element->name);
1277 device->offlinemode = offlinemode;
1279 if (device->blocked == TRUE)
1282 powered = (offlinemode == TRUE) ? FALSE : TRUE;
1284 if (device->powered == powered)
1287 if (device->powered_persistent == FALSE)
1290 set_powered(device, powered);
1293 int __connman_device_set_offlinemode(connman_bool_t offlinemode)
1295 DBG("offlinmode %d", offlinemode);
1297 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
1298 set_offlinemode, GUINT_TO_POINTER(offlinemode));
1300 __connman_notifier_offlinemode(offlinemode);
1305 void __connman_device_increase_connections(struct connman_device *device)
1310 device->connections++;
1313 void __connman_device_decrease_connections(struct connman_device *device)
1318 device->connections--;
1322 * connman_device_add_network:
1323 * @device: device structure
1324 * @network: network structure
1326 * Add new network to the device
1328 int connman_device_add_network(struct connman_device *device,
1329 struct connman_network *network)
1331 const char *identifier = connman_network_get_identifier(network);
1334 DBG("device %p network %p", device, network);
1336 if (identifier == NULL)
1339 __connman_network_set_device(network, device);
1341 err = connman_element_register((struct connman_element *) network,
1344 __connman_network_set_device(network, NULL);
1348 g_hash_table_insert(device->networks, g_strdup(identifier),
1355 * connman_device_get_network:
1356 * @device: device structure
1357 * @identifier: network identifier
1359 * Get network for given identifier
1361 struct connman_network *connman_device_get_network(struct connman_device *device,
1362 const char *identifier)
1364 DBG("device %p identifier %s", device, identifier);
1366 return g_hash_table_lookup(device->networks, identifier);
1370 * connman_device_remove_network:
1371 * @device: device structure
1372 * @identifier: network identifier
1374 * Remove network for given identifier
1376 int connman_device_remove_network(struct connman_device *device,
1377 const char *identifier)
1379 DBG("device %p identifier %s", device, identifier);
1381 g_hash_table_remove(device->networks, identifier);
1386 void connman_device_remove_all_networks(struct connman_device *device)
1388 g_hash_table_remove_all(device->networks);
1391 void __connman_device_set_network(struct connman_device *device,
1392 struct connman_network *network)
1399 if (device->network == network)
1402 if (device->network != NULL)
1403 connman_network_unref(device->network);
1405 if (network != NULL) {
1406 name = connman_network_get_string(network,
1407 CONNMAN_PROPERTY_ID_NAME);
1408 g_free(device->last_network);
1409 device->last_network = g_strdup(name);
1411 device->network = connman_network_ref(network);
1413 g_free(device->last_network);
1414 device->last_network = NULL;
1416 device->network = NULL;
1420 void __connman_device_set_reconnect(struct connman_device *device,
1421 connman_bool_t reconnect)
1423 device->reconnect = reconnect;
1426 connman_bool_t __connman_device_get_reconnect(
1427 struct connman_device *device)
1429 return device->reconnect;
1433 * connman_device_register:
1434 * @device: device structure
1436 * Register device with the system
1438 int connman_device_register(struct connman_device *device)
1440 __connman_storage_load_device(device);
1442 device->offlinemode = __connman_profile_get_offlinemode();
1444 return connman_element_register(&device->element, NULL);
1448 * connman_device_unregister:
1449 * @device: device structure
1451 * Unregister device with the system
1453 void connman_device_unregister(struct connman_device *device)
1455 __connman_storage_save_device(device);
1457 connman_element_unregister(&device->element);
1461 * connman_device_get_data:
1462 * @device: device structure
1464 * Get private device data pointer
1466 void *connman_device_get_data(struct connman_device *device)
1468 return device->driver_data;
1472 * connman_device_set_data:
1473 * @device: device structure
1474 * @data: data pointer
1476 * Set private device data pointer
1478 void connman_device_set_data(struct connman_device *device, void *data)
1480 device->driver_data = data;
1483 static gboolean match_driver(struct connman_device *device,
1484 struct connman_device_driver *driver)
1486 if (device->type == driver->type ||
1487 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1493 static int device_probe(struct connman_element *element)
1495 struct connman_device *device = element->device;
1498 DBG("element %p name %s", element, element->name);
1503 if (device->driver != NULL)
1506 for (list = driver_list; list; list = list->next) {
1507 struct connman_device_driver *driver = list->data;
1509 if (match_driver(device, driver) == FALSE)
1512 DBG("driver %p name %s", driver, driver->name);
1514 if (driver->probe(device) == 0) {
1515 device->driver = driver;
1520 if (device->driver == NULL)
1523 return setup_device(device);
1526 static void device_remove(struct connman_element *element)
1528 struct connman_device *device = element->device;
1530 DBG("element %p name %s", element, element->name);
1535 if (device->driver == NULL)
1538 remove_device(device);
1541 static struct connman_driver device_driver = {
1543 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
1544 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
1545 .probe = device_probe,
1546 .remove = device_remove,
1549 static int device_load(struct connman_device *device)
1551 const char *ident = __connman_profile_active_ident();
1553 GError *error = NULL;
1555 connman_bool_t powered;
1558 DBG("device %p", device);
1560 keyfile = __connman_storage_open_profile(ident);
1561 if (keyfile == NULL)
1564 identifier = g_strdup_printf("device_%s", device->element.name);
1565 if (identifier == NULL)
1568 powered = g_key_file_get_boolean(keyfile, identifier,
1571 device->powered_persistent = powered;
1572 g_clear_error(&error);
1574 val = g_key_file_get_integer(keyfile, identifier,
1575 "ScanInterval", &error);
1577 device->scan_interval = val;
1578 g_clear_error(&error);
1583 __connman_storage_close_profile(ident, keyfile, FALSE);
1588 static int device_save(struct connman_device *device)
1590 const char *ident = __connman_profile_active_ident();
1594 DBG("device %p", device);
1596 keyfile = __connman_storage_open_profile(ident);
1597 if (keyfile == NULL)
1600 identifier = g_strdup_printf("device_%s", device->element.name);
1601 if (identifier == NULL)
1604 g_key_file_set_boolean(keyfile, identifier,
1605 "Powered", device->powered_persistent);
1607 g_key_file_set_integer(keyfile, identifier,
1608 "ScanInterval", device->scan_interval);
1613 __connman_storage_close_profile(ident, keyfile, TRUE);
1618 static struct connman_storage device_storage = {
1620 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
1621 .device_load = device_load,
1622 .device_save = device_save,
1625 int __connman_device_init(void)
1629 connection = connman_dbus_get_connection();
1631 if (connman_storage_register(&device_storage) < 0)
1632 connman_error("Failed to register device storage");
1634 return connman_driver_register(&device_driver);
1637 void __connman_device_cleanup(void)
1641 connman_driver_unregister(&device_driver);
1643 connman_storage_unregister(&device_storage);
1645 dbus_connection_unref(connection);