From 73667927e45ac231b3ca3a94aa1cd460e7072c36 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 4 Jan 2013 20:29:50 -0800 Subject: [PATCH] core: Add support for powered property within adapter handling --- src/adapter.c | 132 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 43 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index df817dbbf..6254c1af5 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -432,29 +432,6 @@ static void new_settings_callback(uint16_t index, uint16_t length, adapter_update_settings(adapter, settings); } -static void set_powered(struct btd_adapter *adapter, gboolean powered, - GDBusPendingPropertySet id) -{ - int err; - - if (mgmt_powered(adapter->current_settings) == powered) { - g_dbus_pending_property_success(id); - return; - } - - err = mgmt_set_powered(adapter->dev_id, powered); - if (err < 0) { - g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed", - strerror(-err)); - return; - } - - if (powered == FALSE) - adapter->off_requested = TRUE; - - g_dbus_pending_property_success(id); -} - static void set_pairable(struct btd_adapter *adapter, gboolean pairable, bool reply, GDBusPendingPropertySet id) { @@ -1324,37 +1301,107 @@ static gboolean adapter_property_get_class(const GDBusPropertyTable *property, return TRUE; } -static gboolean adapter_property_get_powered( - const GDBusPropertyTable *property, - DBusMessageIter *iter, void *data) +static gboolean property_get_powered(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *user_data) { - struct btd_adapter *adapter = data; - dbus_bool_t value; - bool powered = mgmt_powered(adapter->current_settings); + struct btd_adapter *adapter = user_data; + dbus_bool_t powered; - value = (powered && !adapter->off_requested) ? TRUE : FALSE; - dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value); + if (adapter->current_settings & MGMT_SETTING_POWERED) + powered = TRUE; + else + powered = FALSE; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &powered); return TRUE; } -static void adapter_property_set_powered( - const GDBusPropertyTable *property, - DBusMessageIter *value, - GDBusPendingPropertySet id, void *data) +struct property_set_data { + struct btd_adapter *adapter; + GDBusPendingPropertySet id; +}; + +static void set_powered_complete(uint8_t status, uint16_t length, + const void *param, void *user_data) { - dbus_bool_t powered; + struct property_set_data *data = user_data; + struct btd_adapter *adapter = data->adapter; + uint32_t settings; - if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) { - g_dbus_pending_property_error(id, - ERROR_INTERFACE ".InvalidArguments", - "Invalid arguments in method call"); + if (status != MGMT_STATUS_SUCCESS) { + error("Failed to set powered: %s (0x%02x)", + mgmt_errstr(status), status); + g_dbus_pending_property_error(data->id, + ERROR_INTERFACE ".Failed", + mgmt_errstr(status)); + return; + } + + if (length < sizeof(settings)) { + error("Wrong size of set powered response"); + g_dbus_pending_property_error(data->id, + ERROR_INTERFACE ".Failed", + "Invalid response data"); return; } + settings = bt_get_le32(param); + + DBG("Settings: 0x%08x", settings); + + adapter->current_settings = settings; + + g_dbus_pending_property_success(data->id); + + g_dbus_emit_property_changed(dbus_conn, adapter->path, + ADAPTER_INTERFACE, "Powered"); +} + +static void property_set_powered(const GDBusPropertyTable *property, + DBusMessageIter *value, + GDBusPendingPropertySet id, void *user_data) +{ + struct btd_adapter *adapter = user_data; + struct property_set_data *data; + struct mgmt_mode cp; + dbus_bool_t powered, current_powered; + dbus_message_iter_get_basic(value, &powered); - set_powered(data, powered, id); + if (adapter->current_settings & MGMT_SETTING_POWERED) + current_powered = TRUE; + else + current_powered = FALSE; + + if (powered == current_powered) { + g_dbus_pending_property_success(id); + return; + } + + memset(&cp, 0, sizeof(cp)); + cp.val = (powered == TRUE) ? 0x01 : 0x00; + + DBG("sending set powered command for index %u", adapter->dev_id); + + data = g_try_new0(struct property_set_data, 1); + if (!data) + goto failed; + + data->adapter = adapter; + data->id = id; + + if (mgmt_send(adapter->mgmt, MGMT_OP_SET_POWERED, + adapter->dev_id, sizeof(cp), &cp, + set_powered_complete, data, g_free) > 0) + return; + + g_free(data); + +failed: + error("Failed to set powered for index %u", adapter->dev_id); + + g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed", NULL); } static gboolean adapter_property_get_discoverable( @@ -1595,8 +1642,7 @@ static const GDBusPropertyTable adapter_properties[] = { { "Alias", "s", adapter_property_get_alias, adapter_property_set_alias }, { "Class", "u", adapter_property_get_class }, - { "Powered", "b", adapter_property_get_powered, - adapter_property_set_powered }, + { "Powered", "b", property_get_powered, property_set_powered }, { "Discoverable", "b", adapter_property_get_discoverable, adapter_property_set_discoverable }, { "Pairable", "b", adapter_property_get_pairable, -- 2.47.3