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 static const char *type2string(enum connman_device_type type)
34 case CONNMAN_DEVICE_TYPE_ETHERNET:
36 case CONNMAN_DEVICE_TYPE_WIFI:
38 case CONNMAN_DEVICE_TYPE_WIMAX:
40 case CONNMAN_DEVICE_TYPE_MODEM:
42 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
49 static int set_powered(struct connman_device *device, gboolean powered)
51 struct connman_device_driver *driver = device->driver;
54 DBG("device %p powered %d", device, powered);
59 if (powered == TRUE) {
61 err = driver->enable(device);
66 err = driver->disable(device);
74 static DBusMessage *get_properties(DBusConnection *conn,
75 DBusMessage *msg, void *data)
77 struct connman_device *device = data;
79 DBusMessageIter array, dict;
84 reply = dbus_message_new_method_return(msg);
88 dbus_message_iter_init_append(reply, &array);
90 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
91 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
92 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
93 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
95 str = type2string(device->type);
97 connman_dbus_dict_append_variant(&dict, "Type",
98 DBUS_TYPE_STRING, &str);
100 connman_dbus_dict_append_variant(&dict, "Powered",
101 DBUS_TYPE_BOOLEAN, &device->powered);
103 if (device->driver && device->driver->scan)
104 connman_dbus_dict_append_variant(&dict, "Scanning",
105 DBUS_TYPE_BOOLEAN, &device->scanning);
107 dbus_message_iter_close_container(&array, &dict);
112 static DBusMessage *set_property(DBusConnection *conn,
113 DBusMessage *msg, void *data)
115 struct connman_device *device = data;
116 DBusMessageIter iter, value;
119 DBG("conn %p", conn);
121 if (dbus_message_iter_init(msg, &iter) == FALSE)
122 return __connman_error_invalid_arguments(msg);
124 dbus_message_iter_get_basic(&iter, &name);
125 dbus_message_iter_next(&iter);
126 dbus_message_iter_recurse(&iter, &value);
128 if (__connman_security_check_privileges(msg) < 0)
129 return __connman_error_permission_denied(msg);
131 if (g_str_equal(name, "Powered") == TRUE) {
135 dbus_message_iter_get_basic(&value, &powered);
137 if (device->powered == powered)
138 return __connman_error_invalid_arguments(msg);
140 err = set_powered(device, powered);
141 if (err < 0 && err != -EINPROGRESS)
142 return __connman_error_failed(msg);
145 __connman_element_store(device->element);
147 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
150 static DBusMessage *create_network(DBusConnection *conn,
151 DBusMessage *msg, void *data)
153 DBG("conn %p", conn);
155 if (__connman_security_check_privileges(msg) < 0)
156 return __connman_error_permission_denied(msg);
158 return __connman_error_invalid_arguments(msg);
161 static DBusMessage *remove_network(DBusConnection *conn,
162 DBusMessage *msg, void *data)
164 DBG("conn %p", conn);
166 if (__connman_security_check_privileges(msg) < 0)
167 return __connman_error_permission_denied(msg);
169 return __connman_error_invalid_arguments(msg);
172 static DBusMessage *propose_scan(DBusConnection *conn,
173 DBusMessage *msg, void *data)
175 DBG("conn %p", conn);
177 return __connman_error_failed(msg);
180 static GDBusMethodTable device_methods[] = {
181 { "GetProperties", "", "a{sv}", get_properties },
182 { "SetProperty", "sv", "", set_property },
183 { "CreateNetwork", "a{sv}", "o", create_network },
184 { "RemoveNetwork", "o", "", remove_network },
185 { "ProposeScan", "", "", propose_scan },
189 static GDBusSignalTable device_signals[] = {
190 { "PropertyChanged", "sv" },
194 static DBusConnection *connection;
196 static int register_interface(struct connman_element *element)
198 struct connman_device *device = connman_element_get_data(element);
200 g_dbus_unregister_interface(connection, element->path,
201 CONNMAN_DEVICE_INTERFACE);
203 if (g_dbus_register_interface(connection, element->path,
204 CONNMAN_DEVICE_INTERFACE,
205 device_methods, device_signals,
206 NULL, device, NULL) == FALSE) {
207 connman_error("Failed to register %s device", element->path);
214 static void unregister_interface(struct connman_element *element)
216 g_dbus_unregister_interface(connection, element->path,
217 CONNMAN_DEVICE_INTERFACE);
220 static GSList *driver_list = NULL;
222 static gint compare_priority(gconstpointer a, gconstpointer b)
224 const struct connman_device_driver *driver1 = a;
225 const struct connman_device_driver *driver2 = b;
227 return driver2->priority - driver1->priority;
231 * connman_device_driver_register:
232 * @driver: device driver definition
234 * Register a new device driver
236 * Returns: %0 on success
238 int connman_device_driver_register(struct connman_device_driver *driver)
240 DBG("driver %p name %s", driver, driver->name);
242 driver_list = g_slist_insert_sorted(driver_list, driver,
245 //__connman_driver_rescan(&device_driver);
251 * connman_device_driver_unregister:
252 * @driver: device driver definition
254 * Remove a previously registered device driver
256 void connman_device_driver_unregister(struct connman_device_driver *driver)
258 DBG("driver %p name %s", driver, driver->name);
260 driver_list = g_slist_remove(driver_list, driver);
264 * connman_device_set_powered:
265 * @device: device structure
267 * Change power state of device
269 int connman_device_set_powered(struct connman_device *device,
273 DBusMessageIter entry, value;
274 const char *key = "Powered";
276 DBG("driver %p powered %d", device, powered);
278 if (device->powered == powered)
281 device->powered = powered;
283 signal = dbus_message_new_signal(device->element->path,
284 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
288 dbus_message_iter_init_append(signal, &entry);
290 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
292 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
293 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
294 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &powered);
295 dbus_message_iter_close_container(&entry, &value);
297 g_dbus_send_message(connection, signal);
303 * connman_device_set_scanning:
304 * @device: device structure
306 * Change scanning state of device
308 int connman_device_set_scanning(struct connman_device *device,
312 DBusMessageIter entry, value;
313 const char *key = "Scanning";
315 DBG("driver %p scanning %d", device, scanning);
320 if (!device->driver->scan)
323 if (device->scanning == scanning)
326 device->scanning = scanning;
328 signal = dbus_message_new_signal(device->element->path,
329 CONNMAN_DEVICE_INTERFACE, "PropertyChanged");
333 dbus_message_iter_init_append(signal, &entry);
335 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
337 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
338 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
339 dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &scanning);
340 dbus_message_iter_close_container(&entry, &value);
342 g_dbus_send_message(connection, signal);
347 static gboolean match_driver(struct connman_device *device,
348 struct connman_device_driver *driver)
350 if (device->element->subtype == driver->type ||
351 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
357 static int device_probe(struct connman_element *element)
359 struct connman_device *device;
363 DBG("element %p name %s", element, element->name);
365 if (element->subtype == CONNMAN_ELEMENT_SUBTYPE_NETWORK)
368 device = g_try_new0(struct connman_device, 1);
372 device->element = element;
373 device->type = element->subtype;
375 connman_element_set_data(element, device);
377 err = register_interface(element);
383 for (list = driver_list; list; list = list->next) {
384 struct connman_device_driver *driver = list->data;
386 if (match_driver(device, driver) == FALSE)
389 DBG("driver %p name %s", driver, driver->name);
391 if (driver->probe(device) == 0) {
392 device->driver = driver;
400 static void device_remove(struct connman_element *element)
402 struct connman_device *device = connman_element_get_data(element);
404 DBG("element %p name %s", element, element->name);
406 unregister_interface(element);
408 if (device->driver && device->driver->remove)
409 device->driver->remove(device);
411 connman_element_set_data(element, NULL);
416 static struct connman_driver device_driver = {
418 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
419 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
420 .probe = device_probe,
421 .remove = device_remove,
424 int __connman_device_init(void)
428 connection = connman_dbus_get_connection();
430 return connman_driver_register(&device_driver);
433 void __connman_device_cleanup(void)
437 connman_driver_unregister(&device_driver);
439 dbus_connection_unref(connection);