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_pending;
44 connman_bool_t powered_persistent;
45 connman_bool_t carrier;
46 connman_bool_t scanning;
47 connman_bool_t disconnected;
48 connman_bool_t reconnect;
49 connman_uint16_t scan_interval;
57 unsigned int connections;
59 struct connman_ipconfig *ipconfig;
61 struct connman_device_driver *driver;
64 connman_bool_t registered;
67 struct connman_network *network;
74 static gboolean device_scan_trigger(gpointer user_data)
76 struct connman_device *device = user_data;
78 DBG("device %p", device);
80 if (device->driver == NULL) {
81 device->scan_timeout = 0;
85 if (device->driver->scan)
86 device->driver->scan(device);
91 static void clear_scan_trigger(struct connman_device *device)
93 if (device->scan_timeout > 0) {
94 g_source_remove(device->scan_timeout);
95 device->scan_timeout = 0;
99 static void reset_scan_trigger(struct connman_device *device)
101 clear_scan_trigger(device);
103 if (device->scan_interval > 0) {
104 guint interval = device->scan_interval;
105 device->scan_timeout = g_timeout_add_seconds(interval,
106 device_scan_trigger, device);
110 static void force_scan_trigger(struct connman_device *device)
112 clear_scan_trigger(device);
114 device->scan_timeout = g_timeout_add_seconds(5,
115 device_scan_trigger, device);
118 void connman_device_schedule_scan(struct connman_device *device)
120 reset_scan_trigger(device);
123 static const char *type2description(enum connman_device_type type)
126 case CONNMAN_DEVICE_TYPE_UNKNOWN:
127 case CONNMAN_DEVICE_TYPE_VENDOR:
129 case CONNMAN_DEVICE_TYPE_ETHERNET:
131 case CONNMAN_DEVICE_TYPE_WIFI:
133 case CONNMAN_DEVICE_TYPE_WIMAX:
135 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
137 case CONNMAN_DEVICE_TYPE_GPS:
139 case CONNMAN_DEVICE_TYPE_MBM:
140 case CONNMAN_DEVICE_TYPE_CELLULAR:
141 case CONNMAN_DEVICE_TYPE_HSO:
142 case CONNMAN_DEVICE_TYPE_NOZOMI:
143 case CONNMAN_DEVICE_TYPE_HUAWEI:
144 case CONNMAN_DEVICE_TYPE_NOVATEL:
151 static const char *type2string(enum connman_device_type type)
154 case CONNMAN_DEVICE_TYPE_UNKNOWN:
155 case CONNMAN_DEVICE_TYPE_VENDOR:
157 case CONNMAN_DEVICE_TYPE_ETHERNET:
159 case CONNMAN_DEVICE_TYPE_WIFI:
161 case CONNMAN_DEVICE_TYPE_WIMAX:
163 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
165 case CONNMAN_DEVICE_TYPE_GPS:
167 case CONNMAN_DEVICE_TYPE_MBM:
168 case CONNMAN_DEVICE_TYPE_CELLULAR:
169 case CONNMAN_DEVICE_TYPE_HSO:
170 case CONNMAN_DEVICE_TYPE_HUAWEI:
171 case CONNMAN_DEVICE_TYPE_NOZOMI:
172 case CONNMAN_DEVICE_TYPE_NOVATEL:
179 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
181 enum connman_device_type type = connman_device_get_type(device);
184 case CONNMAN_DEVICE_TYPE_UNKNOWN:
185 case CONNMAN_DEVICE_TYPE_VENDOR:
186 case CONNMAN_DEVICE_TYPE_GPS:
187 case CONNMAN_DEVICE_TYPE_NOZOMI:
188 case CONNMAN_DEVICE_TYPE_HUAWEI:
189 case CONNMAN_DEVICE_TYPE_NOVATEL:
191 case CONNMAN_DEVICE_TYPE_ETHERNET:
192 return CONNMAN_SERVICE_TYPE_ETHERNET;
193 case CONNMAN_DEVICE_TYPE_WIFI:
194 return CONNMAN_SERVICE_TYPE_WIFI;
195 case CONNMAN_DEVICE_TYPE_WIMAX:
196 return CONNMAN_SERVICE_TYPE_WIMAX;
197 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
198 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
199 case CONNMAN_DEVICE_TYPE_MBM:
200 case CONNMAN_DEVICE_TYPE_CELLULAR:
201 case CONNMAN_DEVICE_TYPE_HSO:
202 return CONNMAN_SERVICE_TYPE_CELLULAR;
205 return CONNMAN_SERVICE_TYPE_UNKNOWN;
208 static int set_connected(struct connman_device *device,
209 connman_bool_t connected)
211 if (connected == TRUE) {
212 enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
213 struct connman_element *element;
215 device->disconnected = TRUE;
217 switch (device->element.ipv4.method) {
218 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
219 case CONNMAN_IPCONFIG_METHOD_IGNORE:
221 case CONNMAN_IPCONFIG_METHOD_STATIC:
222 type = CONNMAN_ELEMENT_TYPE_IPV4;
224 case CONNMAN_IPCONFIG_METHOD_DHCP:
225 type = CONNMAN_ELEMENT_TYPE_DHCP;
229 element = connman_element_create(NULL);
230 if (element != NULL) {
231 struct connman_service *service;
233 element->type = type;
234 element->index = device->element.index;
236 if (connman_element_register(element,
237 &device->element) < 0)
238 connman_element_unref(element);
240 device->disconnected = FALSE;
242 service = __connman_service_lookup_from_device(device);
243 __connman_service_indicate_state(service,
244 CONNMAN_SERVICE_STATE_CONFIGURATION);
247 struct connman_service *service;
249 connman_element_unregister_children(&device->element);
251 device->disconnected = TRUE;
253 service = __connman_service_lookup_from_device(device);
254 __connman_service_indicate_state(service,
255 CONNMAN_SERVICE_STATE_IDLE);
258 if (connected == TRUE) {
259 enum connman_service_type type;
261 type = __connman_device_get_service_type(device);
262 __connman_notifier_connect(type);
264 enum connman_service_type type;
266 type = __connman_device_get_service_type(device);
267 __connman_notifier_disconnect(type);
273 static int set_carrier(struct connman_device *device, connman_bool_t carrier)
276 __connman_profile_add_device(device);
278 __connman_profile_remove_device(device);
280 return set_connected(device, carrier);
283 static int powered_changed(struct connman_device *device)
286 DBusMessageIter entry, value;
287 const char *key = "Powered";
289 signal = dbus_message_new_signal(device->element.path,
290 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
294 dbus_message_iter_init_append(signal, &entry);
296 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
298 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
299 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
300 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
302 dbus_message_iter_close_container(&entry, &value);
304 g_dbus_send_message(connection, signal);
309 static int set_powered(struct connman_device *device, connman_bool_t powered)
311 struct connman_device_driver *driver = device->driver;
312 enum connman_service_type type;
315 DBG("device %p powered %d", device, powered);
317 if (device->powered_pending == powered)
323 type = __connman_device_get_service_type(device);
325 if (powered == TRUE) {
326 if (driver->enable) {
327 device->powered_pending = powered;
329 err = driver->enable(device);
331 __connman_notifier_enable(type);
335 device->powered_pending = powered;
337 device->reconnect = FALSE;
339 clear_scan_trigger(device);
341 g_hash_table_remove_all(device->networks);
343 set_carrier(device, FALSE);
345 if (driver->disable) {
346 err = driver->disable(device);
348 __connman_notifier_disable(type);
354 device->powered = powered;
356 if (device->registered == TRUE)
357 powered_changed(device);
363 static void append_path(gpointer key, gpointer value, gpointer user_data)
365 struct connman_element *element = value;
366 DBusMessageIter *iter = user_data;
368 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
372 static void append_networks(struct connman_device *device,
373 DBusMessageIter *entry)
375 DBusMessageIter value, iter;
376 const char *key = "Networks";
378 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
380 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
381 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
384 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
385 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
386 g_hash_table_foreach(device->networks, append_path, &iter);
387 dbus_message_iter_close_container(&value, &iter);
389 dbus_message_iter_close_container(entry, &value);
392 static DBusMessage *get_properties(DBusConnection *conn,
393 DBusMessage *msg, void *data)
395 struct connman_device *device = data;
397 DBusMessageIter array, dict, entry;
400 DBG("conn %p", conn);
402 if (__connman_security_check_privilege(msg,
403 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
404 return __connman_error_permission_denied(msg);
406 reply = dbus_message_new_method_return(msg);
410 dbus_message_iter_init_append(reply, &array);
412 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
413 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
414 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
415 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
417 if (device->name != NULL)
418 connman_dbus_dict_append_variant(&dict, "Name",
419 DBUS_TYPE_STRING, &device->name);
421 str = type2string(device->type);
423 connman_dbus_dict_append_variant(&dict, "Type",
424 DBUS_TYPE_STRING, &str);
426 if (device->address != NULL)
427 connman_dbus_dict_append_variant(&dict, "Address",
428 DBUS_TYPE_STRING, &device->address);
430 if (device->interface != NULL)
431 connman_dbus_dict_append_variant(&dict, "Interface",
432 DBUS_TYPE_STRING, &device->interface);
434 connman_dbus_dict_append_variant(&dict, "Powered",
435 DBUS_TYPE_BOOLEAN, &device->powered);
437 if (device->driver && device->driver->scan)
438 connman_dbus_dict_append_variant(&dict, "Scanning",
439 DBUS_TYPE_BOOLEAN, &device->scanning);
441 switch (device->mode) {
442 case CONNMAN_DEVICE_MODE_UNKNOWN:
444 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
445 __connman_element_append_ipv4(&device->element, &dict);
447 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
448 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
449 if (device->scan_interval > 0)
450 connman_dbus_dict_append_variant(&dict, "ScanInterval",
451 DBUS_TYPE_UINT16, &device->scan_interval);
453 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
455 append_networks(device, &entry);
456 dbus_message_iter_close_container(&dict, &entry);
460 dbus_message_iter_close_container(&array, &dict);
465 static gboolean powered_timeout(gpointer user_data)
467 struct connman_device *device = user_data;
469 DBG("device %p", device);
473 if (device->pending != NULL) {
476 reply = __connman_error_operation_timeout(device->pending);
478 g_dbus_send_message(connection, reply);
480 dbus_message_unref(device->pending);
481 device->pending = NULL;
487 static DBusMessage *set_property(DBusConnection *conn,
488 DBusMessage *msg, void *data)
490 struct connman_device *device = data;
491 DBusMessageIter iter, value;
495 DBG("conn %p", conn);
497 if (dbus_message_iter_init(msg, &iter) == FALSE)
498 return __connman_error_invalid_arguments(msg);
500 dbus_message_iter_get_basic(&iter, &name);
501 dbus_message_iter_next(&iter);
502 dbus_message_iter_recurse(&iter, &value);
504 if (__connman_security_check_privilege(msg,
505 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
506 return __connman_error_permission_denied(msg);
508 type = dbus_message_iter_get_arg_type(&value);
510 if (g_str_equal(name, "Powered") == TRUE) {
511 connman_bool_t powered;
514 if (type != DBUS_TYPE_BOOLEAN)
515 return __connman_error_invalid_arguments(msg);
517 dbus_message_iter_get_basic(&value, &powered);
519 device->powered_persistent = powered;
521 __connman_storage_save_device(device);
523 if (device->powered == powered)
524 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
526 if (device->pending != NULL)
527 return __connman_error_in_progress(msg);
529 err = set_powered(device, powered);
531 if (err != -EINPROGRESS)
532 return __connman_error_failed(msg, -err);
534 device->pending = dbus_message_ref(msg);
536 device->timeout = g_timeout_add_seconds(15,
537 powered_timeout, device);
541 } else if (g_str_equal(name, "ScanInterval") == TRUE) {
542 connman_uint16_t interval;
544 switch (device->mode) {
545 case CONNMAN_DEVICE_MODE_UNKNOWN:
546 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
547 return __connman_error_invalid_arguments(msg);
548 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
549 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
553 if (type != DBUS_TYPE_UINT16)
554 return __connman_error_invalid_arguments(msg);
556 dbus_message_iter_get_basic(&value, &interval);
558 if (device->scan_interval != interval) {
559 device->scan_interval = interval;
561 __connman_storage_save_device(device);
563 reset_scan_trigger(device);
565 } else if (g_str_has_prefix(name, "IPv4.") == TRUE) {
568 if (device->ipconfig == NULL)
569 return __connman_error_invalid_property(msg);
571 switch (device->mode) {
572 case CONNMAN_DEVICE_MODE_UNKNOWN:
573 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
574 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
575 return __connman_error_invalid_arguments(msg);
576 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
580 err = __connman_ipconfig_set_ipv4(device->ipconfig,
583 return __connman_error_failed(msg, -err);
585 return __connman_error_invalid_property(msg);
587 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
590 static DBusMessage *propose_scan(DBusConnection *conn,
591 DBusMessage *msg, void *data)
593 struct connman_device *device = data;
596 DBG("conn %p", conn);
598 switch (device->mode) {
599 case CONNMAN_DEVICE_MODE_UNKNOWN:
600 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
601 return __connman_error_not_supported(msg);
602 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
603 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
607 err = __connman_device_scan(device);
609 return __connman_error_failed(msg, -err);
611 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
614 static GDBusMethodTable device_methods[] = {
615 { "GetProperties", "", "a{sv}", get_properties },
616 { "SetProperty", "sv", "", set_property,
617 G_DBUS_METHOD_FLAG_ASYNC },
618 { "ProposeScan", "", "", propose_scan },
622 static GDBusSignalTable device_signals[] = {
623 { "PropertyChanged", "sv" },
627 static void append_devices(DBusMessageIter *entry)
629 DBusMessageIter value, iter;
630 const char *key = "Devices";
632 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
634 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
635 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
638 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
639 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
640 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
641 dbus_message_iter_close_container(&value, &iter);
643 dbus_message_iter_close_container(entry, &value);
646 static void emit_devices_signal(void)
649 DBusMessageIter entry;
651 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
652 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
656 dbus_message_iter_init_append(signal, &entry);
658 append_devices(&entry);
660 g_dbus_send_message(connection, signal);
663 static int register_interface(struct connman_element *element)
665 struct connman_device *device = element->device;
667 DBG("element %p name %s", element, element->name);
669 if (g_dbus_register_interface(connection, element->path,
670 CONNMAN_DEVICE_INTERFACE,
671 device_methods, device_signals,
672 NULL, device, NULL) == FALSE) {
673 connman_error("Failed to register %s device", element->path);
677 device->registered = TRUE;
679 emit_devices_signal();
684 static void unregister_interface(struct connman_element *element)
686 struct connman_device *device = element->device;
688 DBG("element %p name %s", element, element->name);
690 device->registered = FALSE;
692 emit_devices_signal();
694 g_dbus_unregister_interface(connection, element->path,
695 CONNMAN_DEVICE_INTERFACE);
698 static int setup_device(struct connman_device *device)
700 enum connman_service_type type;
703 DBG("device %p", device);
705 err = register_interface(&device->element);
707 if (device->driver->remove)
708 device->driver->remove(device);
709 device->driver = NULL;
713 type = __connman_device_get_service_type(device);
714 __connman_notifier_register(type);
716 switch (device->mode) {
717 case CONNMAN_DEVICE_MODE_UNKNOWN:
718 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
719 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
721 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
722 if (device->carrier == TRUE && device->secondary == FALSE)
723 __connman_profile_add_device(device);
727 if (device->offlinemode == FALSE &&
728 device->powered_persistent == TRUE)
729 __connman_device_enable(device);
734 static void probe_driver(struct connman_element *element, gpointer user_data)
736 struct connman_device_driver *driver = user_data;
738 DBG("element %p name %s", element, element->name);
740 if (element->device == NULL)
743 if (element->device->driver != NULL)
746 if (driver->type != element->device->type)
749 if (driver->probe(element->device) < 0)
752 element->device->driver = driver;
754 setup_device(element->device);
757 static void remove_device(struct connman_device *device)
759 enum connman_service_type type;
761 DBG("device %p", device);
763 __connman_device_disable(device);
765 switch (device->mode) {
766 case CONNMAN_DEVICE_MODE_UNKNOWN:
767 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
768 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
770 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
771 if (device->secondary == FALSE)
772 __connman_profile_remove_device(device);
776 type = __connman_device_get_service_type(device);
777 __connman_notifier_unregister(type);
779 unregister_interface(&device->element);
781 if (device->driver->remove)
782 device->driver->remove(device);
784 device->driver = NULL;
787 static void remove_driver(struct connman_element *element, gpointer user_data)
789 struct connman_device_driver *driver = user_data;
791 DBG("element %p name %s", element, element->name);
793 if (element->device == NULL)
796 if (element->device->driver == driver)
797 remove_device(element->device);
800 connman_bool_t __connman_device_has_driver(struct connman_device *device)
802 if (device == NULL || device->driver == NULL)
805 return device->registered;
808 static GSList *driver_list = NULL;
810 static gint compare_priority(gconstpointer a, gconstpointer b)
812 const struct connman_device_driver *driver1 = a;
813 const struct connman_device_driver *driver2 = b;
815 return driver2->priority - driver1->priority;
819 * connman_device_driver_register:
820 * @driver: device driver definition
822 * Register a new device driver
824 * Returns: %0 on success
826 int connman_device_driver_register(struct connman_device_driver *driver)
828 DBG("driver %p name %s", driver, driver->name);
830 driver_list = g_slist_insert_sorted(driver_list, driver,
833 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
834 probe_driver, driver);
840 * connman_device_driver_unregister:
841 * @driver: device driver definition
843 * Remove a previously registered device driver
845 void connman_device_driver_unregister(struct connman_device_driver *driver)
847 DBG("driver %p name %s", driver, driver->name);
849 driver_list = g_slist_remove(driver_list, driver);
851 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
852 remove_driver, driver);
855 static void unregister_network(gpointer data)
857 struct connman_network *network = data;
859 DBG("network %p", network);
861 connman_element_unregister((struct connman_element *) network);
863 connman_network_unref(network);
866 static void device_destruct(struct connman_element *element)
868 struct connman_device *device = element->device;
870 DBG("element %p name %s", element, element->name);
872 if (device->timeout > 0) {
873 g_source_remove(device->timeout);
877 clear_scan_trigger(device);
879 if (device->pending != NULL) {
880 dbus_message_unref(device->pending);
881 device->pending = NULL;
884 g_free(device->ident);
885 g_free(device->node);
886 g_free(device->name);
887 g_free(device->address);
888 g_free(device->control);
889 g_free(device->interface);
891 if (device->ipconfig != NULL) {
892 connman_ipconfig_unref(device->ipconfig);
893 device->ipconfig = NULL;
896 g_free(device->last_network);
898 g_hash_table_destroy(device->networks);
899 device->networks = NULL;
903 * connman_device_create:
904 * @node: device node name (for example an address)
907 * Allocate a new device of given #type and assign the #node name to it.
909 * Returns: a newly-allocated #connman_device structure
911 struct connman_device *connman_device_create(const char *node,
912 enum connman_device_type type)
914 struct connman_device *device;
917 DBG("node %s type %d", node, type);
919 device = g_try_new0(struct connman_device, 1);
923 DBG("device %p", device);
925 __connman_element_initialize(&device->element);
927 device->element.name = g_strdup(node);
928 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
930 device->element.device = device;
931 device->element.destruct = device_destruct;
933 str = type2string(type);
935 connman_element_set_string(&device->element,
936 CONNMAN_PROPERTY_ID_TYPE, str);
938 device->element.ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
941 device->name = g_strdup(type2description(device->type));
942 device->mode = CONNMAN_DEVICE_MODE_UNKNOWN;
943 device->secondary = FALSE;
945 device->powered_persistent = TRUE;
947 device->phyindex = -1;
950 case CONNMAN_DEVICE_TYPE_UNKNOWN:
951 case CONNMAN_DEVICE_TYPE_VENDOR:
952 device->scan_interval = 0;
954 case CONNMAN_DEVICE_TYPE_ETHERNET:
955 case CONNMAN_DEVICE_TYPE_WIFI:
956 device->scan_interval = 300;
958 case CONNMAN_DEVICE_TYPE_WIMAX:
959 device->scan_interval = 0;
961 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
962 device->scan_interval = 0;
964 case CONNMAN_DEVICE_TYPE_GPS:
965 device->scan_interval = 0;
967 case CONNMAN_DEVICE_TYPE_MBM:
968 case CONNMAN_DEVICE_TYPE_CELLULAR:
969 case CONNMAN_DEVICE_TYPE_HSO:
970 case CONNMAN_DEVICE_TYPE_NOZOMI:
971 case CONNMAN_DEVICE_TYPE_HUAWEI:
972 case CONNMAN_DEVICE_TYPE_NOVATEL:
973 device->scan_interval = 0;
977 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
978 g_free, unregister_network);
984 * connman_device_ref:
985 * @device: device structure
987 * Increase reference counter of device
989 struct connman_device *connman_device_ref(struct connman_device *device)
991 if (connman_element_ref(&device->element) == NULL)
998 * connman_device_unref:
999 * @device: device structure
1001 * Decrease reference counter of device
1003 void connman_device_unref(struct connman_device *device)
1005 connman_element_unref(&device->element);
1008 const char *__connman_device_get_type(struct connman_device *device)
1010 return type2string(device->type);
1014 * connman_device_get_type:
1015 * @device: device structure
1017 * Get type of device
1019 enum connman_device_type connman_device_get_type(struct connman_device *device)
1021 return device->type;
1025 * connman_device_get_name:
1026 * @device: device structure
1028 * Get unique name of device
1030 const char *connman_device_get_name(struct connman_device *device)
1032 return device->element.name;
1036 * connman_device_get_path:
1037 * @device: device structure
1039 * Get path name of device
1041 const char *connman_device_get_path(struct connman_device *device)
1043 return device->element.path;
1047 * connman_device_set_index:
1048 * @device: device structure
1049 * @index: index number
1051 * Set index number of device
1053 void connman_device_set_index(struct connman_device *device, int index)
1055 device->element.index = index;
1057 if (device->ipconfig != NULL) {
1058 if (index == connman_ipconfig_get_index(device->ipconfig))
1061 connman_ipconfig_unref(device->ipconfig);
1064 device->ipconfig = connman_ipconfig_create(index);
1068 * connman_device_get_index:
1069 * @device: device structure
1071 * Get index number of device
1073 int connman_device_get_index(struct connman_device *device)
1075 return device->element.index;
1078 int __connman_device_get_phyindex(struct connman_device *device)
1080 return device->phyindex;
1083 void __connman_device_set_phyindex(struct connman_device *device,
1086 device->phyindex = phyindex;
1090 * connman_device_set_interface:
1091 * @device: device structure
1092 * @interface: interface name
1093 * @control: control interface
1095 * Set interface name of device
1097 void connman_device_set_interface(struct connman_device *device,
1098 const char *interface, const char *control)
1100 g_free(device->element.devname);
1101 device->element.devname = g_strdup(interface);
1103 g_free(device->interface);
1104 device->interface = g_strdup(interface);
1106 g_free(device->control);
1107 device->control = g_strdup(control);
1109 if (device->name == NULL) {
1110 const char *str = type2description(device->type);
1111 if (str != NULL && device->interface != NULL)
1112 device->name = g_strdup_printf("%s (%s)", str,
1117 const char *connman_device_get_control(struct connman_device *device)
1119 return device->control;
1123 * connman_device_set_ident:
1124 * @device: device structure
1125 * @ident: unique identifier
1127 * Set unique identifier of device
1129 void connman_device_set_ident(struct connman_device *device,
1132 g_free(device->ident);
1133 device->ident = g_strdup(ident);
1136 const char *__connman_device_get_ident(struct connman_device *device)
1138 return device->ident;
1142 * connman_device_set_mode:
1143 * @device: device structure
1144 * @mode: network mode
1146 * Change network mode of device
1148 void connman_device_set_mode(struct connman_device *device,
1149 enum connman_device_mode mode)
1151 device->mode = mode;
1155 * connman_device_get_mode:
1156 * @device: device structure
1158 * Get network mode of device
1160 enum connman_device_mode connman_device_get_mode(struct connman_device *device)
1162 return device->mode;
1166 * connman_device_set_secondary:
1167 * @device: device structure
1168 * @secondary: secondary value
1170 * Change secondary value of device
1172 void connman_device_set_secondary(struct connman_device *device,
1173 connman_bool_t secondary)
1175 device->secondary = secondary;
1179 * connman_device_get_secondary:
1180 * @device: device structure
1182 * Get secondary value of device
1184 connman_bool_t connman_device_get_secondary(struct connman_device *device)
1186 return device->secondary;
1190 * connman_device_set_powered:
1191 * @device: device structure
1192 * @powered: powered state
1194 * Change power state of device
1196 int connman_device_set_powered(struct connman_device *device,
1197 connman_bool_t powered)
1199 enum connman_service_type type;
1201 DBG("driver %p powered %d", device, powered);
1203 if (device->timeout > 0) {
1204 g_source_remove(device->timeout);
1205 device->timeout = 0;
1208 if (device->pending != NULL) {
1209 g_dbus_send_reply(connection, device->pending,
1212 dbus_message_unref(device->pending);
1213 device->pending = NULL;
1216 if (device->powered == powered)
1219 device->powered = powered;
1220 device->powered_pending = powered;
1222 type = __connman_device_get_service_type(device);
1224 if (device->powered == TRUE)
1225 __connman_notifier_enable(type);
1227 __connman_notifier_disable(type);
1229 if (device->registered == FALSE)
1232 powered_changed(device);
1234 if (powered == FALSE)
1237 reset_scan_trigger(device);
1239 if (device->driver->scan)
1240 device->driver->scan(device);
1245 int __connman_device_set_blocked(struct connman_device *device,
1246 connman_bool_t blocked)
1248 connman_bool_t powered;
1250 DBG("device %p blocked %d", device, blocked);
1252 device->blocked = blocked;
1254 if (device->offlinemode == TRUE)
1257 connman_info("%s {rfkill} blocked %d", device->interface, blocked);
1259 if (blocked == FALSE)
1260 powered = device->powered_persistent;
1264 return set_powered(device, powered);
1268 * connman_device_set_carrier:
1269 * @device: device structure
1270 * @carrier: carrier state
1272 * Change carrier state of device (only for device without scanning)
1274 int connman_device_set_carrier(struct connman_device *device,
1275 connman_bool_t carrier)
1277 DBG("device %p carrier %d", device, carrier);
1279 switch (device->mode) {
1280 case CONNMAN_DEVICE_MODE_UNKNOWN:
1281 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1282 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1284 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1288 if (device->carrier == carrier)
1291 device->carrier = carrier;
1293 return set_carrier(device, device->carrier);
1296 int __connman_device_scan(struct connman_device *device)
1298 if (!device->driver || !device->driver->scan)
1301 if (device->powered == FALSE)
1304 reset_scan_trigger(device);
1306 return device->driver->scan(device);
1309 int __connman_device_enable(struct connman_device *device)
1311 enum connman_service_type type;
1314 DBG("device %p", device);
1316 if (!device->driver || !device->driver->enable)
1319 if (device->powered_pending == TRUE)
1322 device->powered_pending = TRUE;
1324 err = device->driver->enable(device);
1328 device->powered = TRUE;
1330 type = __connman_device_get_service_type(device);
1331 __connman_notifier_enable(type);
1336 int __connman_device_enable_persistent(struct connman_device *device)
1338 DBG("device %p", device);
1340 device->powered_persistent = TRUE;
1342 __connman_storage_save_device(device);
1344 return __connman_device_enable(device);
1347 int __connman_device_disable(struct connman_device *device)
1349 enum connman_service_type type;
1352 DBG("device %p", device);
1354 if (!device->driver || !device->driver->disable)
1357 if (device->powered == FALSE)
1360 if (device->powered_pending == FALSE)
1363 device->powered_pending = FALSE;
1365 device->reconnect = FALSE;
1367 clear_scan_trigger(device);
1369 g_hash_table_remove_all(device->networks);
1371 err = device->driver->disable(device);
1375 device->powered = FALSE;
1377 type = __connman_device_get_service_type(device);
1378 __connman_notifier_disable(type);
1383 int __connman_device_disable_persistent(struct connman_device *device)
1385 DBG("device %p", device);
1387 device->powered_persistent = FALSE;
1389 __connman_storage_save_device(device);
1391 return __connman_device_disable(device);
1394 int __connman_device_connect(struct connman_device *device)
1396 DBG("device %p", device);
1398 if (device->disconnected == FALSE)
1401 if (device->driver && device->driver->connect)
1402 device->driver->connect(device);
1407 int __connman_device_disconnect(struct connman_device *device)
1409 GHashTableIter iter;
1410 gpointer key, value;
1412 DBG("device %p", device);
1414 connman_device_set_disconnected(device, TRUE);
1416 g_hash_table_iter_init(&iter, device->networks);
1418 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1419 struct connman_network *network = value;
1421 __connman_network_disconnect(network);
1424 if (device->driver && device->driver->disconnect)
1425 device->driver->disconnect(device);
1430 static void mark_network_unavailable(gpointer key, gpointer value,
1433 struct connman_network *network = value;
1435 if (connman_network_get_connected(network) == TRUE)
1438 connman_network_set_available(network, FALSE);
1441 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1444 struct connman_network *network = value;
1446 if (connman_network_get_connected(network) == TRUE)
1449 if (connman_network_get_available(network) == TRUE)
1455 void __connman_device_cleanup_networks(struct connman_device *device)
1457 g_hash_table_foreach_remove(device->networks,
1458 remove_unavailable_network, NULL);
1461 static void scanning_changed(struct connman_device *device)
1463 DBusMessage *signal;
1464 DBusMessageIter entry, value;
1465 const char *key = "Scanning";
1467 signal = dbus_message_new_signal(device->element.path,
1468 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
1472 dbus_message_iter_init_append(signal, &entry);
1474 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1476 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
1477 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
1478 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
1480 dbus_message_iter_close_container(&entry, &value);
1482 g_dbus_send_message(connection, signal);
1485 static void mark_network_available(gpointer key, gpointer value,
1488 struct connman_network *network = value;
1490 connman_network_set_available(network, TRUE);
1493 void connman_device_cleanup_scanning(struct connman_device *device)
1495 device->scanning = FALSE;
1497 scanning_changed(device);
1499 g_hash_table_foreach(device->networks,
1500 mark_network_available, NULL);
1504 * connman_device_set_scanning:
1505 * @device: device structure
1506 * @scanning: scanning state
1508 * Change scanning state of device
1510 int connman_device_set_scanning(struct connman_device *device,
1511 connman_bool_t scanning)
1513 DBG("device %p scanning %d", device, scanning);
1515 if (!device->driver || !device->driver->scan)
1518 if (device->scanning == scanning)
1521 device->scanning = scanning;
1523 scanning_changed(device);
1525 if (scanning == TRUE) {
1526 reset_scan_trigger(device);
1528 g_hash_table_foreach(device->networks,
1529 mark_network_unavailable, NULL);
1534 __connman_device_cleanup_networks(device);
1536 if (device->connections > 0)
1539 if (device->disconnected == TRUE)
1542 __connman_service_auto_connect();
1548 * connman_device_set_disconnected:
1549 * @device: device structure
1550 * @disconnected: disconnected state
1552 * Change disconnected state of device (only for device with networks)
1554 int connman_device_set_disconnected(struct connman_device *device,
1555 connman_bool_t disconnected)
1557 DBG("device %p disconnected %d", device, disconnected);
1559 switch (device->mode) {
1560 case CONNMAN_DEVICE_MODE_UNKNOWN:
1561 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1563 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1564 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1568 if (device->disconnected == disconnected)
1571 device->disconnected = disconnected;
1573 if (disconnected == TRUE)
1574 force_scan_trigger(device);
1580 * connman_device_get_disconnected:
1581 * @device: device structure
1583 * Get device disconnected state
1585 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
1587 return device->disconnected;
1591 * connman_device_set_connected:
1592 * @device: device structure
1593 * @connected: connected state
1595 * Change connected state of device (for Ethernet like devices)
1597 int connman_device_set_connected(struct connman_device *device,
1598 connman_bool_t connected)
1600 DBG("device %p connected %d", device, connected);
1602 switch (device->mode) {
1603 case CONNMAN_DEVICE_MODE_UNKNOWN:
1604 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1605 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1607 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1611 if (device->carrier == FALSE)
1614 return set_connected(device, connected);
1618 * connman_device_set_string:
1619 * @device: device structure
1620 * @key: unique identifier
1621 * @value: string value
1623 * Set string value for specific key
1625 int connman_device_set_string(struct connman_device *device,
1626 const char *key, const char *value)
1628 DBG("device %p key %s value %s", device, key, value);
1630 if (g_str_equal(key, "Address") == TRUE) {
1631 g_free(device->address);
1632 device->address = g_strdup(value);
1633 } else if (g_str_equal(key, "Name") == TRUE) {
1634 g_free(device->name);
1635 device->name = g_strdup(value);
1636 } else if (g_str_equal(key, "Node") == TRUE) {
1637 g_free(device->node);
1638 device->node = g_strdup(value);
1641 return connman_element_set_string(&device->element, key, value);
1645 * connman_device_get_string:
1646 * @device: device structure
1647 * @key: unique identifier
1649 * Get string value for specific key
1651 const char *connman_device_get_string(struct connman_device *device,
1654 DBG("device %p key %s", device, key);
1656 if (g_str_equal(key, "Address") == TRUE)
1657 return device->address;
1658 else if (g_str_equal(key, "Name") == TRUE)
1659 return device->name;
1660 else if (g_str_equal(key, "Node") == TRUE)
1661 return device->node;
1663 return connman_element_get_string(&device->element, key);
1666 static void set_offlinemode(struct connman_element *element, gpointer user_data)
1668 struct connman_device *device = element->device;
1669 connman_bool_t offlinemode = GPOINTER_TO_UINT(user_data);
1670 connman_bool_t powered;
1672 DBG("element %p name %s", element, element->name);
1677 device->offlinemode = offlinemode;
1679 powered = (offlinemode == TRUE) ? FALSE : TRUE;
1681 if (device->powered == powered)
1684 if (device->powered_persistent == FALSE)
1687 set_powered(device, powered);
1690 int __connman_device_set_offlinemode(connman_bool_t offlinemode)
1692 DBG("offlinmode %d", offlinemode);
1694 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
1695 set_offlinemode, GUINT_TO_POINTER(offlinemode));
1697 __connman_notifier_offlinemode(offlinemode);
1702 void __connman_device_increase_connections(struct connman_device *device)
1704 device->connections++;
1707 void __connman_device_decrease_connections(struct connman_device *device)
1709 device->connections--;
1713 * connman_device_add_network:
1714 * @device: device structure
1715 * @network: network structure
1717 * Add new network to the device
1719 int connman_device_add_network(struct connman_device *device,
1720 struct connman_network *network)
1722 const char *identifier = connman_network_get_identifier(network);
1725 DBG("device %p network %p", device, network);
1727 switch (device->mode) {
1728 case CONNMAN_DEVICE_MODE_UNKNOWN:
1729 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1731 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1732 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1736 __connman_network_set_device(network, device);
1738 err = connman_element_register((struct connman_element *) network,
1741 __connman_network_set_device(network, NULL);
1745 g_hash_table_insert(device->networks, g_strdup(identifier),
1752 * connman_device_get_network:
1753 * @device: device structure
1754 * @identifier: network identifier
1756 * Get network for given identifier
1758 struct connman_network *connman_device_get_network(struct connman_device *device,
1759 const char *identifier)
1761 DBG("device %p identifier %s", device, identifier);
1763 return g_hash_table_lookup(device->networks, identifier);
1767 * connman_device_remove_network:
1768 * @device: device structure
1769 * @identifier: network identifier
1771 * Remove network for given identifier
1773 int connman_device_remove_network(struct connman_device *device,
1774 const char *identifier)
1776 DBG("device %p identifier %s", device, identifier);
1778 g_hash_table_remove(device->networks, identifier);
1783 void connman_device_remove_all_networks(struct connman_device *device)
1785 g_hash_table_remove_all(device->networks);
1788 void __connman_device_set_network(struct connman_device *device,
1789 struct connman_network *network)
1793 if (device->network == network)
1796 if (device->network != NULL)
1797 connman_network_unref(device->network);
1799 if (network != NULL) {
1800 name = connman_network_get_string(network,
1801 CONNMAN_PROPERTY_ID_NAME);
1802 g_free(device->last_network);
1803 device->last_network = g_strdup(name);
1805 device->network = connman_network_ref(network);
1807 g_free(device->last_network);
1808 device->last_network = NULL;
1810 device->network = NULL;
1814 void __connman_device_set_reconnect(struct connman_device *device,
1815 connman_bool_t reconnect)
1817 device->reconnect = reconnect;
1820 connman_bool_t __connman_device_get_reconnect(
1821 struct connman_device *device)
1823 return device->reconnect;
1827 * connman_device_register:
1828 * @device: device structure
1830 * Register device with the system
1832 int connman_device_register(struct connman_device *device)
1834 __connman_storage_load_device(device);
1836 device->offlinemode = __connman_profile_get_offlinemode();
1838 return connman_element_register(&device->element, NULL);
1842 * connman_device_unregister:
1843 * @device: device structure
1845 * Unregister device with the system
1847 void connman_device_unregister(struct connman_device *device)
1849 __connman_storage_save_device(device);
1851 connman_element_unregister(&device->element);
1855 * connman_device_get_data:
1856 * @device: device structure
1858 * Get private device data pointer
1860 void *connman_device_get_data(struct connman_device *device)
1862 return device->driver_data;
1866 * connman_device_set_data:
1867 * @device: device structure
1868 * @data: data pointer
1870 * Set private device data pointer
1872 void connman_device_set_data(struct connman_device *device, void *data)
1874 device->driver_data = data;
1877 static gboolean match_driver(struct connman_device *device,
1878 struct connman_device_driver *driver)
1880 if (device->type == driver->type ||
1881 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1887 static int device_probe(struct connman_element *element)
1889 struct connman_device *device = element->device;
1892 DBG("element %p name %s", element, element->name);
1897 if (device->driver != NULL)
1900 for (list = driver_list; list; list = list->next) {
1901 struct connman_device_driver *driver = list->data;
1903 if (match_driver(device, driver) == FALSE)
1906 DBG("driver %p name %s", driver, driver->name);
1908 if (driver->probe(device) == 0) {
1909 device->driver = driver;
1914 if (device->driver == NULL)
1917 return setup_device(device);
1920 static void device_remove(struct connman_element *element)
1922 struct connman_device *device = element->device;
1924 DBG("element %p name %s", element, element->name);
1929 if (device->driver == NULL)
1932 remove_device(device);
1935 static struct connman_driver device_driver = {
1937 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
1938 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
1939 .probe = device_probe,
1940 .remove = device_remove,
1943 static int device_load(struct connman_device *device)
1945 const char *ident = __connman_profile_active_ident();
1947 GError *error = NULL;
1949 connman_bool_t powered;
1952 DBG("device %p", device);
1954 keyfile = __connman_storage_open(ident);
1955 if (keyfile == NULL)
1958 identifier = g_strdup_printf("device_%s", device->element.name);
1959 if (identifier == NULL)
1962 powered = g_key_file_get_boolean(keyfile, identifier,
1965 device->powered_persistent = powered;
1966 g_clear_error(&error);
1968 switch (device->mode) {
1969 case CONNMAN_DEVICE_MODE_UNKNOWN:
1970 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1972 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1973 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1974 val = g_key_file_get_integer(keyfile, identifier,
1975 "ScanInterval", &error);
1976 if (error == NULL && val > 0)
1977 device->scan_interval = val;
1978 g_clear_error(&error);
1985 __connman_storage_close(ident, keyfile, FALSE);
1990 static int device_save(struct connman_device *device)
1992 const char *ident = __connman_profile_active_ident();
1996 DBG("device %p", device);
1998 keyfile = __connman_storage_open(ident);
1999 if (keyfile == NULL)
2002 identifier = g_strdup_printf("device_%s", device->element.name);
2003 if (identifier == NULL)
2006 g_key_file_set_boolean(keyfile, identifier,
2007 "Powered", device->powered_persistent);
2009 switch (device->mode) {
2010 case CONNMAN_DEVICE_MODE_UNKNOWN:
2011 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
2013 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
2014 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
2015 if (device->scan_interval > 0)
2016 g_key_file_set_integer(keyfile, identifier,
2017 "ScanInterval", device->scan_interval);
2024 __connman_storage_close(ident, keyfile, TRUE);
2029 static struct connman_storage device_storage = {
2031 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
2032 .device_load = device_load,
2033 .device_save = device_save,
2036 int __connman_device_init(void)
2040 connection = connman_dbus_get_connection();
2042 if (connman_storage_register(&device_storage) < 0)
2043 connman_error("Failed to register device storage");
2045 return connman_driver_register(&device_driver);
2048 void __connman_device_cleanup(void)
2052 connman_driver_unregister(&device_driver);
2054 connman_storage_unregister(&device_storage);
2056 dbus_connection_unref(connection);