From 05f8d1bc5fe81a9024f5915d72f8338dbb7351a7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Jul 2009 16:05:08 +0200 Subject: [PATCH] Add full support for enable/disable technology methods --- src/connman.h | 4 +++ src/device.c | 26 ++++++++++++++++ src/element.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/manager.c | 54 ++++++++++++++++++++++++++++++-- 4 files changed, 180 insertions(+), 2 deletions(-) diff --git a/src/connman.h b/src/connman.h index b3aa487..85d6d3e 100644 --- a/src/connman.h +++ b/src/connman.h @@ -167,6 +167,8 @@ const char *__connman_element_get_network_path(struct connman_element *element); struct connman_device *__connman_element_find_device(enum connman_device_type type); int __connman_element_request_scan(enum connman_device_type type); +int __connman_element_enable_technology(enum connman_device_type type); +int __connman_element_disable_technology(enum connman_device_type type); const char *__connman_element_type2string(enum connman_element_type type); @@ -209,6 +211,8 @@ void __connman_device_set_network(struct connman_device *device, void __connman_device_cleanup_networks(struct connman_device *device); int __connman_device_scan(struct connman_device *device); +int __connman_device_enable(struct connman_device *device); +int __connman_device_disable(struct connman_device *device); int __connman_device_connect(struct connman_device *device); int __connman_device_disconnect(struct connman_device *device); diff --git a/src/device.c b/src/device.c index c05fada..248c041 100644 --- a/src/device.c +++ b/src/device.c @@ -1390,6 +1390,32 @@ int __connman_device_scan(struct connman_device *device) return device->driver->scan(device); } +int __connman_device_enable(struct connman_device *device) +{ + if (!device->driver || !device->driver->enable) + return -EOPNOTSUPP; + + if (device->powered == TRUE) + return -EALREADY; + + device_enable(device); + + return 0; +} + +int __connman_device_disable(struct connman_device *device) +{ + if (!device->driver || !device->driver->disable) + return -EOPNOTSUPP; + + if (device->powered == FALSE) + return -ENOLINK; + + device_disable(device); + + return 0; +} + int __connman_device_connect(struct connman_device *device) { DBG("device %p", device); diff --git a/src/element.c b/src/element.c index 3545e17..3adbf46 100644 --- a/src/element.c +++ b/src/element.c @@ -413,6 +413,104 @@ int __connman_element_request_scan(enum connman_device_type type) return 0; } +static gboolean enable_technology(GNode *node, gpointer user_data) +{ + struct connman_element *element = node->data; + struct find_data *data = user_data; + enum connman_device_type type; + + if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE) + return FALSE; + + if (element->device == NULL) + return FALSE; + + type = connman_device_get_type(element->device); + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + case CONNMAN_DEVICE_TYPE_VENDOR: + case CONNMAN_DEVICE_TYPE_MBM: + case CONNMAN_DEVICE_TYPE_HSO: + case CONNMAN_DEVICE_TYPE_NOZOMI: + case CONNMAN_DEVICE_TYPE_HUAWEI: + case CONNMAN_DEVICE_TYPE_NOVATEL: + return FALSE; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_WIFI: + case CONNMAN_DEVICE_TYPE_WIMAX: + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + case CONNMAN_DEVICE_TYPE_GPS: + if (data->type != CONNMAN_DEVICE_TYPE_UNKNOWN && + data->type != type) + return FALSE; + break; + } + + __connman_device_enable(element->device); + + return FALSE; +} + +int __connman_element_enable_technology(enum connman_device_type type) +{ + struct find_data data = { .type = type, .device = NULL }; + + g_node_traverse(element_root, G_PRE_ORDER, + G_TRAVERSE_ALL, -1, enable_technology, &data); + + return 0; +} + +static gboolean disable_technology(GNode *node, gpointer user_data) +{ + struct connman_element *element = node->data; + struct find_data *data = user_data; + enum connman_device_type type; + + if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE) + return FALSE; + + if (element->device == NULL) + return FALSE; + + type = connman_device_get_type(element->device); + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + case CONNMAN_DEVICE_TYPE_VENDOR: + case CONNMAN_DEVICE_TYPE_MBM: + case CONNMAN_DEVICE_TYPE_HSO: + case CONNMAN_DEVICE_TYPE_NOZOMI: + case CONNMAN_DEVICE_TYPE_HUAWEI: + case CONNMAN_DEVICE_TYPE_NOVATEL: + return FALSE; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_WIFI: + case CONNMAN_DEVICE_TYPE_WIMAX: + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + case CONNMAN_DEVICE_TYPE_GPS: + if (data->type != CONNMAN_DEVICE_TYPE_UNKNOWN && + data->type != type) + return FALSE; + break; + } + + __connman_device_disable(element->device); + + return FALSE; +} + +int __connman_element_disable_technology(enum connman_device_type type) +{ + struct find_data data = { .type = type, .device = NULL }; + + g_node_traverse(element_root, G_PRE_ORDER, + G_TRAVERSE_ALL, -1, disable_technology, &data); + + return 0; +} + static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_driver *driver1 = a; diff --git a/src/manager.c b/src/manager.c index 4daca1c..b92440d 100644 --- a/src/manager.c +++ b/src/manager.c @@ -313,27 +313,77 @@ static DBusMessage *request_scan(DBusConnection *conn, static DBusMessage *enable_technology(DBusConnection *conn, DBusMessage *msg, void *data) { + enum connman_device_type type; const char *str; + int err; DBG("conn %p", conn); dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); - return __connman_error_not_supported(msg); + if (g_strcmp0(str, "ethernet") == 0) + type = CONNMAN_DEVICE_TYPE_ETHERNET; + else if (g_strcmp0(str, "wifi") == 0) + type = CONNMAN_DEVICE_TYPE_WIFI; + else if (g_strcmp0(str, "wimax") == 0) + type = CONNMAN_DEVICE_TYPE_WIMAX; + else if (g_strcmp0(str, "bluetooth") == 0) + type = CONNMAN_DEVICE_TYPE_BLUETOOTH; + else if (g_strcmp0(str, "gps") == 0) + type = CONNMAN_DEVICE_TYPE_GPS; + else + return __connman_error_invalid_arguments(msg); + + err = __connman_element_enable_technology(type); + if (err < 0) { + if (err == -EINPROGRESS) { + connman_error("Invalid return code from enable"); + err = -EINVAL; + } + + return __connman_error_failed(msg, -err); + } + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } static DBusMessage *disable_technology(DBusConnection *conn, DBusMessage *msg, void *data) { + enum connman_device_type type; const char *str; + int err; DBG("conn %p", conn); dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); - return __connman_error_not_supported(msg); + if (g_strcmp0(str, "ethernet") == 0) + type = CONNMAN_DEVICE_TYPE_ETHERNET; + else if (g_strcmp0(str, "wifi") == 0) + type = CONNMAN_DEVICE_TYPE_WIFI; + else if (g_strcmp0(str, "wimax") == 0) + type = CONNMAN_DEVICE_TYPE_WIMAX; + else if (g_strcmp0(str, "bluetooth") == 0) + type = CONNMAN_DEVICE_TYPE_BLUETOOTH; + else if (g_strcmp0(str, "gps") == 0) + type = CONNMAN_DEVICE_TYPE_GPS; + else + return __connman_error_invalid_arguments(msg); + + err = __connman_element_disable_technology(type); + if (err < 0) { + if (err == -EINPROGRESS) { + connman_error("Invalid return code from disable"); + err = -EINVAL; + } + + return __connman_error_failed(msg, -err); + } + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } static DBusMessage *connect_service(DBusConnection *conn, -- 2.7.4