diff mbox series

[BlueZ,v2,3/5] emulator/btdev: Add support HCI LE Adv Set Terminated event

Message ID 20210623044944.602205-3-hj.tedd.an@gmail.com (mailing list archive)
State Accepted
Delegated to: Luiz Von Dentz
Headers show
Series [BlueZ,v2,1/5] tools/mgmt-tester: Enable High-Speed(HS) test cases | expand

Commit Message

Tedd Ho-Jeong An June 23, 2021, 4:49 a.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This patch adds support the HCI_LE_Advertising_Set_Terminated event in
btdev.
---
 emulator/btdev.c | 64 +++++++++++++++++++++++++++++++++++++++++++++---
 monitor/bt.h     |  1 +
 2 files changed, 62 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/emulator/btdev.c b/emulator/btdev.c
index c5ea35e54..90457a5aa 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -74,6 +74,7 @@  struct btdev_rl {
 };
 
 struct le_ext_adv {
+	struct btdev *dev;
 	uint8_t handle;
 	uint8_t enable;
 	uint8_t type;			/* evt_properties */
@@ -86,6 +87,7 @@  struct le_ext_adv {
 	uint8_t adv_data_len;
 	uint8_t scan_data[252];
 	uint8_t scan_data_len;
+	unsigned int id;
 };
 
 struct btdev {
@@ -4237,6 +4239,11 @@  static void ext_adv_disable(void *data, void *user_data)
 	if (handle && ext_adv->handle != handle)
 		return;
 
+	if (ext_adv->id) {
+		timeout_remove(ext_adv->id);
+		ext_adv->id = 0;
+	}
+
 	ext_adv->enable = 0x00;
 }
 
@@ -4253,6 +4260,7 @@  static struct le_ext_adv *le_ext_adv_new(struct btdev *btdev, uint8_t handle)
 	struct le_ext_adv *ext_adv;
 
 	ext_adv = new0(struct le_ext_adv, 1);
+	ext_adv->dev = btdev;
 	ext_adv->handle = handle;
 
 	/* Add to queue */
@@ -4268,6 +4276,12 @@  static void le_ext_adv_free(void *data)
 {
 	struct le_ext_adv *ext_adv = data;
 
+	/* Remove to queue */
+	queue_remove(ext_adv->dev->le_ext_adv, ext_adv);
+
+	if (ext_adv->id)
+		timeout_remove(ext_adv->id);
+
 	free(ext_adv);
 }
 
@@ -4477,6 +4491,31 @@  static void le_set_ext_adv_enable_complete(struct btdev *btdev,
 		}
 	}
 }
+static void adv_set_terminate(struct btdev *dev, uint8_t status, uint8_t handle,
+					uint16_t conn_handle, uint8_t num_evts)
+{
+	struct bt_hci_evt_le_adv_set_term ev;
+
+	memset(&ev, 0, sizeof(ev));
+	ev.status = status;
+	ev.handle = handle;
+	ev.conn_handle = cpu_to_le16(conn_handle);
+	ev.num_evts = num_evts;
+
+	le_meta_event(dev, BT_HCI_EVT_LE_ADV_SET_TERM, &ev, sizeof(ev));
+}
+
+static bool ext_adv_timeout(void *user_data)
+{
+	struct le_ext_adv *adv = user_data;
+
+	adv->id = 0;
+	adv_set_terminate(adv->dev, BT_HCI_ERR_ADV_TIMEOUT, adv->handle,
+								0x0000, 0x00);
+	le_ext_adv_free(adv);
+
+	return false;
+}
 
 static int cmd_set_ext_adv_enable(struct btdev *dev, const void *data,
 							uint8_t len)
@@ -4517,6 +4556,13 @@  static int cmd_set_ext_adv_enable(struct btdev *dev, const void *data,
 		}
 
 		ext_adv->enable = cmd->enable;
+
+		if (!cmd->enable)
+			ext_adv_disable(ext_adv, NULL);
+		else if (eas->duration)
+			ext_adv->id = timeout_add(eas->duration * 10,
+							ext_adv_timeout,
+							ext_adv, NULL);
 	}
 
 exit_complete:
@@ -4785,6 +4831,19 @@  static int cmd_ext_create_conn(struct btdev *dev, const void *data, uint8_t len)
 	return 0;
 }
 
+static void ext_adv_term(void *data, void *user_data)
+{
+	struct le_ext_adv *adv = data;
+	struct btdev_conn *conn = user_data;
+
+	/* if connectable bit is set the send adv terminate */
+	if (conn && adv->type & 0x01) {
+		adv_set_terminate(conn->dev, 0x00, adv->handle, conn->handle,
+									0x00);
+		le_ext_adv_free(adv);
+	}
+}
+
 static void le_ext_conn_complete(struct btdev *btdev,
 			const struct bt_hci_cmd_le_ext_create_conn *cmd,
 			struct le_ext_adv *ext_adv,
@@ -4803,9 +4862,8 @@  static void le_ext_conn_complete(struct btdev *btdev,
 			return;
 
 		/* Disable EXT ADV */
-		queue_foreach(btdev->le_ext_adv, ext_adv_disable, NULL);
-		queue_foreach(conn->link->dev->le_ext_adv, ext_adv_disable,
-									NULL);
+		queue_foreach(btdev->le_ext_adv, ext_adv_term, conn);
+		queue_foreach(conn->link->dev->le_ext_adv, ext_adv_term, conn);
 
 		ev.status = status;
 		ev.peer_addr_type = btdev->le_scan_own_addr_type;
diff --git a/monitor/bt.h b/monitor/bt.h
index d60bbdb20..738bc294b 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -3656,6 +3656,7 @@  struct bt_hci_evt_le_req_peer_sca_complete {
 #define BT_HCI_ERR_UNSUPPORTED_FEATURE		0x11
 #define BT_HCI_ERR_INVALID_PARAMETERS		0x12
 #define BT_HCI_ERR_UNSPECIFIED_ERROR		0x1f
+#define BT_HCI_ERR_ADV_TIMEOUT                 0x3c
 #define BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH	0x3e
 #define BT_HCI_ERR_UNKNOWN_ADVERTISING_ID	0x42