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 powered;
47 connman_bool_t powered_persistent;
48 connman_bool_t scanning;
49 connman_bool_t disconnected;
50 connman_bool_t reconnect;
51 connman_uint16_t scan_interval;
52 connman_uint16_t backoff_interval;
62 unsigned int connections;
64 guint pending_timeout;
66 struct connman_device_driver *driver;
70 struct connman_network *network;
74 #define SCAN_INITIAL_DELAY 10
76 static gboolean device_scan_trigger(gpointer user_data)
78 struct connman_device *device = user_data;
80 DBG("device %p", device);
82 if (device->driver == NULL) {
83 device->scan_timeout = 0;
87 if (device->driver->scan)
88 device->driver->scan(device);
93 static void clear_scan_trigger(struct connman_device *device)
95 if (device->scan_timeout > 0) {
96 g_source_remove(device->scan_timeout);
97 device->scan_timeout = 0;
101 static void reset_scan_trigger(struct connman_device *device)
103 clear_scan_trigger(device);
105 if (device->scan_interval > 0) {
108 if (g_hash_table_size(device->networks) == 0) {
109 if (device->backoff_interval >= device->scan_interval)
110 device->backoff_interval = SCAN_INITIAL_DELAY;
111 interval = device->backoff_interval;
113 interval = device->scan_interval;
115 DBG("interval %d", interval);
117 device->scan_timeout = g_timeout_add_seconds(interval,
118 device_scan_trigger, device);
120 device->backoff_interval *= 2;
121 if (device->backoff_interval > device->scan_interval)
122 device->backoff_interval = device->scan_interval;
126 static void force_scan_trigger(struct connman_device *device)
128 clear_scan_trigger(device);
130 device->scan_timeout = g_timeout_add_seconds(5,
131 device_scan_trigger, device);
134 void connman_device_schedule_scan(struct connman_device *device)
136 reset_scan_trigger(device);
139 static const char *type2description(enum connman_device_type type)
142 case CONNMAN_DEVICE_TYPE_UNKNOWN:
143 case CONNMAN_DEVICE_TYPE_VENDOR:
145 case CONNMAN_DEVICE_TYPE_ETHERNET:
147 case CONNMAN_DEVICE_TYPE_WIFI:
149 case CONNMAN_DEVICE_TYPE_WIMAX:
151 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
153 case CONNMAN_DEVICE_TYPE_GPS:
155 case CONNMAN_DEVICE_TYPE_CELLULAR:
157 case CONNMAN_DEVICE_TYPE_GADGET:
165 static const char *type2string(enum connman_device_type type)
168 case CONNMAN_DEVICE_TYPE_UNKNOWN:
169 case CONNMAN_DEVICE_TYPE_VENDOR:
171 case CONNMAN_DEVICE_TYPE_ETHERNET:
173 case CONNMAN_DEVICE_TYPE_WIFI:
175 case CONNMAN_DEVICE_TYPE_WIMAX:
177 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
179 case CONNMAN_DEVICE_TYPE_GPS:
181 case CONNMAN_DEVICE_TYPE_CELLULAR:
183 case CONNMAN_DEVICE_TYPE_GADGET:
191 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
193 enum connman_device_type type = connman_device_get_type(device);
196 case CONNMAN_DEVICE_TYPE_UNKNOWN:
197 case CONNMAN_DEVICE_TYPE_VENDOR:
198 case CONNMAN_DEVICE_TYPE_GPS:
200 case CONNMAN_DEVICE_TYPE_ETHERNET:
201 return CONNMAN_SERVICE_TYPE_ETHERNET;
202 case CONNMAN_DEVICE_TYPE_WIFI:
203 return CONNMAN_SERVICE_TYPE_WIFI;
204 case CONNMAN_DEVICE_TYPE_WIMAX:
205 return CONNMAN_SERVICE_TYPE_WIMAX;
206 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
207 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
208 case CONNMAN_DEVICE_TYPE_CELLULAR:
209 return CONNMAN_SERVICE_TYPE_CELLULAR;
210 case CONNMAN_DEVICE_TYPE_GADGET:
211 return CONNMAN_SERVICE_TYPE_GADGET;
215 return CONNMAN_SERVICE_TYPE_UNKNOWN;
218 static gboolean device_pending_reset(gpointer user_data)
220 struct connman_device *device = user_data;
222 DBG("device %p", device);
224 /* Power request timedout, reset power pending state. */
225 if (device->pending_timeout > 0) {
226 g_source_remove(device->pending_timeout);
227 device->pending_timeout = 0;
228 device->powered_pending = PENDING_NONE;
234 int __connman_device_enable(struct connman_device *device)
238 DBG("device %p", device);
240 if (!device->driver || !device->driver->enable)
243 /* There is an ongoing power disable request. */
244 if (device->powered_pending == PENDING_DISABLE)
247 if (device->powered_pending == PENDING_ENABLE)
250 if (device->powered_pending == PENDING_NONE && device->powered == TRUE)
253 device->powered_pending = PENDING_ENABLE;
255 err = device->driver->enable(device);
257 * device gets enabled right away.
258 * Invoke the callback
261 connman_device_set_powered(device, TRUE);
265 if (err == -EALREADY) {
266 /* If device is already powered, but connman is not updated */
267 connman_device_set_powered(device, TRUE);
271 * if err == -EINPROGRESS, then the DBus call to the respective daemon
272 * was successful. We set a 4 sec timeout so if the daemon never
273 * returns a reply, we would reset the pending request.
275 if (err == -EINPROGRESS)
276 device->pending_timeout = g_timeout_add_seconds(4,
277 device_pending_reset, device);
282 int __connman_device_disable(struct connman_device *device)
286 DBG("device %p", device);
288 if (!device->driver || !device->driver->disable)
291 /* Ongoing power enable request */
292 if (device->powered_pending == PENDING_ENABLE)
295 if (device->powered_pending == PENDING_DISABLE)
298 if (device->powered_pending == PENDING_NONE && device->powered == FALSE)
301 device->reconnect = FALSE;
303 clear_scan_trigger(device);
305 err = device->driver->disable(device);
307 connman_device_set_powered(device, FALSE);
311 if (err == -EALREADY) {
312 connman_device_set_powered(device, FALSE);
316 if (err == -EINPROGRESS)
317 device->pending_timeout = g_timeout_add_seconds(4,
318 device_pending_reset, device);
323 static void probe_driver(struct connman_device_driver *driver)
327 DBG("driver %p name %s", driver, driver->name);
329 for (list = device_list; list != NULL; list = list->next) {
330 struct connman_device *device = list->data;
332 if (device->driver != NULL)
335 if (driver->type != device->type)
338 if (driver->probe(device) < 0)
341 device->driver = driver;
343 __connman_technology_add_device(device);
347 static void remove_device(struct connman_device *device)
349 DBG("device %p", device);
351 __connman_device_disable(device);
353 __connman_technology_remove_device(device);
355 if (device->driver->remove)
356 device->driver->remove(device);
358 device->driver = NULL;
361 static void remove_driver(struct connman_device_driver *driver)
365 DBG("driver %p name %s", driver, driver->name);
367 for (list = device_list; list != NULL; list = list->next) {
368 struct connman_device *device = list->data;
370 if (device->driver == driver)
371 remove_device(device);
375 connman_bool_t __connman_device_has_driver(struct connman_device *device)
377 if (device == NULL || device->driver == NULL)
383 static GSList *driver_list = NULL;
385 static gint compare_priority(gconstpointer a, gconstpointer b)
387 const struct connman_device_driver *driver1 = a;
388 const struct connman_device_driver *driver2 = b;
390 return driver2->priority - driver1->priority;
394 * connman_device_driver_register:
395 * @driver: device driver definition
397 * Register a new device driver
399 * Returns: %0 on success
401 int connman_device_driver_register(struct connman_device_driver *driver)
403 DBG("driver %p name %s", driver, driver->name);
405 driver_list = g_slist_insert_sorted(driver_list, driver,
407 probe_driver(driver);
413 * connman_device_driver_unregister:
414 * @driver: device driver definition
416 * Remove a previously registered device driver
418 void connman_device_driver_unregister(struct connman_device_driver *driver)
420 DBG("driver %p name %s", driver, driver->name);
422 driver_list = g_slist_remove(driver_list, driver);
424 remove_driver(driver);
427 static void free_network(gpointer data)
429 struct connman_network *network = data;
431 DBG("network %p", network);
433 __connman_network_set_device(network, NULL);
435 connman_network_unref(network);
438 static void device_destruct(struct connman_device *device)
440 DBG("device %p name %s", device, device->name);
442 clear_scan_trigger(device);
444 g_free(device->ident);
445 g_free(device->node);
446 g_free(device->name);
447 g_free(device->address);
448 g_free(device->interface);
449 g_free(device->path);
450 g_free(device->devname);
452 g_free(device->last_network);
454 g_hash_table_destroy(device->networks);
455 device->networks = NULL;
461 * connman_device_create:
462 * @node: device node name (for example an address)
465 * Allocate a new device of given #type and assign the #node name to it.
467 * Returns: a newly-allocated #connman_device structure
469 struct connman_device *connman_device_create(const char *node,
470 enum connman_device_type type)
472 struct connman_device *device;
473 connman_bool_t bg_scan;
475 DBG("node %s type %d", node, type);
477 device = g_try_new0(struct connman_device, 1);
481 DBG("device %p", device);
483 device->refcount = 1;
485 bg_scan = connman_setting_get_bool("BackgroundScanning");
488 device->name = g_strdup(type2description(device->type));
490 device->powered_persistent = TRUE;
492 device->phyindex = -1;
494 device->backoff_interval = SCAN_INITIAL_DELAY;
497 case CONNMAN_DEVICE_TYPE_UNKNOWN:
498 case CONNMAN_DEVICE_TYPE_ETHERNET:
499 case CONNMAN_DEVICE_TYPE_WIMAX:
500 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
501 case CONNMAN_DEVICE_TYPE_CELLULAR:
502 case CONNMAN_DEVICE_TYPE_GPS:
503 case CONNMAN_DEVICE_TYPE_GADGET:
504 case CONNMAN_DEVICE_TYPE_VENDOR:
505 device->scan_interval = 0;
507 case CONNMAN_DEVICE_TYPE_WIFI:
509 device->scan_interval = 300;
511 device->scan_interval = 0;
515 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
516 g_free, free_network);
518 device_list = g_slist_append(device_list, device);
524 * connman_device_ref:
525 * @device: device structure
527 * Increase reference counter of device
529 struct connman_device *connman_device_ref(struct connman_device *device)
533 g_atomic_int_inc(&device->refcount);
539 * connman_device_unref:
540 * @device: device structure
542 * Decrease reference counter of device
544 void connman_device_unref(struct connman_device *device)
546 if (g_atomic_int_dec_and_test(&device->refcount) == FALSE)
549 if (device->driver) {
550 device->driver->remove(device);
551 device->driver = NULL;
554 device_list = g_slist_remove(device_list, device);
556 device_destruct(device);
559 const char *__connman_device_get_type(struct connman_device *device)
561 return type2string(device->type);
565 * connman_device_get_type:
566 * @device: device structure
570 enum connman_device_type connman_device_get_type(struct connman_device *device)
576 * connman_device_set_index:
577 * @device: device structure
578 * @index: index number
580 * Set index number of device
582 void connman_device_set_index(struct connman_device *device, int index)
584 device->index = index;
588 * connman_device_get_index:
589 * @device: device structure
591 * Get index number of device
593 int connman_device_get_index(struct connman_device *device)
595 return device->index;
598 int __connman_device_get_phyindex(struct connman_device *device)
600 return device->phyindex;
603 void __connman_device_set_phyindex(struct connman_device *device,
606 device->phyindex = phyindex;
610 * connman_device_set_interface:
611 * @device: device structure
612 * @interface: interface name
614 * Set interface name of device
616 void connman_device_set_interface(struct connman_device *device,
617 const char *interface)
619 g_free(device->devname);
620 device->devname = g_strdup(interface);
622 g_free(device->interface);
623 device->interface = g_strdup(interface);
625 if (device->name == NULL) {
626 const char *str = type2description(device->type);
627 if (str != NULL && device->interface != NULL)
628 device->name = g_strdup_printf("%s (%s)", str,
634 * connman_device_set_ident:
635 * @device: device structure
636 * @ident: unique identifier
638 * Set unique identifier of device
640 void connman_device_set_ident(struct connman_device *device,
643 g_free(device->ident);
644 device->ident = g_strdup(ident);
647 const char *connman_device_get_ident(struct connman_device *device)
649 return device->ident;
653 * connman_device_set_powered:
654 * @device: device structure
655 * @powered: powered state
657 * Change power state of device
659 int connman_device_set_powered(struct connman_device *device,
660 connman_bool_t powered)
662 enum connman_service_type type;
664 DBG("driver %p powered %d", device, powered);
666 if (device->powered == powered)
669 /* Reset pending request */
670 g_source_remove(device->pending_timeout);
671 device->pending_timeout = 0;
672 device->powered_pending = PENDING_NONE;
674 device->powered = powered;
676 type = __connman_device_get_service_type(device);
678 if (device->powered == TRUE)
679 __connman_technology_enabled(type);
681 __connman_technology_disabled(type);
683 if (powered == FALSE) {
684 device->connections = 0;
688 connman_device_set_disconnected(device, FALSE);
689 device->scanning = FALSE;
691 reset_scan_trigger(device);
693 if (device->driver && device->driver->scan)
694 device->driver->scan(device);
699 static int device_scan(struct connman_device *device)
701 if (!device->driver || !device->driver->scan)
704 if (device->powered == FALSE)
707 reset_scan_trigger(device);
709 return device->driver->scan(device);
712 int __connman_device_enable_persistent(struct connman_device *device)
714 DBG("device %p", device);
716 device->powered_persistent = TRUE;
718 __connman_storage_save_device(device);
720 return __connman_device_enable(device);
723 int __connman_device_disable_persistent(struct connman_device *device)
725 DBG("device %p", device);
727 device->powered_persistent = FALSE;
729 __connman_storage_save_device(device);
731 return __connman_device_disable(device);
734 int __connman_device_disconnect(struct connman_device *device)
739 DBG("device %p", device);
741 connman_device_set_disconnected(device, TRUE);
743 g_hash_table_iter_init(&iter, device->networks);
745 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
746 struct connman_network *network = value;
748 if (connman_network_get_connecting(network) == TRUE) {
750 * Skip network in the process of connecting.
751 * This is a workaround for WiFi networks serviced
752 * by the supplicant plugin that hold a reference
753 * to the network. If we disconnect the network
754 * here then the referenced object will not be
755 * registered and usage (like launching DHCP client)
756 * will fail. There is nothing to be gained by
757 * removing the network here anyway.
759 connman_warn("Skipping disconnect of %s, network is connecting.",
760 connman_network_get_identifier(network));
764 __connman_network_disconnect(network);
770 static void mark_network_available(gpointer key, gpointer value,
773 struct connman_network *network = value;
775 connman_network_set_available(network, TRUE);
778 static void mark_network_unavailable(gpointer key, gpointer value,
781 struct connman_network *network = value;
783 if (connman_network_get_connected(network) == TRUE)
786 connman_network_set_available(network, FALSE);
789 static gboolean remove_unavailable_network(gpointer key, gpointer value,
792 struct connman_network *network = value;
794 if (connman_network_get_connected(network) == TRUE)
797 if (connman_network_get_available(network) == TRUE)
803 void __connman_device_cleanup_networks(struct connman_device *device)
805 g_hash_table_foreach_remove(device->networks,
806 remove_unavailable_network, NULL);
809 connman_bool_t __connman_device_scanning(struct connman_device *device)
811 return device->scanning;
814 void connman_device_reset_scanning(struct connman_device *device)
816 device->scanning = FALSE;
818 g_hash_table_foreach(device->networks,
819 mark_network_available, NULL);
824 * connman_device_set_scanning:
825 * @device: device structure
826 * @scanning: scanning state
828 * Change scanning state of device
830 int connman_device_set_scanning(struct connman_device *device,
831 connman_bool_t scanning)
833 DBG("device %p scanning %d", device, scanning);
835 if (!device->driver || !device->driver->scan)
838 if (device->scanning == scanning)
841 device->scanning = scanning;
843 if (scanning == TRUE) {
844 reset_scan_trigger(device);
846 g_hash_table_foreach(device->networks,
847 mark_network_unavailable, NULL);
852 __connman_device_cleanup_networks(device);
854 if (device->connections > 0)
857 __connman_service_auto_connect();
863 * connman_device_set_disconnected:
864 * @device: device structure
865 * @disconnected: disconnected state
867 * Change disconnected state of device (only for device with networks)
869 int connman_device_set_disconnected(struct connman_device *device,
870 connman_bool_t disconnected)
872 DBG("device %p disconnected %d", device, disconnected);
874 if (device->disconnected == disconnected)
877 device->disconnected = disconnected;
879 if (disconnected == TRUE)
880 force_scan_trigger(device);
886 * connman_device_get_disconnected:
887 * @device: device structure
889 * Get device disconnected state
891 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
893 return device->disconnected;
897 * connman_device_set_string:
898 * @device: device structure
899 * @key: unique identifier
900 * @value: string value
902 * Set string value for specific key
904 int connman_device_set_string(struct connman_device *device,
905 const char *key, const char *value)
907 DBG("device %p key %s value %s", device, key, value);
909 if (g_str_equal(key, "Address") == TRUE) {
910 g_free(device->address);
911 device->address = g_strdup(value);
912 } else if (g_str_equal(key, "Name") == TRUE) {
913 g_free(device->name);
914 device->name = g_strdup(value);
915 } else if (g_str_equal(key, "Node") == TRUE) {
916 g_free(device->node);
917 device->node = g_strdup(value);
918 } else if (g_str_equal(key, "Path") == TRUE) {
919 g_free(device->path);
920 device->path = g_strdup(value);
929 * connman_device_get_string:
930 * @device: device structure
931 * @key: unique identifier
933 * Get string value for specific key
935 const char *connman_device_get_string(struct connman_device *device,
938 DBG("device %p key %s", device, key);
940 if (g_str_equal(key, "Address") == TRUE)
941 return device->address;
942 else if (g_str_equal(key, "Name") == TRUE)
944 else if (g_str_equal(key, "Node") == TRUE)
946 else if (g_str_equal(key, "Interface") == TRUE)
947 return device->interface;
948 else if (g_str_equal(key, "Path") == TRUE)
954 void __connman_device_increase_connections(struct connman_device *device)
959 device->connections++;
962 void __connman_device_decrease_connections(struct connman_device *device)
967 device->connections--;
969 if (device->connections == 0)
970 device->backoff_interval = SCAN_INITIAL_DELAY;
974 * connman_device_add_network:
975 * @device: device structure
976 * @network: network structure
978 * Add new network to the device
980 int connman_device_add_network(struct connman_device *device,
981 struct connman_network *network)
983 const char *identifier = connman_network_get_identifier(network);
985 DBG("device %p network %p", device, network);
987 if (identifier == NULL)
990 connman_network_ref(network);
992 __connman_network_set_device(network, device);
994 g_hash_table_insert(device->networks, g_strdup(identifier),
1001 * connman_device_get_network:
1002 * @device: device structure
1003 * @identifier: network identifier
1005 * Get network for given identifier
1007 struct connman_network *connman_device_get_network(struct connman_device *device,
1008 const char *identifier)
1010 DBG("device %p identifier %s", device, identifier);
1012 return g_hash_table_lookup(device->networks, identifier);
1016 * connman_device_remove_network:
1017 * @device: device structure
1018 * @identifier: network identifier
1020 * Remove network for given identifier
1022 int connman_device_remove_network(struct connman_device *device,
1023 struct connman_network *network)
1025 const char *identifier;
1027 DBG("device %p network %p", device, network);
1029 if (network == NULL)
1032 identifier = connman_network_get_identifier(network);
1033 g_hash_table_remove(device->networks, identifier);
1038 void connman_device_remove_all_networks(struct connman_device *device)
1040 g_hash_table_remove_all(device->networks);
1043 void __connman_device_set_network(struct connman_device *device,
1044 struct connman_network *network)
1051 if (device->network == network)
1054 if (network != NULL) {
1055 name = connman_network_get_string(network, "Name");
1056 g_free(device->last_network);
1057 device->last_network = g_strdup(name);
1059 device->network = network;
1061 g_free(device->last_network);
1062 device->last_network = NULL;
1064 device->network = NULL;
1068 void __connman_device_set_reconnect(struct connman_device *device,
1069 connman_bool_t reconnect)
1071 device->reconnect = reconnect;
1074 connman_bool_t __connman_device_get_reconnect(
1075 struct connman_device *device)
1077 return device->reconnect;
1080 static gboolean match_driver(struct connman_device *device,
1081 struct connman_device_driver *driver)
1083 if (device->type == driver->type ||
1084 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1090 static int device_probe(struct connman_device *device)
1094 DBG("device %p name %s", device, device->name);
1096 if (device->driver != NULL)
1099 for (list = driver_list; list; list = list->next) {
1100 struct connman_device_driver *driver = list->data;
1102 if (match_driver(device, driver) == FALSE)
1105 DBG("driver %p name %s", driver, driver->name);
1107 if (driver->probe(device) == 0) {
1108 device->driver = driver;
1113 if (device->driver == NULL)
1116 return __connman_technology_add_device(device);
1119 static void device_remove(struct connman_device *device)
1121 DBG("device %p name %s", device, device->name);
1123 if (device->driver == NULL)
1126 remove_device(device);
1130 * connman_device_register:
1131 * @device: device structure
1133 * Register device with the system
1135 int connman_device_register(struct connman_device *device)
1137 __connman_storage_load_device(device);
1139 return device_probe(device);
1143 * connman_device_unregister:
1144 * @device: device structure
1146 * Unregister device with the system
1148 void connman_device_unregister(struct connman_device *device)
1150 __connman_storage_save_device(device);
1152 device_remove(device);
1156 * connman_device_get_data:
1157 * @device: device structure
1159 * Get private device data pointer
1161 void *connman_device_get_data(struct connman_device *device)
1163 return device->driver_data;
1167 * connman_device_set_data:
1168 * @device: device structure
1169 * @data: data pointer
1171 * Set private device data pointer
1173 void connman_device_set_data(struct connman_device *device, void *data)
1175 device->driver_data = data;
1178 struct connman_device *__connman_device_find_device(
1179 enum connman_service_type type)
1183 for (list = device_list; list != NULL; list = list->next) {
1184 struct connman_device *device = list->data;
1185 enum connman_service_type service_type =
1186 __connman_device_get_service_type(device);
1188 if (service_type != type)
1197 int __connman_device_request_scan(enum connman_service_type type)
1203 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1204 case CONNMAN_SERVICE_TYPE_SYSTEM:
1205 case CONNMAN_SERVICE_TYPE_ETHERNET:
1206 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1207 case CONNMAN_SERVICE_TYPE_CELLULAR:
1208 case CONNMAN_SERVICE_TYPE_GPS:
1209 case CONNMAN_SERVICE_TYPE_VPN:
1210 case CONNMAN_SERVICE_TYPE_GADGET:
1212 case CONNMAN_SERVICE_TYPE_WIFI:
1213 case CONNMAN_SERVICE_TYPE_WIMAX:
1217 for (list = device_list; list != NULL; list = list->next) {
1218 struct connman_device *device = list->data;
1219 enum connman_service_type service_type =
1220 __connman_device_get_service_type(device);
1222 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN &&
1223 service_type != type) {
1227 err = device_scan(device);
1228 if (err < 0 && err != -EINPROGRESS) {
1230 /* XXX maybe only a continue? */
1238 connman_bool_t __connman_device_isfiltered(const char *devname)
1242 if (device_filter == NULL)
1245 for (pattern = device_filter; *pattern; pattern++) {
1246 if (g_pattern_match_simple(*pattern, devname) == FALSE) {
1247 DBG("ignoring device %s (match)", devname);
1253 if (g_pattern_match_simple("dummy*", devname) == TRUE) {
1254 DBG("ignoring dummy networking devices");
1258 if (nodevice_filter == NULL)
1261 for (pattern = nodevice_filter; *pattern; pattern++) {
1262 if (g_pattern_match_simple(*pattern, devname) == TRUE) {
1263 DBG("ignoring device %s (no match)", devname);
1271 static int device_load(struct connman_device *device)
1273 const char *ident = __connman_profile_active_ident();
1275 GError *error = NULL;
1277 connman_bool_t powered;
1279 DBG("device %p", device);
1281 keyfile = __connman_storage_open_profile(ident);
1282 if (keyfile == NULL)
1285 identifier = g_strdup_printf("device_%s", device->name);
1286 if (identifier == NULL)
1289 powered = g_key_file_get_boolean(keyfile, identifier,
1292 device->powered_persistent = powered;
1293 g_clear_error(&error);
1298 __connman_storage_close_profile(ident, keyfile, FALSE);
1303 static int device_save(struct connman_device *device)
1305 const char *ident = __connman_profile_active_ident();
1309 DBG("device %p", device);
1311 keyfile = __connman_storage_open_profile(ident);
1312 if (keyfile == NULL)
1315 identifier = g_strdup_printf("device_%s", device->name);
1316 if (identifier == NULL)
1319 g_key_file_set_boolean(keyfile, identifier,
1320 "Powered", device->powered_persistent);
1325 __connman_storage_close_profile(ident, keyfile, TRUE);
1330 static struct connman_storage device_storage = {
1332 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
1333 .device_load = device_load,
1334 .device_save = device_save,
1337 int __connman_device_init(const char *device, const char *nodevice)
1342 device_filter = g_strsplit(device, ",", -1);
1344 if (nodevice != NULL)
1345 nodevice_filter = g_strsplit(nodevice, ",", -1);
1347 return connman_storage_register(&device_storage);
1350 void __connman_device_cleanup(void)
1354 g_strfreev(nodevice_filter);
1355 g_strfreev(device_filter);
1357 connman_storage_unregister(&device_storage);