@@ -640,14 +640,21 @@ static void new_settings_callback(uint16_t index, uint16_t length,
settings_changed(adapter, settings);
}
+struct set_mode_data {
+ struct btd_adapter *adapter;
+ uint32_t setting;
+};
+
static void set_mode_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
- struct btd_adapter *adapter = user_data;
+ struct set_mode_data *data = user_data;
+ struct btd_adapter *adapter = data->adapter;
if (status != MGMT_STATUS_SUCCESS) {
btd_error(adapter->dev_id, "Failed to set mode: %s (0x%02x)",
mgmt_errstr(status), status);
+ adapter->pending_settings &= ~data->setting;
return;
}
@@ -677,6 +684,7 @@ static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
{
struct mgmt_mode cp;
uint32_t setting = 0;
+ struct set_mode_data *data;
memset(&cp, 0, sizeof(cp));
cp.val = mode;
@@ -699,15 +707,23 @@ static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
break;
}
- adapter->pending_settings |= setting;
-
DBG("sending set mode command for index %u", adapter->dev_id);
+ data = g_try_new0(struct set_mode_data, 1);
+ if (!data)
+ goto failed;
+
+ data->adapter = adapter;
+ data->setting = setting;
+
if (mgmt_send(adapter->mgmt, opcode,
adapter->dev_id, sizeof(cp), &cp,
- set_mode_complete, adapter, NULL) > 0)
+ set_mode_complete, data, g_free) > 0) {
+ adapter->pending_settings |= setting;
return true;
+ }
+failed:
btd_error(adapter->dev_id, "Failed to set mode for index %u",
adapter->dev_id);
@@ -718,6 +734,7 @@ static bool set_discoverable(struct btd_adapter *adapter, uint8_t mode,
uint16_t timeout)
{
struct mgmt_cp_set_discoverable cp;
+ struct set_mode_data *data;
memset(&cp, 0, sizeof(cp));
cp.val = mode;
@@ -734,11 +751,19 @@ static bool set_discoverable(struct btd_adapter *adapter, uint8_t mode,
mode);
}
+ data = g_try_new0(struct set_mode_data, 1);
+ if (!data)
+ goto failed;
+
+ data->adapter = adapter;
+ data->setting = 0;
+
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_DISCOVERABLE,
adapter->dev_id, sizeof(cp), &cp,
- set_mode_complete, adapter, NULL) > 0)
+ set_mode_complete, data, g_free) > 0)
return true;
+failed:
btd_error(adapter->dev_id, "Failed to set mode for index %u",
adapter->dev_id);
@@ -2877,6 +2902,7 @@ static gboolean property_get_mode(struct btd_adapter *adapter,
struct property_set_data {
struct btd_adapter *adapter;
+ uint32_t setting;
GDBusPendingPropertySet id;
};
@@ -2901,6 +2927,8 @@ static void property_set_mode_complete(uint8_t status, uint16_t length,
g_dbus_pending_property_error(data->id, dbus_err,
mgmt_errstr(status));
+
+ adapter->pending_settings &= ~data->setting;
return;
}
@@ -2969,8 +2997,6 @@ static void property_set_mode(struct btd_adapter *adapter, uint32_t setting,
mode = (enable == TRUE) ? 0x01 : 0x00;
- adapter->pending_settings |= setting;
-
switch (setting) {
case MGMT_SETTING_POWERED:
opcode = MGMT_OP_SET_POWERED;
@@ -3024,11 +3050,14 @@ static void property_set_mode(struct btd_adapter *adapter, uint32_t setting,
goto failed;
data->adapter = adapter;
+ data->setting = setting;
data->id = id;
if (mgmt_send(adapter->mgmt, opcode, adapter->dev_id, len, param,
- property_set_mode_complete, data, g_free) > 0)
+ property_set_mode_complete, data, g_free) > 0) {
+ adapter->pending_settings |= setting;
return;
+ }
g_free(data);