summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/connman.h4
-rw-r--r--src/device.c26
-rw-r--r--src/element.c98
-rw-r--r--src/manager.c54
4 files changed, 180 insertions, 2 deletions
diff --git a/src/connman.h b/src/connman.h
index b3aa487f..85d6d3e3 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 c05fada2..248c0419 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 3545e170..3adbf46f 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 4daca1c2..b92440dd 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,