[PATCH BlueZ 03/11] btdev: Implement BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

This adds implementation of
BT_HCI_CMD_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL generating
BT_HCI_EVT_LE_PER_SYNC_ESTABLISHED if necessary.
---
 emulator/btdev.c | 30 +++++++++++++++++++++++++++---
 monitor/bt.h     |  1 +
 2 files changed, 28 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,
diff --git a/monitor/bt.h b/monitor/bt.h
index 51b1833dc..b6b6c49e1 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -3660,6 +3660,7 @@ struct bt_hci_evt_le_req_peer_sca_complete {
 #define BT_HCI_ERR_ADV_TIMEOUT                 0x3c
 #define BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH	0x3e
 #define BT_HCI_ERR_UNKNOWN_ADVERTISING_ID	0x42
+#define BT_HCI_ERR_CANCELLED			0x44
 
 struct bt_l2cap_hdr {
 	uint16_t len;
-- 
2.35.1




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux