Diff between 5c7bb42c0850b8feef07ed9f91482d76b7b5e100 and 73667927e45ac231b3ca3a94aa1cd460e7072c36

Changed Files

File Additions Deletions Status
src/adapter.c +89 -43 modified

Full Patch

diff --git a/src/adapter.c b/src/adapter.c
index df817db..6254c1a 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,