From b4158586980b3cb3d7d827c411a6826c7e502bc2 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 13 Jun 2018 23:57:37 +0800 Subject: [PATCH] device: add dbus interface for WDS property The WDS dbus property of a Device directly maps to the 4ADDR property of a real netdevice. It can be activated or deactivated at any point in time. The name WDS comes from the fact that this feature allows a STA interface to be bridged and thus create a Wireless Distribution System (the same name is used in OpenWRT and hostapd). To implement this feature, the 'powered callback' data structure has been renamed and re-used. --- src/device.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/src/device.c b/src/device.c index 2ff547e3..e412168f 100644 --- a/src/device.c +++ b/src/device.c @@ -2167,7 +2167,7 @@ static bool device_property_get_powered(struct l_dbus *dbus, return true; } -struct set_powered_cb_data { +struct set_generic_cb_data { struct device *device; struct l_dbus *dbus; struct l_dbus_message *message; @@ -2176,7 +2176,7 @@ struct set_powered_cb_data { static void set_powered_cb(struct netdev *netdev, int result, void *user_data) { - struct set_powered_cb_data *cb_data = user_data; + struct set_generic_cb_data *cb_data = user_data; struct l_dbus_message *reply = NULL; if (result < 0) @@ -2193,7 +2193,7 @@ static struct l_dbus_message *device_property_set_powered(struct l_dbus *dbus, { struct device *device = user_data; bool powered; - struct set_powered_cb_data *cb_data; + struct set_generic_cb_data *cb_data; if (!l_dbus_message_iter_get_variant(new_value, "b", &powered)) return dbus_error_invalid_args(message); @@ -2204,7 +2204,7 @@ static struct l_dbus_message *device_property_set_powered(struct l_dbus *dbus, return NULL; } - cb_data = l_new(struct set_powered_cb_data, 1); + cb_data = l_new(struct set_generic_cb_data, 1); cb_data->device = device; cb_data->dbus = dbus; cb_data->message = message; @@ -2216,6 +2216,65 @@ static struct l_dbus_message *device_property_set_powered(struct l_dbus *dbus, return NULL; } +static bool device_property_get_4addr(struct l_dbus *dbus, + struct l_dbus_message *message, + struct l_dbus_message_builder *builder, + void *user_data) +{ + struct device *device = user_data; + bool use_4addr = netdev_get_4addr(device->netdev); + + l_dbus_message_builder_append_basic(builder, 'b', &use_4addr); + + return true; +} + +static void set_4addr_cb(struct netdev *netdev, int result, void *user_data) +{ + struct set_generic_cb_data *cb_data = user_data; + struct l_dbus_message *reply = NULL; + + if (result < 0) + reply = dbus_error_failed(cb_data->message); + + cb_data->complete(cb_data->dbus, cb_data->message, reply); + + l_dbus_property_changed(cb_data->dbus, device_get_path(cb_data->device), + IWD_DEVICE_INTERFACE, "WDS"); +} + +static struct l_dbus_message *device_property_set_4addr(struct l_dbus *dbus, + struct l_dbus_message *message, + struct l_dbus_message_iter *new_value, + l_dbus_property_complete_cb_t complete, + void *user_data) +{ + struct set_generic_cb_data *cb_data; + struct device *device = user_data; + bool use_4addr; + + if (!l_dbus_message_iter_get_variant(new_value, "b", &use_4addr)) + return dbus_error_invalid_args(message); + + if (use_4addr == netdev_get_4addr(device->netdev)) { + complete(dbus, message, NULL); + + return NULL; + } + + cb_data = l_new(struct set_generic_cb_data, 1); + cb_data->device = device; + cb_data->dbus = dbus; + cb_data->message = message; + cb_data->complete = complete; + + if (netdev_set_4addr(device->netdev, use_4addr, set_4addr_cb, cb_data, + l_free) < 0) + return dbus_error_failed(message); + + return NULL; +} + static bool device_property_get_scanning(struct l_dbus *dbus, struct l_dbus_message *message, struct l_dbus_message_builder *builder, @@ -2305,6 +2364,9 @@ static void setup_device_interface(struct l_dbus_interface *interface) l_dbus_interface_property(interface, "ConnectedNetwork", 0, "o", device_property_get_connected_network, NULL); + l_dbus_interface_property(interface, "WDS", 0, "b", + device_property_get_4addr, + device_property_set_4addr); l_dbus_interface_property(interface, "Powered", 0, "b", device_property_get_powered, device_property_set_powered);