diff --git a/src/device.c b/src/device.c index 151837d9..02ccc3f1 100644 --- a/src/device.c +++ b/src/device.c @@ -44,6 +44,7 @@ #include "src/device.h" #include "src/watchlist.h" #include "src/ap.h" +#include "src/adhoc.h" struct device_watchlist_item { uint32_t id; @@ -2057,18 +2058,8 @@ static struct l_dbus_message *device_signal_agent_unregister( return l_dbus_message_new_method_return(message); } -static struct l_dbus_message *device_set_mode_ap(struct device *device, - struct l_dbus_message *message) +static void device_prepare_adhoc_ap_mode(struct device *device) { - if (device->mode == DEVICE_MODE_AP) - return dbus_error_already_exists(message); - - if (device->state != DEVICE_STATE_DISCONNECTED && - device->state != DEVICE_STATE_AUTOCONNECT) - return dbus_error_busy(message); - - l_debug(""); - periodic_scan_stop(device); /* Drop all state we can related to client mode */ @@ -2088,6 +2079,44 @@ static struct l_dbus_message *device_set_mode_ap(struct device *device, l_queue_destroy(device->networks_sorted, NULL); device->networks_sorted = l_queue_new(); +} + +static struct l_dbus_message *device_set_mode_adhoc(struct device *device, + struct l_dbus_message *message) +{ + if (device->mode == DEVICE_MODE_ADHOC) + return dbus_error_already_exists(message); + + if (device->state != DEVICE_STATE_DISCONNECTED && + device->state != DEVICE_STATE_AUTOCONNECT) + return dbus_error_busy(message); + + l_debug(""); + + device_prepare_adhoc_ap_mode(device); + + netdev_set_iftype(device->netdev, NETDEV_IFTYPE_ADHOC); + + device->mode = DEVICE_MODE_ADHOC; + + adhoc_add_interface(device); + + return NULL; +} + +static struct l_dbus_message *device_set_mode_ap(struct device *device, + struct l_dbus_message *message) +{ + if (device->mode == DEVICE_MODE_AP) + return dbus_error_already_exists(message); + + if (device->state != DEVICE_STATE_DISCONNECTED && + device->state != DEVICE_STATE_AUTOCONNECT) + return dbus_error_busy(message); + + l_debug(""); + + device_prepare_adhoc_ap_mode(device); netdev_set_iftype(device->netdev, NETDEV_IFTYPE_AP); @@ -2101,15 +2130,24 @@ static struct l_dbus_message *device_set_mode_ap(struct device *device, static struct l_dbus_message *device_set_mode_sta(struct device *device, struct l_dbus_message *message) { - if (device->mode != DEVICE_MODE_AP) - return dbus_error_not_found(message); + if (device->mode == DEVICE_MODE_STATION) + return dbus_error_already_exists(message); - netdev_set_iftype(device->netdev, NETDEV_IFTYPE_STATION); + switch (device->mode) { + case DEVICE_MODE_AP: + netdev_set_iftype(device->netdev, NETDEV_IFTYPE_STATION); + ap_remove_interface(device); + break; + case DEVICE_MODE_ADHOC: + netdev_set_iftype(device->netdev, NETDEV_IFTYPE_STATION); + adhoc_remove_interface(device); + break; + default: + return dbus_error_not_found(message); + } device->mode = DEVICE_MODE_STATION; - ap_remove_interface(device); - l_debug(""); return NULL; @@ -2499,6 +2537,9 @@ static bool device_property_get_mode(struct l_dbus *dbus, case DEVICE_MODE_AP: modestr = "ap"; break; + case DEVICE_MODE_ADHOC: + modestr = "ad-hoc"; + break; } l_dbus_message_builder_append_basic(builder, 's', modestr); @@ -2527,6 +2568,10 @@ static struct l_dbus_message *device_property_set_mode(struct l_dbus *dbus, reply = device_set_mode_ap(device, message); if (reply) return reply; + } else if (!strcmp(mode, "ad-hoc")) { + reply = device_set_mode_adhoc(device, message); + if (reply) + return reply; } else { return dbus_error_invalid_args(message); } diff --git a/src/device.h b/src/device.h index 39480e32..f949f566 100644 --- a/src/device.h +++ b/src/device.h @@ -45,7 +45,8 @@ enum device_state { enum device_mode { DEVICE_MODE_STATION, - DEVICE_MODE_AP + DEVICE_MODE_AP, + DEVICE_MODE_ADHOC, }; typedef void (*device_watch_func_t)(struct device *device,