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 *type2string(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_MODEM:
58 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
65 static const char *policy2string(enum connman_device_policy policy)
68 case CONNMAN_DEVICE_POLICY_IGNORE:
70 case CONNMAN_DEVICE_POLICY_AUTO:
72 case CONNMAN_DEVICE_POLICY_OFF:
79 static int set_powered(struct connman_device *device, gboolean powered)
81 struct connman_device_driver *driver = device->driver;
84 DBG("device %p powered %d", device, powered);
89 if (powered == TRUE) {
91 err = driver->enable(device);
96 err = driver->disable(device);
104 static DBusMessage *get_properties(DBusConnection *conn,
105 DBusMessage *msg, void *data)
107 struct connman_device *device = data;
109 DBusMessageIter array, dict;
112 DBG("conn %p", conn);
114 reply = dbus_message_new_method_return(msg);
118 dbus_message_iter_init_append(reply, &array);
120 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
121 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
122 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
123 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
125 str = type2string(device->type);
127 connman_dbus_dict_append_variant(&dict, "Type",
128 DBUS_TYPE_STRING, &str);
130 if (device->interface != NULL)
131 connman_dbus_dict_append_variant(&dict, "Interface",
132 DBUS_TYPE_STRING, &device->interface);
134 str = policy2string(device->policy);
136 connman_dbus_dict_append_variant(&dict, "Policy",
137 DBUS_TYPE_STRING, &str);
139 connman_dbus_dict_append_variant(&dict, "Powered",
140 DBUS_TYPE_BOOLEAN, &device->powered);
142 if (device->driver && device->driver->scan)
143 connman_dbus_dict_append_variant(&dict, "Scanning",
144 DBUS_TYPE_BOOLEAN, &device->scanning);
146 dbus_message_iter_close_container(&array, &dict);
151 static DBusMessage *set_property(DBusConnection *conn,
152 DBusMessage *msg, void *data)
154 struct connman_device *device = data;
155 DBusMessageIter iter, value;
158 DBG("conn %p", conn);
160 if (dbus_message_iter_init(msg, &iter) == FALSE)
161 return __connman_error_invalid_arguments(msg);
163 dbus_message_iter_get_basic(&iter, &name);
164 dbus_message_iter_next(&iter);
165 dbus_message_iter_recurse(&iter, &value);
167 if (__connman_security_check_privileges(msg) < 0)
168 return __connman_error_permission_denied(msg);
170 if (g_str_equal(name, "Powered") == TRUE) {
174 dbus_message_iter_get_basic(&value, &powered);
176 if (device->powered == powered)
177 return __connman_error_invalid_arguments(msg);
179 err = set_powered(device, powered);
180 if (err < 0 && err != -EINPROGRESS)
181 return __connman_error_failed(msg);
184 __connman_element_store(&device->element);
186 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
189 static DBusMessage *create_network(DBusConnection *conn,
190 DBusMessage *msg, void *data)
192 DBG("conn %p", conn);
194 if (__connman_security_check_privileges(msg) < 0)
195 return __connman_error_permission_denied(msg);
197 return __connman_error_invalid_arguments(msg);
200 static DBusMessage *remove_network(DBusConnection *conn,
201 DBusMessage *msg, void *data)
203 DBG("conn %p", conn);
205 if (__connman_security_check_privileges(msg) < 0)
206 return __connman_error_permission_denied(msg);
208 return __connman_error_invalid_arguments(msg);
211 static DBusMessage *propose_scan(DBusConnection *conn,
212 DBusMessage *msg, void *data)
214 DBG("conn %p", conn);
216 return __connman_error_failed(msg);
219 static GDBusMethodTable device_methods[] = {
220 { "GetProperties", "", "a{sv}", get_properties },
221 { "SetProperty", "sv", "", set_property },
222 { "CreateNetwork", "a{sv}", "o", create_network },
223 { "RemoveNetwork", "o", "", remove_network },
224 { "ProposeScan", "", "", propose_scan },
228 static GDBusSignalTable device_signals[] = {
229 { "PropertyChanged", "sv" },
233 static DBusConnection *connection;
235 static int register_interface(struct connman_element *element)
237 struct connman_device *device = element->device;
239 g_dbus_unregister_interface(connection, element->path,
240 CONNMAN_DEVICE_INTERFACE);
242 if (g_dbus_register_interface(connection, element->path,
243 CONNMAN_DEVICE_INTERFACE,
244 device_methods, device_signals,
245 NULL, device, NULL) == FALSE) {
246 connman_error("Failed to register %s device", element->path);
253 static void unregister_interface(struct connman_element *element)
255 g_dbus_unregister_interface(connection, element->path,
256 CONNMAN_DEVICE_INTERFACE);
259 static GSList *driver_list = NULL;
261 static gint compare_priority(gconstpointer a, gconstpointer b)
263 const struct connman_device_driver *driver1 = a;
264 const struct connman_device_driver *driver2 = b;
266 return driver2->priority - driver1->priority;
270 * connman_device_driver_register:
271 * @driver: device driver definition
273 * Register a new device driver
275 * Returns: %0 on success
277 int connman_device_driver_register(struct connman_device_driver *driver)
279 DBG("driver %p name %s", driver, driver->name);
281 driver_list = g_slist_insert_sorted(driver_list, driver,
284 //__connman_driver_rescan(&device_driver);
290 * connman_device_driver_unregister:
291 * @driver: device driver definition
293 * Remove a previously registered device driver
295 void connman_device_driver_unregister(struct connman_device_driver *driver)
297 DBG("driver %p name %s", driver, driver->name);
299 driver_list = g_slist_remove(driver_list, driver);
302 static void device_destruct(struct connman_element *element)
304 struct connman_device *device = element->device;
306 DBG("element %p name %s", element, element->name);
308 g_free(device->interface);
312 * connman_device_create:
313 * @node: device node name (for example an address)
316 * Allocate a new device of given #type and assign the #node name to it.
318 * Returns: a newly-allocated #connman_device structure
320 struct connman_device *connman_device_create(const char *node,
321 enum connman_device_type type)
323 struct connman_device *device;
325 DBG("node %s type %d", node, type);
327 device = g_try_new0(struct connman_device, 1);
331 DBG("device %p", device);
333 device->element.name = g_strdup(node);
334 device->element.type = CONNMAN_ELEMENT_TYPE_DEVICE;
335 device->element.index = -1;
337 device->element.device = device;
338 device->element.destruct = device_destruct;
341 device->policy = CONNMAN_DEVICE_POLICY_AUTO;
347 * connman_device_ref:
348 * @device: device structure
350 * Increase reference counter of device
352 struct connman_device *connman_device_ref(struct connman_device *device)
354 if (connman_element_ref(&device->element) == NULL)
361 * connman_device_unref:
362 * @device: device structure
364 * Decrease reference counter of device
366 void connman_device_unref(struct connman_device *device)
368 connman_element_unref(&device->element);
372 * connman_device_set_path:
373 * @device: device structure
376 * Set path name of device
378 void connman_device_set_path(struct connman_device *device, const char *path)
380 g_free(device->element.devpath);
381 device->element.devpath = g_strdup(path);
383 g_free(device->path);
384 device->path = g_strdup(path);
388 * connman_device_get_path:
389 * @device: device structure
391 * Get path name of device
393 const char *connman_device_get_path(struct connman_device *device)
399 * connman_device_set_index:
400 * @device: device structure
401 * @index: index number
403 * Set index number of device
405 void connman_device_set_index(struct connman_device *device, int index)
407 device->element.index = index;
411 * connman_device_get_index:
412 * @device: device structure
414 * Get index number of device
416 int connman_device_get_index(struct connman_device *device)
418 return device->element.index;
422 * connman_device_set_interface:
423 * @device: device structure
424 * @interface: interface name
426 * Set interface name of device
428 void connman_device_set_interface(struct connman_device *device,
429 const char *interface)
431 g_free(device->element.devname);
432 device->element.devname = g_strdup(interface);
434 g_free(device->interface);
435 device->interface = g_strdup(interface);
439 * connman_device_get_interface:
440 * @device: device structure
442 * Get interface name of device
444 const char *connman_device_get_interface(struct connman_device *device)
446 return device->interface;
450 * connman_device_set_powered:
451 * @device: device structure
452 * @powered: powered state
454 * Change power state of device
456 int connman_device_set_powered(struct connman_device *device,
460 DBusMessageIter entry, value;
461 const char *key = "Powered";
463 DBG("driver %p powered %d", device, powered);
465 if (device->powered == powered)
468 device->powered = powered;
470 signal = dbus_message_new_signal(device->element.path,
471 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
475 dbus_message_iter_init_append(signal, &entry);
477 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
479 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
480 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
481 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &powered);
482 dbus_message_iter_close_container(&entry, &value);
484 g_dbus_send_message(connection, signal);
490 * connman_device_set_carrier:
491 * @device: device structure
492 * @carrier: carrier state
494 * Change carrier state of device (only for device without scanning)
496 int connman_device_set_carrier(struct connman_device *device,
499 DBG("driver %p carrier %d", device, carrier);
504 if (device->driver->scan)
507 if (device->carrier == carrier)
510 device->carrier = carrier;
512 if (carrier == TRUE) {
513 struct connman_element *element;
515 element = connman_element_create(NULL);
516 if (element != NULL) {
517 element->type = CONNMAN_ELEMENT_TYPE_DEVICE;
518 element->subtype = CONNMAN_ELEMENT_SUBTYPE_NETWORK;
519 element->index = device->element.index;
521 if (connman_element_register(element,
522 &device->element) < 0)
523 connman_element_unref(element);
526 connman_element_unregister_children(&device->element);
532 * connman_device_set_scanning:
533 * @device: device structure
534 * @scanning: scanning state
536 * Change scanning state of device
538 int connman_device_set_scanning(struct connman_device *device,
542 DBusMessageIter entry, value;
543 const char *key = "Scanning";
545 DBG("driver %p scanning %d", device, scanning);
550 if (!device->driver->scan)
553 if (device->scanning == scanning)
556 device->scanning = scanning;
558 signal = dbus_message_new_signal(device->element.path,
559 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
563 dbus_message_iter_init_append(signal, &entry);
565 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
567 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
568 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
569 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &scanning);
570 dbus_message_iter_close_container(&entry, &value);
572 g_dbus_send_message(connection, signal);
578 * connman_device_register:
579 * @device: device structure
581 * Register device with the system
583 int connman_device_register(struct connman_device *device)
585 return connman_element_register(&device->element, NULL);
589 * connman_device_unregister:
590 * @device: device structure
592 * Unregister device with the system
594 void connman_device_unregister(struct connman_device *device)
596 connman_element_unregister(&device->element);
600 * connman_device_get_data:
601 * @device: device structure
603 * Get private device data pointer
605 void *connman_device_get_data(struct connman_device *device)
607 return device->driver_data;
611 * connman_device_set_data:
612 * @device: device structure
613 * @data: data pointer
615 * Set private device data pointer
617 void connman_device_set_data(struct connman_device *device, void *data)
619 device->driver_data = data;
622 static void device_enable(struct connman_device *device)
624 DBG("device %p", device);
626 if (device->policy != CONNMAN_DEVICE_POLICY_AUTO)
629 if (device->powered == TRUE)
632 if (device->driver->enable)
633 device->driver->enable(device);
636 static void device_disable(struct connman_device *device)
638 DBG("device %p", device);
640 if (device->policy != CONNMAN_DEVICE_POLICY_AUTO)
643 if (device->powered == FALSE)
646 if (device->driver->disable)
647 device->driver->disable(device);
650 static gboolean match_driver(struct connman_device *device,
651 struct connman_device_driver *driver)
653 if (device->type == driver->type ||
654 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
660 static int device_probe(struct connman_element *element)
662 struct connman_device *device = element->device;
666 DBG("element %p name %s", element, element->name);
671 err = register_interface(element);
675 for (list = driver_list; list; list = list->next) {
676 struct connman_device_driver *driver = list->data;
678 if (match_driver(device, driver) == FALSE)
681 DBG("driver %p name %s", driver, driver->name);
683 if (driver->probe(device) == 0) {
684 device->driver = driver;
685 device_enable(device);
693 static void device_remove(struct connman_element *element)
695 struct connman_device *device = element->device;
697 DBG("element %p name %s", element, element->name);
702 unregister_interface(element);
704 if (device->driver) {
705 device_disable(device);
707 if (device->driver->remove)
708 device->driver->remove(device);
712 static struct connman_driver device_driver = {
714 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
715 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
716 .probe = device_probe,
717 .remove = device_remove,
720 int __connman_device_init(void)
724 connection = connman_dbus_get_connection();
726 return connman_driver_register(&device_driver);
729 void __connman_device_cleanup(void)
733 connman_driver_unregister(&device_driver);
735 dbus_connection_unref(connection);