diff --git a/src/adapter.c b/src/adapter.c
index df817db..6254c1a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
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)
{
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(
{ "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,