5 * Copyright (C) 2007-2008 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 struct connman_device {
32 struct connman_element element;
33 enum connman_device_type type;
34 enum connman_device_policy policy;
41 struct connman_device_driver *driver;
47 static const char *type2description(enum connman_device_type type)
50 case CONNMAN_DEVICE_TYPE_ETHERNET:
52 case CONNMAN_DEVICE_TYPE_WIFI:
54 case CONNMAN_DEVICE_TYPE_WIMAX:
56 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
63 static const char *type2string(enum connman_device_type type)
66 case CONNMAN_DEVICE_TYPE_ETHERNET:
68 case CONNMAN_DEVICE_TYPE_WIFI:
70 case CONNMAN_DEVICE_TYPE_WIMAX:
72 case CONNMAN_DEVICE_TYPE_MODEM:
74 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
81 static const char *policy2string(enum connman_device_policy policy)
84 case CONNMAN_DEVICE_POLICY_IGNORE:
86 case CONNMAN_DEVICE_POLICY_AUTO:
88 case CONNMAN_DEVICE_POLICY_OFF:
95 static int set_powered(struct connman_device *device, gboolean powered)
97 struct connman_device_driver *driver = device->driver;
100 DBG("device %p powered %d", device, powered);
105 if (powered == TRUE) {
107 err = driver->enable(device);
112 err = driver->disable(device);
120 static DBusMessage *get_properties(DBusConnection *conn,
121 DBusMessage *msg, void *data)
123 struct connman_device *device = data;
125 DBusMessageIter array, dict;
128 DBG("conn %p", conn);
130 reply = dbus_message_new_method_return(msg);
134 dbus_message_iter_init_append(reply, &array);
136 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
137 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
138 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
139 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
141 str = type2description(device->type);
142 if (str != NULL && device->interface != NULL) {
143 char *name = g_strdup_printf("%s (%s)", str, device->interface);
145 connman_dbus_dict_append_variant(&dict, "Name",
146 DBUS_TYPE_STRING, &name);
150 str = type2string(device->type);
152 connman_dbus_dict_append_variant(&dict, "Type",
153 DBUS_TYPE_STRING, &str);
155 if (device->interface != NULL)
156 connman_dbus_dict_append_variant(&dict, "Interface",
157 DBUS_TYPE_STRING, &device->interface);
159 str = policy2string(device->policy);
161 connman_dbus_dict_append_variant(&dict, "Policy",
162 DBUS_TYPE_STRING, &str);
164 connman_dbus_dict_append_variant(&dict, "Powered",
165 DBUS_TYPE_BOOLEAN, &device->powered);
167 if (device->driver && device->driver->scan)
168 connman_dbus_dict_append_variant(&dict, "Scanning",
169 DBUS_TYPE_BOOLEAN, &device->scanning);
171 dbus_message_iter_close_container(&array, &dict);
176 static DBusMessage *set_property(DBusConnection *conn,
177 DBusMessage *msg, void *data)
179 struct connman_device *device = data;
180 DBusMessageIter iter, value;
183 DBG("conn %p", conn);
185 if (dbus_message_iter_init(msg, &iter) == FALSE)
186 return __connman_error_invalid_arguments(msg);
188 dbus_message_iter_get_basic(&iter, &name);
189 dbus_message_iter_next(&iter);
190 dbus_message_iter_recurse(&iter, &value);
192 if (__connman_security_check_privileges(msg) < 0)
193 return __connman_error_permission_denied(msg);
195 if (g_str_equal(name, "Powered") == TRUE) {
199 dbus_message_iter_get_basic(&value, &powered);
201 if (device->powered == powered)
202 return __connman_error_invalid_arguments(msg);
204 err = set_powered(device, powered);
205 if (err < 0 && err != -EINPROGRESS)
206 return __connman_error_failed(msg);
209 __connman_element_store(&device->element);
211 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
214 static DBusMessage *create_network(DBusConnection *conn,
215 DBusMessage *msg, void *data)
217 DBG("conn %p", conn);
219 if (__connman_security_check_privileges(msg) < 0)
220 return __connman_error_permission_denied(msg);
222 return __connman_error_invalid_arguments(msg);
225 static DBusMessage *remove_network(DBusConnection *conn,
226 DBusMessage *msg, void *data)
228 DBG("conn %p", conn);
230 if (__connman_security_check_privileges(msg) < 0)
231 return __connman_error_permission_denied(msg);
233 return __connman_error_invalid_arguments(msg);
236 static DBusMessage *propose_scan(DBusConnection *conn,
237 DBusMessage *msg, void *data)
239 DBG("conn %p", conn);
241 return __connman_error_not_supported(msg);
244 static GDBusMethodTable device_methods[] = {
245 { "GetProperties", "", "a{sv}", get_properties },
246 { "SetProperty", "sv", "", set_property },
247 { "CreateNetwork", "a{sv}", "o", create_network },
248 { "RemoveNetwork", "o", "", remove_network },
249 { "ProposeScan", "", "", propose_scan },
253 static GDBusSignalTable device_signals[] = {
254 { "PropertyChanged", "sv" },
258 static DBusConnection *connection;
260 static int register_interface(struct connman_element *element)
262 struct connman_device *device = element->device;
264 g_dbus_unregister_interface(connection, element->path,
265 CONNMAN_DEVICE_INTERFACE);
267 if (g_dbus_register_interface(connection, element->path,
268 CONNMAN_DEVICE_INTERFACE,
269 device_methods, device_signals,
270 NULL, device, NULL) == FALSE) {
271 connman_error("Failed to register %s device", element->path);
278 static void unregister_interface(struct connman_element *element)
280 g_dbus_unregister_interface(connection, element->path,
281 CONNMAN_DEVICE_INTERFACE);
284 static GSList *driver_list = NULL;
286 static gint compare_priority(gconstpointer a, gconstpointer b)
288 const struct connman_device_driver *driver1 = a;
289 const struct connman_device_driver *driver2 = b;
291 return driver2->priority - driver1->priority;
295 * connman_device_driver_register:
296 * @driver: device driver definition
298 * Register a new device driver
300 * Returns: %0 on success
302 int connman_device_driver_register(struct connman_device_driver *driver)
304 DBG("driver %p name %s", driver, driver->name);
306 driver_list = g_slist_insert_sorted(driver_list, driver,
309 //__connman_driver_rescan(&device_driver);
315 * connman_device_driver_unregister:
316 * @driver: device driver definition
318 * Remove a previously registered device driver
320 void connman_device_driver_unregister(struct connman_device_driver *driver)
322 DBG("driver %p name %s", driver, driver->name);
324 driver_list = g_slist_remove(driver_list, driver);
327 static void device_destruct(struct connman_element *element)
329 struct connman_device *device = element->device;
331 DBG("element %p name %s", element, element->name);
333 g_free(device->interface);
337 * connman_device_create:
338 * @node: device node name (for example an address)
341 * Allocate a new device of given #type and assign the #node name to it.
343 * Returns: a newly-allocated #connman_device structure
345 struct connman_device *connman_device_create(const char *node,
346 enum connman_device_type type)
348 struct connman_device *device;
350 DBG("node %s type %d", node, type);
352 device = g_try_new0(struct connman_device, 1);
356 DBG("device %p", device);
358 device->element.name = g_strdup(node);
359 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
360 device->element.index = -1;
362 device->element.device = device;
363 device->element.destruct = device_destruct;
366 device->policy = CONNMAN_DEVICE_POLICY_AUTO;
372 * connman_device_ref:
373 * @device: device structure
375 * Increase reference counter of device
377 struct connman_device *connman_device_ref(struct connman_device *device)
379 if (connman_element_ref(&device->element) == NULL)
386 * connman_device_unref:
387 * @device: device structure
389 * Decrease reference counter of device
391 void connman_device_unref(struct connman_device *device)
393 connman_element_unref(&device->element);
397 * connman_device_set_path:
398 * @device: device structure
401 * Set path name of device
403 void connman_device_set_path(struct connman_device *device, const char *path)
405 g_free(device->element.devpath);
406 device->element.devpath = g_strdup(path);
408 g_free(device->path);
409 device->path = g_strdup(path);
413 * connman_device_get_path:
414 * @device: device structure
416 * Get path name of device
418 const char *connman_device_get_path(struct connman_device *device)
424 * connman_device_set_index:
425 * @device: device structure
426 * @index: index number
428 * Set index number of device
430 void connman_device_set_index(struct connman_device *device, int index)
432 device->element.index = index;
436 * connman_device_get_index:
437 * @device: device structure
439 * Get index number of device
441 int connman_device_get_index(struct connman_device *device)
443 return device->element.index;
447 * connman_device_set_interface:
448 * @device: device structure
449 * @interface: interface name
451 * Set interface name of device
453 void connman_device_set_interface(struct connman_device *device,
454 const char *interface)
456 g_free(device->element.devname);
457 device->element.devname = g_strdup(interface);
459 g_free(device->interface);
460 device->interface = g_strdup(interface);
464 * connman_device_get_interface:
465 * @device: device structure
467 * Get interface name of device
469 const char *connman_device_get_interface(struct connman_device *device)
471 return device->interface;
475 * connman_device_set_powered:
476 * @device: device structure
477 * @powered: powered state
479 * Change power state of device
481 int connman_device_set_powered(struct connman_device *device,
485 DBusMessageIter entry, value;
486 const char *key = "Powered";
488 DBG("driver %p powered %d", device, powered);
490 if (device->powered == powered)
493 device->powered = powered;
495 signal = dbus_message_new_signal(device->element.path,
496 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
500 dbus_message_iter_init_append(signal, &entry);
502 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
504 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
505 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
506 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &powered);
507 dbus_message_iter_close_container(&entry, &value);
509 g_dbus_send_message(connection, signal);
515 * connman_device_set_carrier:
516 * @device: device structure
517 * @carrier: carrier state
519 * Change carrier state of device (only for device without scanning)
521 int connman_device_set_carrier(struct connman_device *device,
524 DBG("driver %p carrier %d", device, carrier);
529 if (device->driver->scan)
532 if (device->carrier == carrier)
535 device->carrier = carrier;
537 if (carrier == TRUE) {
538 struct connman_element *element;
540 element = connman_element_create(NULL);
541 if (element != NULL) {
542 element->type = CONNMAN_ELEMENT_TYPE_DEVICE;
543 element->subtype = CONNMAN_ELEMENT_SUBTYPE_NETWORK;
544 element->index = device->element.index;
546 if (connman_element_register(element,
547 &device->element) < 0)
548 connman_element_unref(element);
551 connman_element_unregister_children(&device->element);
557 * connman_device_set_scanning:
558 * @device: device structure
559 * @scanning: scanning state
561 * Change scanning state of device
563 int connman_device_set_scanning(struct connman_device *device,
567 DBusMessageIter entry, value;
568 const char *key = "Scanning";
570 DBG("driver %p scanning %d", device, scanning);
575 if (!device->driver->scan)
578 if (device->scanning == scanning)
581 device->scanning = scanning;
583 signal = dbus_message_new_signal(device->element.path,
584 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
588 dbus_message_iter_init_append(signal, &entry);
590 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
592 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
593 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
594 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &scanning);
595 dbus_message_iter_close_container(&entry, &value);
597 g_dbus_send_message(connection, signal);
603 * connman_device_register:
604 * @device: device structure
606 * Register device with the system
608 int connman_device_register(struct connman_device *device)
610 return connman_element_register(&device->element, NULL);
614 * connman_device_unregister:
615 * @device: device structure
617 * Unregister device with the system
619 void connman_device_unregister(struct connman_device *device)
621 connman_element_unregister(&device->element);
625 * connman_device_get_data:
626 * @device: device structure
628 * Get private device data pointer
630 void *connman_device_get_data(struct connman_device *device)
632 return device->driver_data;
636 * connman_device_set_data:
637 * @device: device structure
638 * @data: data pointer
640 * Set private device data pointer
642 void connman_device_set_data(struct connman_device *device, void *data)
644 device->driver_data = data;
647 static void device_enable(struct connman_device *device)
649 DBG("device %p", device);
651 if (device->policy != CONNMAN_DEVICE_POLICY_AUTO)
654 if (device->powered == TRUE)
657 if (device->driver->enable)
658 device->driver->enable(device);
661 static void device_disable(struct connman_device *device)
663 DBG("device %p", device);
665 if (device->policy != CONNMAN_DEVICE_POLICY_AUTO)
668 if (device->powered == FALSE)
671 if (device->driver->disable)
672 device->driver->disable(device);
675 static gboolean match_driver(struct connman_device *device,
676 struct connman_device_driver *driver)
678 if (device->type == driver->type ||
679 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
685 static int device_probe(struct connman_element *element)
687 struct connman_device *device = element->device;
691 DBG("element %p name %s", element, element->name);
696 err = register_interface(element);
700 for (list = driver_list; list; list = list->next) {
701 struct connman_device_driver *driver = list->data;
703 if (match_driver(device, driver) == FALSE)
706 DBG("driver %p name %s", driver, driver->name);
708 if (driver->probe(device) == 0) {
709 device->driver = driver;
710 device_enable(device);
718 static void device_remove(struct connman_element *element)
720 struct connman_device *device = element->device;
722 DBG("element %p name %s", element, element->name);
727 unregister_interface(element);
729 if (device->driver) {
730 device_disable(device);
732 if (device->driver->remove)
733 device->driver->remove(device);
737 static struct connman_driver device_driver = {
739 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
740 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
741 .probe = device_probe,
742 .remove = device_remove,
745 int __connman_device_init(void)
749 connection = connman_dbus_get_connection();
751 return connman_driver_register(&device_driver);
754 void __connman_device_cleanup(void)
758 connman_driver_unregister(&device_driver);
760 dbus_connection_unref(connection);