summaryrefslogtreecommitdiff
path: root/emulator
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-03-04 17:22:20 -0800
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2022-03-07 17:18:37 -0800
commit3250d7f938831eb583284d46e05338ada1ef729e (patch)
tree6df6efc76e4f360ba97f2c9f377225db410f679a /emulator
parentea501af91caed2d1687fe39ff94762ffb1ddf889 (diff)
downloadbluez-3250d7f938831eb583284d46e05338ada1ef729e.tar.gz
btdev: Implement BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL
This adds implementation of BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL generating BT_HCI_EVT_LE_PER_SYNC_ESTABLISHED if necessary.
Diffstat (limited to 'emulator')
-rw-r--r--emulator/btdev.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 34469d986..09101a5df 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -48,6 +48,7 @@
#define ISO_HANDLE 257
#define SCO_HANDLE 257
#define SYC_HANDLE 1
+#define INV_HANDLE 0xffff
struct hook {
btdev_hook_func handler;
@@ -5301,7 +5302,7 @@ static int cmd_per_adv_create_sync(struct btdev *dev, const void *data,
if (dev->le_periodic_sync_handle)
status = BT_HCI_ERR_MEM_CAPACITY_EXCEEDED;
else
- dev->le_periodic_sync_handle = SYC_HANDLE;
+ dev->le_periodic_sync_handle = INV_HANDLE;
cmd_status(dev, status, BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC);
@@ -5351,11 +5352,14 @@ static void le_per_adv_sync_estabilished(struct btdev *dev,
ev.status = status;
if (status) {
+ dev->le_periodic_sync_handle = 0x0000;
le_meta_event(dev, BT_HCI_EVT_LE_PER_SYNC_ESTABLISHED, &ev,
sizeof(ev));
return;
}
+ dev->le_periodic_sync_handle = SYC_HANDLE;
+
ev.handle = cpu_to_le16(dev->le_periodic_sync_handle);
ev.addr_type = cmd->addr_type;
memcpy(ev.addr, cmd->addr, sizeof(ev.addr));
@@ -5394,8 +5398,28 @@ static int cmd_per_adv_create_sync_complete(struct btdev *dev, const void *data,
static int cmd_per_adv_create_sync_cancel(struct btdev *dev, const void *data,
uint8_t len)
{
- /* TODO */
- return -ENOTSUP;
+ uint8_t status = BT_HCI_ERR_SUCCESS;
+
+ /* If the Host issues this command while no
+ * HCI_LE_Periodic_Advertising_Create_Sync command is pending, the
+ * Controller shall return the error code Command Disallowed (0x0C).
+ */
+ if (dev->le_periodic_sync_handle != INV_HANDLE)
+ status = BT_HCI_ERR_COMMAND_DISALLOWED;
+
+ cmd_complete(dev, BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL,
+ &status, sizeof(status));
+
+ /* After the HCI_Command_Complete is sent and if the cancellation was
+ * successful, the Controller sends an
+ * HCI_LE_Periodic_Advertising_Sync_Established event to the Host with
+ * the error code Operation Cancelled by Host (0x44).
+ */
+ if (!status)
+ le_per_adv_sync_estabilished(dev, NULL, NULL,
+ BT_HCI_ERR_CANCELLED);
+
+ return 0;
}
static int cmd_per_adv_term_sync(struct btdev *dev, const void *data,