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
31 static GSList *device_list = NULL;
32 static gchar **device_filter = NULL;
33 static gchar **nodevice_filter = NULL;
35 enum connman_pending_type {
41 struct connman_device {
43 enum connman_device_type type;
44 enum connman_pending_type powered_pending; /* Indicates a pending
45 enable/disable request */
46 connman_bool_t offlinemode;
47 connman_bool_t blocked;
48 connman_bool_t powered;
49 connman_bool_t powered_persistent;
50 connman_bool_t scanning;
51 connman_bool_t disconnected;
52 connman_bool_t reconnect;
53 connman_uint16_t scan_interval;
54 connman_uint16_t backoff_interval;
64 unsigned int connections;
66 guint pending_timeout;
68 struct connman_device_driver *driver;
72 struct connman_network *network;
76 #define SCAN_INITIAL_DELAY 10
78 static gboolean device_scan_trigger(gpointer user_data)
80 struct connman_device *device = user_data;
82 DBG("device %p", device);
84 if (device->driver == NULL) {
85 device->scan_timeout = 0;
89 if (device->driver->scan)
90 device->driver->scan(device);
95 static void clear_scan_trigger(struct connman_device *device)
97 if (device->scan_timeout > 0) {
98 g_source_remove(device->scan_timeout);
99 device->scan_timeout = 0;
103 static void reset_scan_trigger(struct connman_device *device)
105 clear_scan_trigger(device);
107 if (device->scan_interval > 0) {
110 if (g_hash_table_size(device->networks) == 0) {
111 if (device->backoff_interval >= device->scan_interval)
112 device->backoff_interval = SCAN_INITIAL_DELAY;
113 interval = device->backoff_interval;
115 interval = device->scan_interval;
117 DBG("interval %d", interval);
119 device->scan_timeout = g_timeout_add_seconds(interval,
120 device_scan_trigger, device);
122 device->backoff_interval *= 2;
123 if (device->backoff_interval > device->scan_interval)
124 device->backoff_interval = device->scan_interval;
128 static void force_scan_trigger(struct connman_device *device)
130 clear_scan_trigger(device);
132 device->scan_timeout = g_timeout_add_seconds(5,
133 device_scan_trigger, device);
136 void connman_device_schedule_scan(struct connman_device *device)
138 reset_scan_trigger(device);
141 static const char *type2description(enum connman_device_type type)
144 case CONNMAN_DEVICE_TYPE_UNKNOWN:
145 case CONNMAN_DEVICE_TYPE_VENDOR:
147 case CONNMAN_DEVICE_TYPE_ETHERNET:
149 case CONNMAN_DEVICE_TYPE_WIFI:
151 case CONNMAN_DEVICE_TYPE_WIMAX:
153 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
155 case CONNMAN_DEVICE_TYPE_GPS:
157 case CONNMAN_DEVICE_TYPE_CELLULAR:
159 case CONNMAN_DEVICE_TYPE_GADGET:
167 static const char *type2string(enum connman_device_type type)
170 case CONNMAN_DEVICE_TYPE_UNKNOWN:
171 case CONNMAN_DEVICE_TYPE_VENDOR:
173 case CONNMAN_DEVICE_TYPE_ETHERNET:
175 case CONNMAN_DEVICE_TYPE_WIFI:
177 case CONNMAN_DEVICE_TYPE_WIMAX:
179 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
181 case CONNMAN_DEVICE_TYPE_GPS:
183 case CONNMAN_DEVICE_TYPE_CELLULAR:
185 case CONNMAN_DEVICE_TYPE_GADGET:
193 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
195 enum connman_device_type type = connman_device_get_type(device);
198 case CONNMAN_DEVICE_TYPE_UNKNOWN:
199 case CONNMAN_DEVICE_TYPE_VENDOR:
200 case CONNMAN_DEVICE_TYPE_GPS:
202 case CONNMAN_DEVICE_TYPE_ETHERNET:
203 return CONNMAN_SERVICE_TYPE_ETHERNET;
204 case CONNMAN_DEVICE_TYPE_WIFI:
205 return CONNMAN_SERVICE_TYPE_WIFI;
206 case CONNMAN_DEVICE_TYPE_WIMAX:
207 return CONNMAN_SERVICE_TYPE_WIMAX;
208 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
209 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
210 case CONNMAN_DEVICE_TYPE_CELLULAR:
211 return CONNMAN_SERVICE_TYPE_CELLULAR;
212 case CONNMAN_DEVICE_TYPE_GADGET:
213 return CONNMAN_SERVICE_TYPE_GADGET;
217 return CONNMAN_SERVICE_TYPE_UNKNOWN;
220 static gboolean device_pending_reset(gpointer user_data)
222 struct connman_device *device = user_data;
224 DBG("device %p", device);
226 /* Power request timedout, reset power pending state. */
227 if (device->pending_timeout > 0) {
228 g_source_remove(device->pending_timeout);
229 device->pending_timeout = 0;
230 device->powered_pending = PENDING_NONE;
236 int __connman_device_enable(struct connman_device *device)
240 DBG("device %p %d", device, device->blocked);
242 if (!device->driver || !device->driver->enable)
245 if (device->blocked == TRUE)
248 /* There is an ongoing power disable request. */
249 if (device->powered_pending == PENDING_DISABLE)
252 if (device->powered_pending == PENDING_ENABLE)
255 if (device->powered_pending == PENDING_NONE && device->powered == TRUE)
258 device->powered_pending = PENDING_ENABLE;
260 err = device->driver->enable(device);
262 * device gets enabled right away.
263 * Invoke the callback
266 connman_device_set_powered(device, TRUE);
270 if (err == -EALREADY) {
271 /* If device is already powered, but connman is not updated */
272 connman_device_set_powered(device, TRUE);
276 * if err == -EINPROGRESS, then the DBus call to the respective daemon
277 * was successful. We set a 4 sec timeout so if the daemon never
278 * returns a reply, we would reset the pending request.
280 if (err == -EINPROGRESS)
281 device->pending_timeout = g_timeout_add_seconds(4,
282 device_pending_reset, device);
287 int __connman_device_disable(struct connman_device *device)
291 DBG("device %p", device);
293 if (!device->driver || !device->driver->disable)
296 if (device->blocked == TRUE)
299 /* Ongoing power enable request */
300 if (device->powered_pending == PENDING_ENABLE)
303 if (device->powered_pending == PENDING_DISABLE)
306 if (device->powered_pending == PENDING_NONE && device->powered == FALSE)
309 device->reconnect = FALSE;
311 clear_scan_trigger(device);
313 err = device->driver->disable(device);
315 connman_device_set_powered(device, FALSE);
319 if (err == -EALREADY) {
320 connman_device_set_powered(device, FALSE);
324 if (err == -EINPROGRESS)
325 device->pending_timeout = g_timeout_add_seconds(4,
326 device_pending_reset, device);
331 static int set_powered(struct connman_device *device, connman_bool_t powered)
333 DBG("device %p powered %d", device, powered);
336 return __connman_device_enable(device);
338 return __connman_device_disable(device);
341 static int setup_device(struct connman_device *device)
343 DBG("device %p", device);
345 __connman_technology_add_device(device);
347 if (device->offlinemode == FALSE &&
348 device->powered_persistent == TRUE)
349 __connman_device_enable(device);
354 static void probe_driver(struct connman_device_driver *driver)
358 DBG("driver %p name %s", driver, driver->name);
360 for (list = device_list; list != NULL; list = list->next) {
361 struct connman_device *device = list->data;
363 if (device->driver != NULL)
366 if (driver->type != device->type)
369 if (driver->probe(device) < 0)
372 device->driver = driver;
374 setup_device(device);
378 static void remove_device(struct connman_device *device)
380 DBG("device %p", device);
382 __connman_device_disable(device);
384 __connman_technology_remove_device(device);
386 if (device->driver->remove)
387 device->driver->remove(device);
389 device->driver = NULL;
392 static void remove_driver(struct connman_device_driver *driver)
396 DBG("driver %p name %s", driver, driver->name);
398 for (list = device_list; list != NULL; list = list->next) {
399 struct connman_device *device = list->data;
401 if (device->driver == driver)
402 remove_device(device);
406 connman_bool_t __connman_device_has_driver(struct connman_device *device)
408 if (device == NULL || device->driver == NULL)
414 static GSList *driver_list = NULL;
416 static gint compare_priority(gconstpointer a, gconstpointer b)
418 const struct connman_device_driver *driver1 = a;
419 const struct connman_device_driver *driver2 = b;
421 return driver2->priority - driver1->priority;
425 * connman_device_driver_register:
426 * @driver: device driver definition
428 * Register a new device driver
430 * Returns: %0 on success
432 int connman_device_driver_register(struct connman_device_driver *driver)
434 DBG("driver %p name %s", driver, driver->name);
436 driver_list = g_slist_insert_sorted(driver_list, driver,
438 probe_driver(driver);
444 * connman_device_driver_unregister:
445 * @driver: device driver definition
447 * Remove a previously registered device driver
449 void connman_device_driver_unregister(struct connman_device_driver *driver)
451 DBG("driver %p name %s", driver, driver->name);
453 driver_list = g_slist_remove(driver_list, driver);
455 remove_driver(driver);
458 static void free_network(gpointer data)
460 struct connman_network *network = data;
462 DBG("network %p", network);
464 __connman_network_set_device(network, NULL);
466 connman_network_unref(network);
469 static void device_destruct(struct connman_device *device)
471 DBG("device %p name %s", device, device->name);
473 clear_scan_trigger(device);
475 g_free(device->ident);
476 g_free(device->node);
477 g_free(device->name);
478 g_free(device->address);
479 g_free(device->interface);
480 g_free(device->path);
481 g_free(device->devname);
483 g_free(device->last_network);
485 g_hash_table_destroy(device->networks);
486 device->networks = NULL;
492 * connman_device_create:
493 * @node: device node name (for example an address)
496 * Allocate a new device of given #type and assign the #node name to it.
498 * Returns: a newly-allocated #connman_device structure
500 struct connman_device *connman_device_create(const char *node,
501 enum connman_device_type type)
503 struct connman_device *device;
504 enum connman_service_type service_type;
505 connman_bool_t bg_scan;
507 DBG("node %s type %d", node, type);
509 device = g_try_new0(struct connman_device, 1);
513 DBG("device %p", device);
515 device->refcount = 1;
517 bg_scan = connman_setting_get_bool("BackgroundScanning");
520 device->name = g_strdup(type2description(device->type));
522 device->powered_persistent = TRUE;
524 device->phyindex = -1;
526 service_type = __connman_device_get_service_type(device);
527 device->blocked = __connman_technology_get_blocked(service_type);
528 device->backoff_interval = SCAN_INITIAL_DELAY;
531 case CONNMAN_DEVICE_TYPE_UNKNOWN:
532 case CONNMAN_DEVICE_TYPE_ETHERNET:
533 case CONNMAN_DEVICE_TYPE_WIMAX:
534 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
535 case CONNMAN_DEVICE_TYPE_CELLULAR:
536 case CONNMAN_DEVICE_TYPE_GPS:
537 case CONNMAN_DEVICE_TYPE_GADGET:
538 case CONNMAN_DEVICE_TYPE_VENDOR:
539 device->scan_interval = 0;
541 case CONNMAN_DEVICE_TYPE_WIFI:
543 device->scan_interval = 300;
545 device->scan_interval = 0;
549 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
550 g_free, free_network);
552 device_list = g_slist_append(device_list, device);
558 * connman_device_ref:
559 * @device: device structure
561 * Increase reference counter of device
563 struct connman_device *connman_device_ref(struct connman_device *device)
567 g_atomic_int_inc(&device->refcount);
573 * connman_device_unref:
574 * @device: device structure
576 * Decrease reference counter of device
578 void connman_device_unref(struct connman_device *device)
580 if (g_atomic_int_dec_and_test(&device->refcount) == FALSE)
583 if (device->driver) {
584 device->driver->remove(device);
585 device->driver = NULL;
588 device_list = g_slist_remove(device_list, device);
590 device_destruct(device);
593 const char *__connman_device_get_type(struct connman_device *device)
595 return type2string(device->type);
599 * connman_device_get_type:
600 * @device: device structure
604 enum connman_device_type connman_device_get_type(struct connman_device *device)
610 * connman_device_set_index:
611 * @device: device structure
612 * @index: index number
614 * Set index number of device
616 void connman_device_set_index(struct connman_device *device, int index)
618 device->index = index;
622 * connman_device_get_index:
623 * @device: device structure
625 * Get index number of device
627 int connman_device_get_index(struct connman_device *device)
629 return device->index;
632 int __connman_device_get_phyindex(struct connman_device *device)
634 return device->phyindex;
637 void __connman_device_set_phyindex(struct connman_device *device,
640 device->phyindex = phyindex;
644 * connman_device_set_interface:
645 * @device: device structure
646 * @interface: interface name
648 * Set interface name of device
650 void connman_device_set_interface(struct connman_device *device,
651 const char *interface)
653 g_free(device->devname);
654 device->devname = g_strdup(interface);
656 g_free(device->interface);
657 device->interface = g_strdup(interface);
659 if (device->name == NULL) {
660 const char *str = type2description(device->type);
661 if (str != NULL && device->interface != NULL)
662 device->name = g_strdup_printf("%s (%s)", str,
668 * connman_device_set_ident:
669 * @device: device structure
670 * @ident: unique identifier
672 * Set unique identifier of device
674 void connman_device_set_ident(struct connman_device *device,
677 g_free(device->ident);
678 device->ident = g_strdup(ident);
681 const char *connman_device_get_ident(struct connman_device *device)
683 return device->ident;
687 * connman_device_set_powered:
688 * @device: device structure
689 * @powered: powered state
691 * Change power state of device
693 int connman_device_set_powered(struct connman_device *device,
694 connman_bool_t powered)
696 enum connman_service_type type;
698 DBG("driver %p powered %d", device, powered);
700 if (device->powered == powered)
703 /* Reset pending request */
704 g_source_remove(device->pending_timeout);
705 device->pending_timeout = 0;
706 device->powered_pending = PENDING_NONE;
708 if (device->offlinemode == TRUE && powered == TRUE)
709 return __connman_device_disable(device);
711 device->powered = powered;
713 type = __connman_device_get_service_type(device);
715 if (device->powered == TRUE)
716 __connman_technology_enabled(type);
718 __connman_technology_disabled(type);
720 if (powered == FALSE) {
721 device->connections = 0;
725 connman_device_set_disconnected(device, FALSE);
726 device->scanning = FALSE;
728 reset_scan_trigger(device);
730 if (device->driver && device->driver->scan)
731 device->driver->scan(device);
736 int __connman_device_set_blocked(struct connman_device *device,
737 connman_bool_t blocked)
739 connman_bool_t powered;
741 DBG("device %p blocked %d", device, blocked);
743 device->blocked = blocked;
745 if (device->offlinemode == TRUE)
748 connman_info("%s {rfkill} blocked %d", device->interface, blocked);
750 if (blocked == FALSE)
751 powered = device->powered_persistent;
755 return set_powered(device, powered);
758 connman_bool_t __connman_device_get_blocked(struct connman_device *device)
760 return device->blocked;
763 static int device_scan(struct connman_device *device)
765 if (!device->driver || !device->driver->scan)
768 if (device->powered == FALSE)
771 reset_scan_trigger(device);
773 return device->driver->scan(device);
776 int __connman_device_enable_persistent(struct connman_device *device)
778 DBG("device %p", device);
780 device->powered_persistent = TRUE;
782 __connman_storage_save_device(device);
784 return __connman_device_enable(device);
787 int __connman_device_disable_persistent(struct connman_device *device)
789 DBG("device %p", device);
791 device->powered_persistent = FALSE;
793 __connman_storage_save_device(device);
795 return __connman_device_disable(device);
798 int __connman_device_disconnect(struct connman_device *device)
803 DBG("device %p", device);
805 connman_device_set_disconnected(device, TRUE);
807 g_hash_table_iter_init(&iter, device->networks);
809 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
810 struct connman_network *network = value;
812 if (connman_network_get_connecting(network) == TRUE) {
814 * Skip network in the process of connecting.
815 * This is a workaround for WiFi networks serviced
816 * by the supplicant plugin that hold a reference
817 * to the network. If we disconnect the network
818 * here then the referenced object will not be
819 * registered and usage (like launching DHCP client)
820 * will fail. There is nothing to be gained by
821 * removing the network here anyway.
823 connman_warn("Skipping disconnect of %s, network is connecting.",
824 connman_network_get_identifier(network));
828 __connman_network_disconnect(network);
834 static void mark_network_available(gpointer key, gpointer value,
837 struct connman_network *network = value;
839 connman_network_set_available(network, TRUE);
842 static void mark_network_unavailable(gpointer key, gpointer value,
845 struct connman_network *network = value;
847 if (connman_network_get_connected(network) == TRUE)
850 connman_network_set_available(network, FALSE);
853 static gboolean remove_unavailable_network(gpointer key, gpointer value,
856 struct connman_network *network = value;
858 if (connman_network_get_connected(network) == TRUE)
861 if (connman_network_get_available(network) == TRUE)
867 void __connman_device_cleanup_networks(struct connman_device *device)
869 g_hash_table_foreach_remove(device->networks,
870 remove_unavailable_network, NULL);
873 connman_bool_t __connman_device_scanning(struct connman_device *device)
875 return device->scanning;
878 void connman_device_reset_scanning(struct connman_device *device)
880 device->scanning = FALSE;
882 g_hash_table_foreach(device->networks,
883 mark_network_available, NULL);
888 * connman_device_set_scanning:
889 * @device: device structure
890 * @scanning: scanning state
892 * Change scanning state of device
894 int connman_device_set_scanning(struct connman_device *device,
895 connman_bool_t scanning)
897 DBG("device %p scanning %d", device, scanning);
899 if (!device->driver || !device->driver->scan)
902 if (device->scanning == scanning)
905 device->scanning = scanning;
907 if (scanning == TRUE) {
908 reset_scan_trigger(device);
910 g_hash_table_foreach(device->networks,
911 mark_network_unavailable, NULL);
916 __connman_device_cleanup_networks(device);
918 if (device->connections > 0)
921 __connman_service_auto_connect();
927 * connman_device_set_disconnected:
928 * @device: device structure
929 * @disconnected: disconnected state
931 * Change disconnected state of device (only for device with networks)
933 int connman_device_set_disconnected(struct connman_device *device,
934 connman_bool_t disconnected)
936 DBG("device %p disconnected %d", device, disconnected);
938 if (device->disconnected == disconnected)
941 device->disconnected = disconnected;
943 if (disconnected == TRUE)
944 force_scan_trigger(device);
950 * connman_device_get_disconnected:
951 * @device: device structure
953 * Get device disconnected state
955 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
957 return device->disconnected;
961 * connman_device_set_string:
962 * @device: device structure
963 * @key: unique identifier
964 * @value: string value
966 * Set string value for specific key
968 int connman_device_set_string(struct connman_device *device,
969 const char *key, const char *value)
971 DBG("device %p key %s value %s", device, key, value);
973 if (g_str_equal(key, "Address") == TRUE) {
974 g_free(device->address);
975 device->address = g_strdup(value);
976 } else if (g_str_equal(key, "Name") == TRUE) {
977 g_free(device->name);
978 device->name = g_strdup(value);
979 } else if (g_str_equal(key, "Node") == TRUE) {
980 g_free(device->node);
981 device->node = g_strdup(value);
982 } else if (g_str_equal(key, "Path") == TRUE) {
983 g_free(device->path);
984 device->path = g_strdup(value);
993 * connman_device_get_string:
994 * @device: device structure
995 * @key: unique identifier
997 * Get string value for specific key
999 const char *connman_device_get_string(struct connman_device *device,
1002 DBG("device %p key %s", device, key);
1004 if (g_str_equal(key, "Address") == TRUE)
1005 return device->address;
1006 else if (g_str_equal(key, "Name") == TRUE)
1007 return device->name;
1008 else if (g_str_equal(key, "Node") == TRUE)
1009 return device->node;
1010 else if (g_str_equal(key, "Interface") == TRUE)
1011 return device->interface;
1012 else if (g_str_equal(key, "Path") == TRUE)
1013 return device->path;
1018 static void set_offlinemode(struct connman_device *device,
1019 connman_bool_t offlinemode)
1021 connman_bool_t powered;
1023 DBG("device %p name %s", device, device->name);
1028 device->offlinemode = offlinemode;
1030 if (device->blocked == TRUE)
1033 powered = (offlinemode == TRUE) ? FALSE : TRUE;
1035 if (device->powered == powered)
1038 if (device->powered_persistent == FALSE)
1041 set_powered(device, powered);
1044 int __connman_device_set_offlinemode(connman_bool_t offlinemode)
1048 DBG("offlinmode %d", offlinemode);
1050 for (list = device_list; list != NULL; list = list->next) {
1051 struct connman_device *device = list->data;
1053 set_offlinemode(device, offlinemode);
1056 __connman_notifier_offlinemode(offlinemode);
1061 void __connman_device_increase_connections(struct connman_device *device)
1066 device->connections++;
1069 void __connman_device_decrease_connections(struct connman_device *device)
1074 device->connections--;
1076 if (device->connections == 0)
1077 device->backoff_interval = SCAN_INITIAL_DELAY;
1081 * connman_device_add_network:
1082 * @device: device structure
1083 * @network: network structure
1085 * Add new network to the device
1087 int connman_device_add_network(struct connman_device *device,
1088 struct connman_network *network)
1090 const char *identifier = connman_network_get_identifier(network);
1092 DBG("device %p network %p", device, network);
1094 if (identifier == NULL)
1097 connman_network_ref(network);
1099 __connman_network_set_device(network, device);
1101 g_hash_table_insert(device->networks, g_strdup(identifier),
1108 * connman_device_get_network:
1109 * @device: device structure
1110 * @identifier: network identifier
1112 * Get network for given identifier
1114 struct connman_network *connman_device_get_network(struct connman_device *device,
1115 const char *identifier)
1117 DBG("device %p identifier %s", device, identifier);
1119 return g_hash_table_lookup(device->networks, identifier);
1123 * connman_device_remove_network:
1124 * @device: device structure
1125 * @identifier: network identifier
1127 * Remove network for given identifier
1129 int connman_device_remove_network(struct connman_device *device,
1130 struct connman_network *network)
1132 const char *identifier;
1134 DBG("device %p network %p", device, network);
1136 if (network == NULL)
1139 identifier = connman_network_get_identifier(network);
1140 g_hash_table_remove(device->networks, identifier);
1145 void connman_device_remove_all_networks(struct connman_device *device)
1147 g_hash_table_remove_all(device->networks);
1150 void __connman_device_set_network(struct connman_device *device,
1151 struct connman_network *network)
1158 if (device->network == network)
1161 if (network != NULL) {
1162 name = connman_network_get_string(network, "Name");
1163 g_free(device->last_network);
1164 device->last_network = g_strdup(name);
1166 device->network = network;
1168 g_free(device->last_network);
1169 device->last_network = NULL;
1171 device->network = NULL;
1175 void __connman_device_set_reconnect(struct connman_device *device,
1176 connman_bool_t reconnect)
1178 device->reconnect = reconnect;
1181 connman_bool_t __connman_device_get_reconnect(
1182 struct connman_device *device)
1184 return device->reconnect;
1187 static gboolean match_driver(struct connman_device *device,
1188 struct connman_device_driver *driver)
1190 if (device->type == driver->type ||
1191 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1197 static int device_probe(struct connman_device *device)
1201 DBG("device %p name %s", device, device->name);
1203 if (device->driver != NULL)
1206 for (list = driver_list; list; list = list->next) {
1207 struct connman_device_driver *driver = list->data;
1209 if (match_driver(device, driver) == FALSE)
1212 DBG("driver %p name %s", driver, driver->name);
1214 if (driver->probe(device) == 0) {
1215 device->driver = driver;
1220 if (device->driver == NULL)
1223 return setup_device(device);
1226 static void device_remove(struct connman_device *device)
1228 DBG("device %p name %s", device, device->name);
1230 if (device->driver == NULL)
1233 remove_device(device);
1237 * connman_device_register:
1238 * @device: device structure
1240 * Register device with the system
1242 int connman_device_register(struct connman_device *device)
1244 __connman_storage_load_device(device);
1246 device->offlinemode = __connman_profile_get_offlinemode();
1248 return device_probe(device);
1252 * connman_device_unregister:
1253 * @device: device structure
1255 * Unregister device with the system
1257 void connman_device_unregister(struct connman_device *device)
1259 __connman_storage_save_device(device);
1261 device_remove(device);
1265 * connman_device_get_data:
1266 * @device: device structure
1268 * Get private device data pointer
1270 void *connman_device_get_data(struct connman_device *device)
1272 return device->driver_data;
1276 * connman_device_set_data:
1277 * @device: device structure
1278 * @data: data pointer
1280 * Set private device data pointer
1282 void connman_device_set_data(struct connman_device *device, void *data)
1284 device->driver_data = data;
1287 struct connman_device *__connman_device_find_device(
1288 enum connman_service_type type)
1292 for (list = device_list; list != NULL; list = list->next) {
1293 struct connman_device *device = list->data;
1294 enum connman_service_type service_type =
1295 __connman_device_get_service_type(device);
1297 if (service_type != type)
1306 int __connman_device_request_scan(enum connman_service_type type)
1312 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1313 case CONNMAN_SERVICE_TYPE_SYSTEM:
1314 case CONNMAN_SERVICE_TYPE_ETHERNET:
1315 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1316 case CONNMAN_SERVICE_TYPE_CELLULAR:
1317 case CONNMAN_SERVICE_TYPE_GPS:
1318 case CONNMAN_SERVICE_TYPE_VPN:
1319 case CONNMAN_SERVICE_TYPE_GADGET:
1321 case CONNMAN_SERVICE_TYPE_WIFI:
1322 case CONNMAN_SERVICE_TYPE_WIMAX:
1326 for (list = device_list; list != NULL; list = list->next) {
1327 struct connman_device *device = list->data;
1328 enum connman_service_type service_type =
1329 __connman_device_get_service_type(device);
1331 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
1332 service_type != type) {
1336 err = device_scan(device);
1337 if (err < 0 && err != -EINPROGRESS) {
1339 /* XXX maybe only a continue? */
1347 connman_bool_t __connman_device_isfiltered(const char *devname)
1351 if (device_filter == NULL)
1354 for (pattern = device_filter; *pattern; pattern++) {
1355 if (g_pattern_match_simple(*pattern, devname) == FALSE) {
1356 DBG("ignoring device %s (match)", devname);
1362 if (g_pattern_match_simple("dummy*", devname) == TRUE) {
1363 DBG("ignoring dummy networking devices");
1367 if (nodevice_filter == NULL)
1370 for (pattern = nodevice_filter; *pattern; pattern++) {
1371 if (g_pattern_match_simple(*pattern, devname) == TRUE) {
1372 DBG("ignoring device %s (no match)", devname);
1380 static int device_load(struct connman_device *device)
1382 const char *ident = __connman_profile_active_ident();
1384 GError *error = NULL;
1386 connman_bool_t powered;
1388 DBG("device %p", device);
1390 keyfile = __connman_storage_open_profile(ident);
1391 if (keyfile == NULL)
1394 identifier = g_strdup_printf("device_%s", device->name);
1395 if (identifier == NULL)
1398 powered = g_key_file_get_boolean(keyfile, identifier,
1401 device->powered_persistent = powered;
1402 g_clear_error(&error);
1407 __connman_storage_close_profile(ident, keyfile, FALSE);
1412 static int device_save(struct connman_device *device)
1414 const char *ident = __connman_profile_active_ident();
1418 DBG("device %p", device);
1420 keyfile = __connman_storage_open_profile(ident);
1421 if (keyfile == NULL)
1424 identifier = g_strdup_printf("device_%s", device->name);
1425 if (identifier == NULL)
1428 g_key_file_set_boolean(keyfile, identifier,
1429 "Powered", device->powered_persistent);
1434 __connman_storage_close_profile(ident, keyfile, TRUE);
1439 static struct connman_storage device_storage = {
1441 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
1442 .device_load = device_load,
1443 .device_save = device_save,
1446 int __connman_device_init(const char *device, const char *nodevice)
1451 device_filter = g_strsplit(device, ",", -1);
1453 if (nodevice != NULL)
1454 nodevice_filter = g_strsplit(nodevice, ",", -1);
1456 return connman_storage_register(&device_storage);
1459 void __connman_device_cleanup(void)
1463 g_strfreev(nodevice_filter);
1464 g_strfreev(device_filter);
1466 connman_storage_unregister(&device_storage);