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 static const char *type2description(enum connman_device_type type)
121 case CONNMAN_DEVICE_TYPE_UNKNOWN:
122 case CONNMAN_DEVICE_TYPE_VENDOR:
124 case CONNMAN_DEVICE_TYPE_ETHERNET:
126 case CONNMAN_DEVICE_TYPE_WIFI:
128 case CONNMAN_DEVICE_TYPE_WIMAX:
130 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
132 case CONNMAN_DEVICE_TYPE_GPS:
134 case CONNMAN_DEVICE_TYPE_MBM:
135 case CONNMAN_DEVICE_TYPE_CELLULAR:
136 case CONNMAN_DEVICE_TYPE_HSO:
137 case CONNMAN_DEVICE_TYPE_NOZOMI:
138 case CONNMAN_DEVICE_TYPE_HUAWEI:
139 case CONNMAN_DEVICE_TYPE_NOVATEL:
146 static const char *type2string(enum connman_device_type type)
149 case CONNMAN_DEVICE_TYPE_UNKNOWN:
150 case CONNMAN_DEVICE_TYPE_VENDOR:
152 case CONNMAN_DEVICE_TYPE_ETHERNET:
154 case CONNMAN_DEVICE_TYPE_WIFI:
156 case CONNMAN_DEVICE_TYPE_WIMAX:
158 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
160 case CONNMAN_DEVICE_TYPE_GPS:
162 case CONNMAN_DEVICE_TYPE_MBM:
163 case CONNMAN_DEVICE_TYPE_CELLULAR:
164 case CONNMAN_DEVICE_TYPE_HSO:
165 case CONNMAN_DEVICE_TYPE_HUAWEI:
166 case CONNMAN_DEVICE_TYPE_NOZOMI:
167 case CONNMAN_DEVICE_TYPE_NOVATEL:
174 enum connman_service_type __connman_device_get_service_type(struct connman_device *device)
176 enum connman_device_type type = connman_device_get_type(device);
179 case CONNMAN_DEVICE_TYPE_UNKNOWN:
180 case CONNMAN_DEVICE_TYPE_VENDOR:
181 case CONNMAN_DEVICE_TYPE_GPS:
182 case CONNMAN_DEVICE_TYPE_NOZOMI:
183 case CONNMAN_DEVICE_TYPE_HUAWEI:
184 case CONNMAN_DEVICE_TYPE_NOVATEL:
186 case CONNMAN_DEVICE_TYPE_ETHERNET:
187 return CONNMAN_SERVICE_TYPE_ETHERNET;
188 case CONNMAN_DEVICE_TYPE_WIFI:
189 return CONNMAN_SERVICE_TYPE_WIFI;
190 case CONNMAN_DEVICE_TYPE_WIMAX:
191 return CONNMAN_SERVICE_TYPE_WIMAX;
192 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
193 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
194 case CONNMAN_DEVICE_TYPE_MBM:
195 case CONNMAN_DEVICE_TYPE_CELLULAR:
196 case CONNMAN_DEVICE_TYPE_HSO:
197 return CONNMAN_SERVICE_TYPE_CELLULAR;
200 return CONNMAN_SERVICE_TYPE_UNKNOWN;
203 static int set_connected(struct connman_device *device,
204 connman_bool_t connected)
206 if (connected == TRUE) {
207 enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
208 struct connman_element *element;
210 device->disconnected = TRUE;
212 switch (device->element.ipv4.method) {
213 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
214 case CONNMAN_IPCONFIG_METHOD_IGNORE:
216 case CONNMAN_IPCONFIG_METHOD_STATIC:
217 type = CONNMAN_ELEMENT_TYPE_IPV4;
219 case CONNMAN_IPCONFIG_METHOD_DHCP:
220 type = CONNMAN_ELEMENT_TYPE_DHCP;
224 element = connman_element_create(NULL);
225 if (element != NULL) {
226 struct connman_service *service;
228 element->type = type;
229 element->index = device->element.index;
231 if (connman_element_register(element,
232 &device->element) < 0)
233 connman_element_unref(element);
235 device->disconnected = FALSE;
237 service = __connman_service_lookup_from_device(device);
238 __connman_service_indicate_state(service,
239 CONNMAN_SERVICE_STATE_CONFIGURATION);
242 struct connman_service *service;
244 connman_element_unregister_children(&device->element);
246 device->disconnected = TRUE;
248 service = __connman_service_lookup_from_device(device);
249 __connman_service_indicate_state(service,
250 CONNMAN_SERVICE_STATE_IDLE);
253 if (connected == TRUE) {
254 enum connman_service_type type;
256 type = __connman_device_get_service_type(device);
257 __connman_notifier_connect(type);
259 enum connman_service_type type;
261 type = __connman_device_get_service_type(device);
262 __connman_notifier_disconnect(type);
268 static int set_carrier(struct connman_device *device, connman_bool_t carrier)
271 __connman_profile_add_device(device);
273 __connman_profile_remove_device(device);
275 return set_connected(device, carrier);
278 static int powered_changed(struct connman_device *device)
281 DBusMessageIter entry, value;
282 const char *key = "Powered";
284 signal = dbus_message_new_signal(device->element.path,
285 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
289 dbus_message_iter_init_append(signal, &entry);
291 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
293 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
294 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
295 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
297 dbus_message_iter_close_container(&entry, &value);
299 g_dbus_send_message(connection, signal);
304 static int set_powered(struct connman_device *device, connman_bool_t powered)
306 struct connman_device_driver *driver = device->driver;
307 enum connman_service_type type;
310 DBG("device %p powered %d", device, powered);
312 if (device->powered_pending == powered)
318 type = __connman_device_get_service_type(device);
320 if (powered == TRUE) {
321 if (driver->enable) {
322 device->powered_pending = powered;
324 err = driver->enable(device);
326 __connman_notifier_enable(type);
330 device->powered_pending = powered;
332 device->reconnect = FALSE;
334 clear_scan_trigger(device);
336 g_hash_table_remove_all(device->networks);
338 set_carrier(device, FALSE);
340 if (driver->disable) {
341 err = driver->disable(device);
343 __connman_notifier_disable(type);
349 device->powered = powered;
351 if (device->registered == TRUE)
352 powered_changed(device);
358 static void append_path(gpointer key, gpointer value, gpointer user_data)
360 struct connman_element *element = value;
361 DBusMessageIter *iter = user_data;
363 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
367 static void append_networks(struct connman_device *device,
368 DBusMessageIter *entry)
370 DBusMessageIter value, iter;
371 const char *key = "Networks";
373 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
375 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
376 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
379 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
380 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
381 g_hash_table_foreach(device->networks, append_path, &iter);
382 dbus_message_iter_close_container(&value, &iter);
384 dbus_message_iter_close_container(entry, &value);
387 static DBusMessage *get_properties(DBusConnection *conn,
388 DBusMessage *msg, void *data)
390 struct connman_device *device = data;
392 DBusMessageIter array, dict, entry;
395 DBG("conn %p", conn);
397 if (__connman_security_check_privilege(msg,
398 CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
399 return __connman_error_permission_denied(msg);
401 reply = dbus_message_new_method_return(msg);
405 dbus_message_iter_init_append(reply, &array);
407 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
408 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
409 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
410 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
412 if (device->name != NULL)
413 connman_dbus_dict_append_variant(&dict, "Name",
414 DBUS_TYPE_STRING, &device->name);
416 str = type2string(device->type);
418 connman_dbus_dict_append_variant(&dict, "Type",
419 DBUS_TYPE_STRING, &str);
421 if (device->address != NULL)
422 connman_dbus_dict_append_variant(&dict, "Address",
423 DBUS_TYPE_STRING, &device->address);
425 if (device->interface != NULL)
426 connman_dbus_dict_append_variant(&dict, "Interface",
427 DBUS_TYPE_STRING, &device->interface);
429 connman_dbus_dict_append_variant(&dict, "Powered",
430 DBUS_TYPE_BOOLEAN, &device->powered);
432 if (device->driver && device->driver->scan)
433 connman_dbus_dict_append_variant(&dict, "Scanning",
434 DBUS_TYPE_BOOLEAN, &device->scanning);
436 switch (device->mode) {
437 case CONNMAN_DEVICE_MODE_UNKNOWN:
439 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
440 __connman_element_append_ipv4(&device->element, &dict);
442 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
443 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
444 if (device->scan_interval > 0)
445 connman_dbus_dict_append_variant(&dict, "ScanInterval",
446 DBUS_TYPE_UINT16, &device->scan_interval);
448 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
450 append_networks(device, &entry);
451 dbus_message_iter_close_container(&dict, &entry);
455 dbus_message_iter_close_container(&array, &dict);
460 static gboolean powered_timeout(gpointer user_data)
462 struct connman_device *device = user_data;
464 DBG("device %p", device);
468 if (device->pending != NULL) {
471 reply = __connman_error_operation_timeout(device->pending);
473 g_dbus_send_message(connection, reply);
475 dbus_message_unref(device->pending);
476 device->pending = NULL;
482 static DBusMessage *set_property(DBusConnection *conn,
483 DBusMessage *msg, void *data)
485 struct connman_device *device = data;
486 DBusMessageIter iter, value;
490 DBG("conn %p", conn);
492 if (dbus_message_iter_init(msg, &iter) == FALSE)
493 return __connman_error_invalid_arguments(msg);
495 dbus_message_iter_get_basic(&iter, &name);
496 dbus_message_iter_next(&iter);
497 dbus_message_iter_recurse(&iter, &value);
499 if (__connman_security_check_privilege(msg,
500 CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
501 return __connman_error_permission_denied(msg);
503 type = dbus_message_iter_get_arg_type(&value);
505 if (g_str_equal(name, "Powered") == TRUE) {
506 connman_bool_t powered;
509 if (type != DBUS_TYPE_BOOLEAN)
510 return __connman_error_invalid_arguments(msg);
512 dbus_message_iter_get_basic(&value, &powered);
514 device->powered_persistent = powered;
516 __connman_storage_save_device(device);
518 if (device->powered == powered)
519 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
521 if (device->pending != NULL)
522 return __connman_error_in_progress(msg);
524 err = set_powered(device, powered);
526 if (err != -EINPROGRESS)
527 return __connman_error_failed(msg, -err);
529 device->pending = dbus_message_ref(msg);
531 device->timeout = g_timeout_add_seconds(15,
532 powered_timeout, device);
536 } else if (g_str_equal(name, "ScanInterval") == TRUE) {
537 connman_uint16_t interval;
539 switch (device->mode) {
540 case CONNMAN_DEVICE_MODE_UNKNOWN:
541 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
542 return __connman_error_invalid_arguments(msg);
543 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
544 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
548 if (type != DBUS_TYPE_UINT16)
549 return __connman_error_invalid_arguments(msg);
551 dbus_message_iter_get_basic(&value, &interval);
553 if (device->scan_interval != interval) {
554 device->scan_interval = interval;
556 __connman_storage_save_device(device);
558 reset_scan_trigger(device);
560 } else if (g_str_has_prefix(name, "IPv4.") == TRUE) {
563 if (device->ipconfig == NULL)
564 return __connman_error_invalid_property(msg);
566 switch (device->mode) {
567 case CONNMAN_DEVICE_MODE_UNKNOWN:
568 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
569 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
570 return __connman_error_invalid_arguments(msg);
571 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
575 err = __connman_ipconfig_set_ipv4(device->ipconfig,
578 return __connman_error_failed(msg, -err);
580 return __connman_error_invalid_property(msg);
582 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
585 static DBusMessage *propose_scan(DBusConnection *conn,
586 DBusMessage *msg, void *data)
588 struct connman_device *device = data;
591 DBG("conn %p", conn);
593 switch (device->mode) {
594 case CONNMAN_DEVICE_MODE_UNKNOWN:
595 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
596 return __connman_error_not_supported(msg);
597 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
598 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
602 err = __connman_device_scan(device);
604 return __connman_error_failed(msg, -err);
606 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
609 static GDBusMethodTable device_methods[] = {
610 { "GetProperties", "", "a{sv}", get_properties },
611 { "SetProperty", "sv", "", set_property,
612 G_DBUS_METHOD_FLAG_ASYNC },
613 { "ProposeScan", "", "", propose_scan },
617 static GDBusSignalTable device_signals[] = {
618 { "PropertyChanged", "sv" },
622 static void append_devices(DBusMessageIter *entry)
624 DBusMessageIter value, iter;
625 const char *key = "Devices";
627 dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key);
629 dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
630 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
633 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
634 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
635 __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
636 dbus_message_iter_close_container(&value, &iter);
638 dbus_message_iter_close_container(entry, &value);
641 static void emit_devices_signal(void)
644 DBusMessageIter entry;
646 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
647 CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
651 dbus_message_iter_init_append(signal, &entry);
653 append_devices(&entry);
655 g_dbus_send_message(connection, signal);
658 static int register_interface(struct connman_element *element)
660 struct connman_device *device = element->device;
662 DBG("element %p name %s", element, element->name);
664 if (g_dbus_register_interface(connection, element->path,
665 CONNMAN_DEVICE_INTERFACE,
666 device_methods, device_signals,
667 NULL, device, NULL) == FALSE) {
668 connman_error("Failed to register %s device", element->path);
672 device->registered = TRUE;
674 emit_devices_signal();
679 static void unregister_interface(struct connman_element *element)
681 struct connman_device *device = element->device;
683 DBG("element %p name %s", element, element->name);
685 device->registered = FALSE;
687 emit_devices_signal();
689 g_dbus_unregister_interface(connection, element->path,
690 CONNMAN_DEVICE_INTERFACE);
693 static int setup_device(struct connman_device *device)
695 enum connman_service_type type;
698 DBG("device %p", device);
700 err = register_interface(&device->element);
702 if (device->driver->remove)
703 device->driver->remove(device);
704 device->driver = NULL;
708 type = __connman_device_get_service_type(device);
709 __connman_notifier_register(type);
711 switch (device->mode) {
712 case CONNMAN_DEVICE_MODE_UNKNOWN:
713 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
714 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
716 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
717 if (device->carrier == TRUE && device->secondary == FALSE)
718 __connman_profile_add_device(device);
722 if (device->offlinemode == FALSE &&
723 device->powered_persistent == TRUE)
724 __connman_device_enable(device);
729 static void probe_driver(struct connman_element *element, gpointer user_data)
731 struct connman_device_driver *driver = user_data;
733 DBG("element %p name %s", element, element->name);
735 if (element->device == NULL)
738 if (element->device->driver != NULL)
741 if (driver->type != element->device->type)
744 if (driver->probe(element->device) < 0)
747 element->device->driver = driver;
749 setup_device(element->device);
752 static void remove_device(struct connman_device *device)
754 enum connman_service_type type;
756 DBG("device %p", device);
758 __connman_device_disable(device);
760 switch (device->mode) {
761 case CONNMAN_DEVICE_MODE_UNKNOWN:
762 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
763 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
765 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
766 if (device->secondary == FALSE)
767 __connman_profile_remove_device(device);
771 type = __connman_device_get_service_type(device);
772 __connman_notifier_unregister(type);
774 unregister_interface(&device->element);
776 if (device->driver->remove)
777 device->driver->remove(device);
779 device->driver = NULL;
782 static void remove_driver(struct connman_element *element, gpointer user_data)
784 struct connman_device_driver *driver = user_data;
786 DBG("element %p name %s", element, element->name);
788 if (element->device == NULL)
791 if (element->device->driver == driver)
792 remove_device(element->device);
795 connman_bool_t __connman_device_has_driver(struct connman_device *device)
797 if (device == NULL || device->driver == NULL)
800 return device->registered;
803 static GSList *driver_list = NULL;
805 static gint compare_priority(gconstpointer a, gconstpointer b)
807 const struct connman_device_driver *driver1 = a;
808 const struct connman_device_driver *driver2 = b;
810 return driver2->priority - driver1->priority;
814 * connman_device_driver_register:
815 * @driver: device driver definition
817 * Register a new device driver
819 * Returns: %0 on success
821 int connman_device_driver_register(struct connman_device_driver *driver)
823 DBG("driver %p name %s", driver, driver->name);
825 driver_list = g_slist_insert_sorted(driver_list, driver,
828 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
829 probe_driver, driver);
835 * connman_device_driver_unregister:
836 * @driver: device driver definition
838 * Remove a previously registered device driver
840 void connman_device_driver_unregister(struct connman_device_driver *driver)
842 DBG("driver %p name %s", driver, driver->name);
844 driver_list = g_slist_remove(driver_list, driver);
846 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
847 remove_driver, driver);
850 static void unregister_network(gpointer data)
852 struct connman_network *network = data;
854 DBG("network %p", network);
856 connman_element_unregister((struct connman_element *) network);
858 connman_network_unref(network);
861 static void device_destruct(struct connman_element *element)
863 struct connman_device *device = element->device;
865 DBG("element %p name %s", element, element->name);
867 if (device->timeout > 0) {
868 g_source_remove(device->timeout);
872 clear_scan_trigger(device);
874 if (device->pending != NULL) {
875 dbus_message_unref(device->pending);
876 device->pending = NULL;
879 g_free(device->ident);
880 g_free(device->node);
881 g_free(device->name);
882 g_free(device->address);
883 g_free(device->control);
884 g_free(device->interface);
886 if (device->ipconfig != NULL) {
887 connman_ipconfig_unref(device->ipconfig);
888 device->ipconfig = NULL;
891 g_free(device->last_network);
893 g_hash_table_destroy(device->networks);
894 device->networks = NULL;
898 * connman_device_create:
899 * @node: device node name (for example an address)
902 * Allocate a new device of given #type and assign the #node name to it.
904 * Returns: a newly-allocated #connman_device structure
906 struct connman_device *connman_device_create(const char *node,
907 enum connman_device_type type)
909 struct connman_device *device;
912 DBG("node %s type %d", node, type);
914 device = g_try_new0(struct connman_device, 1);
918 DBG("device %p", device);
920 __connman_element_initialize(&device->element);
922 device->element.name = g_strdup(node);
923 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
925 device->element.device = device;
926 device->element.destruct = device_destruct;
928 str = type2string(type);
930 connman_element_set_string(&device->element,
931 CONNMAN_PROPERTY_ID_TYPE, str);
933 device->element.ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
936 device->name = g_strdup(type2description(device->type));
937 device->mode = CONNMAN_DEVICE_MODE_UNKNOWN;
938 device->secondary = FALSE;
940 device->powered_persistent = TRUE;
942 device->phyindex = -1;
945 case CONNMAN_DEVICE_TYPE_UNKNOWN:
946 case CONNMAN_DEVICE_TYPE_VENDOR:
947 device->scan_interval = 0;
949 case CONNMAN_DEVICE_TYPE_ETHERNET:
950 case CONNMAN_DEVICE_TYPE_WIFI:
951 device->scan_interval = 300;
953 case CONNMAN_DEVICE_TYPE_WIMAX:
954 device->scan_interval = 0;
956 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
957 device->scan_interval = 0;
959 case CONNMAN_DEVICE_TYPE_GPS:
960 device->scan_interval = 0;
962 case CONNMAN_DEVICE_TYPE_MBM:
963 case CONNMAN_DEVICE_TYPE_CELLULAR:
964 case CONNMAN_DEVICE_TYPE_HSO:
965 case CONNMAN_DEVICE_TYPE_NOZOMI:
966 case CONNMAN_DEVICE_TYPE_HUAWEI:
967 case CONNMAN_DEVICE_TYPE_NOVATEL:
968 device->scan_interval = 0;
972 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
973 g_free, unregister_network);
979 * connman_device_ref:
980 * @device: device structure
982 * Increase reference counter of device
984 struct connman_device *connman_device_ref(struct connman_device *device)
986 if (connman_element_ref(&device->element) == NULL)
993 * connman_device_unref:
994 * @device: device structure
996 * Decrease reference counter of device
998 void connman_device_unref(struct connman_device *device)
1000 connman_element_unref(&device->element);
1003 const char *__connman_device_get_type(struct connman_device *device)
1005 return type2string(device->type);
1009 * connman_device_get_type:
1010 * @device: device structure
1012 * Get type of device
1014 enum connman_device_type connman_device_get_type(struct connman_device *device)
1016 return device->type;
1020 * connman_device_get_name:
1021 * @device: device structure
1023 * Get unique name of device
1025 const char *connman_device_get_name(struct connman_device *device)
1027 return device->element.name;
1031 * connman_device_get_path:
1032 * @device: device structure
1034 * Get path name of device
1036 const char *connman_device_get_path(struct connman_device *device)
1038 return device->element.path;
1042 * connman_device_set_index:
1043 * @device: device structure
1044 * @index: index number
1046 * Set index number of device
1048 void connman_device_set_index(struct connman_device *device, int index)
1050 device->element.index = index;
1052 if (device->ipconfig != NULL) {
1053 if (index == connman_ipconfig_get_index(device->ipconfig))
1056 connman_ipconfig_unref(device->ipconfig);
1059 device->ipconfig = connman_ipconfig_create(index);
1063 * connman_device_get_index:
1064 * @device: device structure
1066 * Get index number of device
1068 int connman_device_get_index(struct connman_device *device)
1070 return device->element.index;
1073 int __connman_device_get_phyindex(struct connman_device *device)
1075 return device->phyindex;
1078 void __connman_device_set_phyindex(struct connman_device *device,
1081 device->phyindex = phyindex;
1085 * connman_device_set_interface:
1086 * @device: device structure
1087 * @interface: interface name
1088 * @control: control interface
1090 * Set interface name of device
1092 void connman_device_set_interface(struct connman_device *device,
1093 const char *interface, const char *control)
1095 g_free(device->element.devname);
1096 device->element.devname = g_strdup(interface);
1098 g_free(device->interface);
1099 device->interface = g_strdup(interface);
1101 g_free(device->control);
1102 device->control = g_strdup(control);
1104 if (device->name == NULL) {
1105 const char *str = type2description(device->type);
1106 if (str != NULL && device->interface != NULL)
1107 device->name = g_strdup_printf("%s (%s)", str,
1112 const char *connman_device_get_control(struct connman_device *device)
1114 return device->control;
1118 * connman_device_set_ident:
1119 * @device: device structure
1120 * @ident: unique identifier
1122 * Set unique identifier of device
1124 void connman_device_set_ident(struct connman_device *device,
1127 g_free(device->ident);
1128 device->ident = g_strdup(ident);
1131 const char *__connman_device_get_ident(struct connman_device *device)
1133 return device->ident;
1137 * connman_device_set_mode:
1138 * @device: device structure
1139 * @mode: network mode
1141 * Change network mode of device
1143 void connman_device_set_mode(struct connman_device *device,
1144 enum connman_device_mode mode)
1146 device->mode = mode;
1150 * connman_device_get_mode:
1151 * @device: device structure
1153 * Get network mode of device
1155 enum connman_device_mode connman_device_get_mode(struct connman_device *device)
1157 return device->mode;
1161 * connman_device_set_secondary:
1162 * @device: device structure
1163 * @secondary: secondary value
1165 * Change secondary value of device
1167 void connman_device_set_secondary(struct connman_device *device,
1168 connman_bool_t secondary)
1170 device->secondary = secondary;
1174 * connman_device_get_secondary:
1175 * @device: device structure
1177 * Get secondary value of device
1179 connman_bool_t connman_device_get_secondary(struct connman_device *device)
1181 return device->secondary;
1185 * connman_device_set_powered:
1186 * @device: device structure
1187 * @powered: powered state
1189 * Change power state of device
1191 int connman_device_set_powered(struct connman_device *device,
1192 connman_bool_t powered)
1194 enum connman_service_type type;
1196 DBG("driver %p powered %d", device, powered);
1198 if (device->timeout > 0) {
1199 g_source_remove(device->timeout);
1200 device->timeout = 0;
1203 if (device->pending != NULL) {
1204 g_dbus_send_reply(connection, device->pending,
1207 dbus_message_unref(device->pending);
1208 device->pending = NULL;
1211 if (device->powered == powered)
1214 device->powered = powered;
1215 device->powered_pending = powered;
1217 type = __connman_device_get_service_type(device);
1219 if (device->powered == TRUE)
1220 __connman_notifier_enable(type);
1222 __connman_notifier_disable(type);
1224 if (device->registered == FALSE)
1227 powered_changed(device);
1229 if (powered == FALSE)
1232 reset_scan_trigger(device);
1234 if (device->driver->scan)
1235 device->driver->scan(device);
1240 int __connman_device_set_blocked(struct connman_device *device,
1241 connman_bool_t blocked)
1243 connman_bool_t powered;
1245 DBG("device %p blocked %d", device, blocked);
1247 device->blocked = blocked;
1249 if (device->offlinemode == TRUE)
1252 connman_info("%s {rfkill} blocked %d", device->interface, blocked);
1254 if (blocked == FALSE)
1255 powered = device->powered_persistent;
1259 return set_powered(device, powered);
1263 * connman_device_set_carrier:
1264 * @device: device structure
1265 * @carrier: carrier state
1267 * Change carrier state of device (only for device without scanning)
1269 int connman_device_set_carrier(struct connman_device *device,
1270 connman_bool_t carrier)
1272 DBG("device %p carrier %d", device, carrier);
1274 switch (device->mode) {
1275 case CONNMAN_DEVICE_MODE_UNKNOWN:
1276 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1277 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1279 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1283 if (device->carrier == carrier)
1286 device->carrier = carrier;
1288 return set_carrier(device, device->carrier);
1291 int __connman_device_scan(struct connman_device *device)
1293 if (!device->driver || !device->driver->scan)
1296 if (device->powered == FALSE)
1299 reset_scan_trigger(device);
1301 return device->driver->scan(device);
1304 int __connman_device_enable(struct connman_device *device)
1306 enum connman_service_type type;
1309 DBG("device %p", device);
1311 if (!device->driver || !device->driver->enable)
1314 if (device->powered_pending == TRUE)
1317 device->powered_pending = TRUE;
1319 err = device->driver->enable(device);
1323 device->powered = TRUE;
1325 type = __connman_device_get_service_type(device);
1326 __connman_notifier_enable(type);
1331 int __connman_device_enable_persistent(struct connman_device *device)
1333 DBG("device %p", device);
1335 device->powered_persistent = TRUE;
1337 __connman_storage_save_device(device);
1339 return __connman_device_enable(device);
1342 int __connman_device_disable(struct connman_device *device)
1344 enum connman_service_type type;
1347 DBG("device %p", device);
1349 if (!device->driver || !device->driver->disable)
1352 if (device->powered == FALSE)
1355 if (device->powered_pending == FALSE)
1358 device->powered_pending = FALSE;
1360 device->reconnect = FALSE;
1362 clear_scan_trigger(device);
1364 g_hash_table_remove_all(device->networks);
1366 err = device->driver->disable(device);
1370 device->powered = FALSE;
1372 type = __connman_device_get_service_type(device);
1373 __connman_notifier_disable(type);
1378 int __connman_device_disable_persistent(struct connman_device *device)
1380 DBG("device %p", device);
1382 device->powered_persistent = FALSE;
1384 __connman_storage_save_device(device);
1386 return __connman_device_disable(device);
1389 int __connman_device_connect(struct connman_device *device)
1391 DBG("device %p", device);
1393 if (device->disconnected == FALSE)
1396 if (device->driver && device->driver->connect)
1397 device->driver->connect(device);
1402 int __connman_device_disconnect(struct connman_device *device)
1404 GHashTableIter iter;
1405 gpointer key, value;
1407 DBG("device %p", device);
1409 connman_device_set_disconnected(device, TRUE);
1411 g_hash_table_iter_init(&iter, device->networks);
1413 while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
1414 struct connman_network *network = value;
1416 __connman_network_disconnect(network);
1419 if (device->driver && device->driver->disconnect)
1420 device->driver->disconnect(device);
1425 static void mark_network_unavailable(gpointer key, gpointer value,
1428 struct connman_network *network = value;
1430 if (connman_network_get_connected(network) == TRUE)
1433 connman_network_set_available(network, FALSE);
1436 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1439 struct connman_network *network = value;
1441 if (connman_network_get_connected(network) == TRUE)
1444 if (connman_network_get_available(network) == TRUE)
1450 void __connman_device_cleanup_networks(struct connman_device *device)
1452 g_hash_table_foreach_remove(device->networks,
1453 remove_unavailable_network, NULL);
1456 static void scanning_changed(struct connman_device *device)
1458 DBusMessage *signal;
1459 DBusMessageIter entry, value;
1460 const char *key = "Scanning";
1462 signal = dbus_message_new_signal(device->element.path,
1463 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
1467 dbus_message_iter_init_append(signal, &entry);
1469 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
1471 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
1472 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
1473 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
1475 dbus_message_iter_close_container(&entry, &value);
1477 g_dbus_send_message(connection, signal);
1480 static void mark_network_available(gpointer key, gpointer value,
1483 struct connman_network *network = value;
1485 connman_network_set_available(network, TRUE);
1488 void connman_device_cleanup_scanning(struct connman_device *device)
1490 device->scanning = FALSE;
1492 scanning_changed(device);
1494 g_hash_table_foreach(device->networks,
1495 mark_network_available, NULL);
1499 * connman_device_set_scanning:
1500 * @device: device structure
1501 * @scanning: scanning state
1503 * Change scanning state of device
1505 int connman_device_set_scanning(struct connman_device *device,
1506 connman_bool_t scanning)
1508 DBG("device %p scanning %d", device, scanning);
1510 if (!device->driver || !device->driver->scan)
1513 if (device->scanning == scanning)
1516 device->scanning = scanning;
1518 scanning_changed(device);
1520 if (scanning == TRUE) {
1521 reset_scan_trigger(device);
1523 g_hash_table_foreach(device->networks,
1524 mark_network_unavailable, NULL);
1529 __connman_device_cleanup_networks(device);
1531 if (device->connections > 0)
1534 if (device->disconnected == TRUE)
1537 __connman_service_auto_connect();
1543 * connman_device_set_disconnected:
1544 * @device: device structure
1545 * @disconnected: disconnected state
1547 * Change disconnected state of device (only for device with networks)
1549 int connman_device_set_disconnected(struct connman_device *device,
1550 connman_bool_t disconnected)
1552 DBG("device %p disconnected %d", device, disconnected);
1554 switch (device->mode) {
1555 case CONNMAN_DEVICE_MODE_UNKNOWN:
1556 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1558 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1559 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1563 if (device->disconnected == disconnected)
1566 device->disconnected = disconnected;
1568 if (disconnected == TRUE)
1569 force_scan_trigger(device);
1575 * connman_device_get_disconnected:
1576 * @device: device structure
1578 * Get device disconnected state
1580 connman_bool_t connman_device_get_disconnected(struct connman_device *device)
1582 return device->disconnected;
1586 * connman_device_set_connected:
1587 * @device: device structure
1588 * @connected: connected state
1590 * Change connected state of device (for Ethernet like devices)
1592 int connman_device_set_connected(struct connman_device *device,
1593 connman_bool_t connected)
1595 DBG("device %p connected %d", device, connected);
1597 switch (device->mode) {
1598 case CONNMAN_DEVICE_MODE_UNKNOWN:
1599 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1600 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1602 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1606 if (device->carrier == FALSE)
1609 return set_connected(device, connected);
1613 * connman_device_set_string:
1614 * @device: device structure
1615 * @key: unique identifier
1616 * @value: string value
1618 * Set string value for specific key
1620 int connman_device_set_string(struct connman_device *device,
1621 const char *key, const char *value)
1623 DBG("device %p key %s value %s", device, key, value);
1625 if (g_str_equal(key, "Address") == TRUE) {
1626 g_free(device->address);
1627 device->address = g_strdup(value);
1628 } else if (g_str_equal(key, "Name") == TRUE) {
1629 g_free(device->name);
1630 device->name = g_strdup(value);
1631 } else if (g_str_equal(key, "Node") == TRUE) {
1632 g_free(device->node);
1633 device->node = g_strdup(value);
1636 return connman_element_set_string(&device->element, key, value);
1640 * connman_device_get_string:
1641 * @device: device structure
1642 * @key: unique identifier
1644 * Get string value for specific key
1646 const char *connman_device_get_string(struct connman_device *device,
1649 DBG("device %p key %s", device, key);
1651 if (g_str_equal(key, "Address") == TRUE)
1652 return device->address;
1653 else if (g_str_equal(key, "Name") == TRUE)
1654 return device->name;
1655 else if (g_str_equal(key, "Node") == TRUE)
1656 return device->node;
1658 return connman_element_get_string(&device->element, key);
1661 static void set_offlinemode(struct connman_element *element, gpointer user_data)
1663 struct connman_device *device = element->device;
1664 connman_bool_t offlinemode = GPOINTER_TO_UINT(user_data);
1665 connman_bool_t powered;
1667 DBG("element %p name %s", element, element->name);
1672 device->offlinemode = offlinemode;
1674 powered = (offlinemode == TRUE) ? FALSE : TRUE;
1676 if (device->powered == powered)
1679 if (device->powered_persistent == FALSE)
1682 set_powered(device, powered);
1685 int __connman_device_set_offlinemode(connman_bool_t offlinemode)
1687 DBG("offlinmode %d", offlinemode);
1689 __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE,
1690 set_offlinemode, GUINT_TO_POINTER(offlinemode));
1692 __connman_notifier_offlinemode(offlinemode);
1697 void __connman_device_increase_connections(struct connman_device *device)
1699 device->connections++;
1702 void __connman_device_decrease_connections(struct connman_device *device)
1704 device->connections--;
1708 * connman_device_add_network:
1709 * @device: device structure
1710 * @network: network structure
1712 * Add new network to the device
1714 int connman_device_add_network(struct connman_device *device,
1715 struct connman_network *network)
1717 const char *identifier = connman_network_get_identifier(network);
1720 DBG("device %p network %p", device, network);
1722 switch (device->mode) {
1723 case CONNMAN_DEVICE_MODE_UNKNOWN:
1724 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1726 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1727 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1731 __connman_network_set_device(network, device);
1733 err = connman_element_register((struct connman_element *) network,
1736 __connman_network_set_device(network, NULL);
1740 g_hash_table_insert(device->networks, g_strdup(identifier),
1747 * connman_device_get_network:
1748 * @device: device structure
1749 * @identifier: network identifier
1751 * Get network for given identifier
1753 struct connman_network *connman_device_get_network(struct connman_device *device,
1754 const char *identifier)
1756 DBG("device %p identifier %s", device, identifier);
1758 return g_hash_table_lookup(device->networks, identifier);
1762 * connman_device_remove_network:
1763 * @device: device structure
1764 * @identifier: network identifier
1766 * Remove network for given identifier
1768 int connman_device_remove_network(struct connman_device *device,
1769 const char *identifier)
1771 DBG("device %p identifier %s", device, identifier);
1773 g_hash_table_remove(device->networks, identifier);
1778 void __connman_device_set_network(struct connman_device *device,
1779 struct connman_network *network)
1783 if (device->network == network)
1786 if (device->network != NULL)
1787 connman_network_unref(device->network);
1789 if (network != NULL) {
1790 name = connman_network_get_string(network,
1791 CONNMAN_PROPERTY_ID_NAME);
1792 g_free(device->last_network);
1793 device->last_network = g_strdup(name);
1795 device->network = connman_network_ref(network);
1797 g_free(device->last_network);
1798 device->last_network = NULL;
1800 device->network = NULL;
1804 void __connman_device_set_reconnect(struct connman_device *device,
1805 connman_bool_t reconnect)
1807 device->reconnect = reconnect;
1810 connman_bool_t __connman_device_get_reconnect(
1811 struct connman_device *device)
1813 return device->reconnect;
1817 * connman_device_register:
1818 * @device: device structure
1820 * Register device with the system
1822 int connman_device_register(struct connman_device *device)
1824 __connman_storage_load_device(device);
1826 device->offlinemode = __connman_profile_get_offlinemode();
1828 return connman_element_register(&device->element, NULL);
1832 * connman_device_unregister:
1833 * @device: device structure
1835 * Unregister device with the system
1837 void connman_device_unregister(struct connman_device *device)
1839 __connman_storage_save_device(device);
1841 connman_element_unregister(&device->element);
1845 * connman_device_get_data:
1846 * @device: device structure
1848 * Get private device data pointer
1850 void *connman_device_get_data(struct connman_device *device)
1852 return device->driver_data;
1856 * connman_device_set_data:
1857 * @device: device structure
1858 * @data: data pointer
1860 * Set private device data pointer
1862 void connman_device_set_data(struct connman_device *device, void *data)
1864 device->driver_data = data;
1867 static gboolean match_driver(struct connman_device *device,
1868 struct connman_device_driver *driver)
1870 if (device->type == driver->type ||
1871 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1877 static int device_probe(struct connman_element *element)
1879 struct connman_device *device = element->device;
1882 DBG("element %p name %s", element, element->name);
1887 if (device->driver != NULL)
1890 for (list = driver_list; list; list = list->next) {
1891 struct connman_device_driver *driver = list->data;
1893 if (match_driver(device, driver) == FALSE)
1896 DBG("driver %p name %s", driver, driver->name);
1898 if (driver->probe(device) == 0) {
1899 device->driver = driver;
1904 if (device->driver == NULL)
1907 return setup_device(device);
1910 static void device_remove(struct connman_element *element)
1912 struct connman_device *device = element->device;
1914 DBG("element %p name %s", element, element->name);
1919 if (device->driver == NULL)
1922 remove_device(device);
1925 static struct connman_driver device_driver = {
1927 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
1928 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
1929 .probe = device_probe,
1930 .remove = device_remove,
1933 static int device_load(struct connman_device *device)
1935 const char *ident = __connman_profile_active_ident();
1937 GError *error = NULL;
1939 connman_bool_t powered;
1942 DBG("device %p", device);
1944 keyfile = __connman_storage_open(ident);
1945 if (keyfile == NULL)
1948 identifier = g_strdup_printf("device_%s", device->element.name);
1949 if (identifier == NULL)
1952 powered = g_key_file_get_boolean(keyfile, identifier,
1955 device->powered_persistent = powered;
1956 g_clear_error(&error);
1958 switch (device->mode) {
1959 case CONNMAN_DEVICE_MODE_UNKNOWN:
1960 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
1962 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
1963 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
1964 val = g_key_file_get_integer(keyfile, identifier,
1965 "ScanInterval", &error);
1966 if (error == NULL && val > 0)
1967 device->scan_interval = val;
1968 g_clear_error(&error);
1975 __connman_storage_close(ident, keyfile, FALSE);
1980 static int device_save(struct connman_device *device)
1982 const char *ident = __connman_profile_active_ident();
1986 DBG("device %p", device);
1988 keyfile = __connman_storage_open(ident);
1989 if (keyfile == NULL)
1992 identifier = g_strdup_printf("device_%s", device->element.name);
1993 if (identifier == NULL)
1996 g_key_file_set_boolean(keyfile, identifier,
1997 "Powered", device->powered_persistent);
1999 switch (device->mode) {
2000 case CONNMAN_DEVICE_MODE_UNKNOWN:
2001 case CONNMAN_DEVICE_MODE_TRANSPORT_IP:
2003 case CONNMAN_DEVICE_MODE_NETWORK_SINGLE:
2004 case CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE:
2005 if (device->scan_interval > 0)
2006 g_key_file_set_integer(keyfile, identifier,
2007 "ScanInterval", device->scan_interval);
2014 __connman_storage_close(ident, keyfile, TRUE);
2019 static struct connman_storage device_storage = {
2021 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
2022 .device_load = device_load,
2023 .device_save = device_save,
2026 int __connman_device_init(void)
2030 connection = connman_dbus_get_connection();
2032 if (connman_storage_register(&device_storage) < 0)
2033 connman_error("Failed to register device storage");
2035 return connman_driver_register(&device_driver);
2038 void __connman_device_cleanup(void)
2042 connman_driver_unregister(&device_driver);
2044 connman_storage_unregister(&device_storage);
2046 dbus_connection_unref(connection);