diff mbox series

[BlueZ,04/14] shared/bass: Add support to register cp handlers

Message ID 20240821145602.92083-5-iulia.tanasescu@nxp.com
State Superseded
Headers show
Series Add Scan Delegator support for Add Source op | expand

Commit Message

Iulia Tanasescu Aug. 21, 2024, 2:55 p.m. UTC
The BASS Broadcast Audio Scan Control Point characteristic defines a
number of commands that require socket operations, which should be
handled inside the BASS plugin.

This commit adds shared/bass APIs to register control point handlers
with bt_bass. The BASS plugin will use these APIs to register a control
point callback to handle each operation based on opcode and parameters.
---
 src/shared/bass.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/bass.h |  9 +++++++
 2 files changed, 77 insertions(+)
diff mbox series

Patch

diff --git a/src/shared/bass.c b/src/shared/bass.c
index 636eb24fd..635fe1054 100644
--- a/src/shared/bass.c
+++ b/src/shared/bass.c
@@ -66,12 +66,20 @@  struct bt_bass {
 	void *debug_data;
 
 	struct queue *src_cbs;
+	struct queue *cp_handlers;
 
 	unsigned int disconn_id;
 
 	void *user_data;
 };
 
+struct bt_bass_cp_handler {
+	unsigned int id;
+	bt_bass_cp_handler_func_t handler;
+	bt_bass_destroy_func_t destroy;
+	void *data;
+};
+
 /* BASS subgroup field of the Broadcast
  * Receive State characteristic
  */
@@ -134,6 +142,64 @@  static void bass_debug(struct bt_bass *bass, const char *format, ...)
 	va_end(ap);
 }
 
+unsigned int bt_bass_cp_handler_register(struct bt_bass *bass,
+				bt_bass_cp_handler_func_t handler,
+				bt_bass_destroy_func_t destroy,
+				void *user_data)
+{
+	struct bt_bass_cp_handler *cb;
+	static unsigned int id;
+
+	if (!bass)
+		return 0;
+
+	cb = new0(struct bt_bass_cp_handler, 1);
+	cb->id = ++id ? id : ++id;
+	cb->handler = handler;
+	cb->destroy = destroy;
+	cb->data = user_data;
+
+	queue_push_tail(bass->cp_handlers, cb);
+
+	return cb->id;
+}
+
+static void bass_cp_handler_free(void *data)
+{
+	struct bt_bass_cp_handler *cb = data;
+
+	if (cb->destroy)
+		cb->destroy(cb->data);
+
+	free(cb);
+}
+
+static bool match_cb_id(const void *data, const void *match_data)
+{
+	const struct bt_bass_cp_handler *cb = data;
+	unsigned int id = PTR_TO_UINT(match_data);
+
+	return (cb->id == id);
+}
+
+bool bt_bass_cp_handler_unregister(struct bt_bass *bass,
+				unsigned int id)
+{
+	struct bt_bass_cp_handler *cb;
+
+	if (!bass)
+		return false;
+
+	cb = queue_remove_if(bass->cp_handlers, match_cb_id,
+						UINT_TO_PTR(id));
+	if (!cb)
+		return false;
+
+	bass_cp_handler_free(cb);
+
+	return true;
+}
+
 unsigned int bt_bass_src_register(struct bt_bass *bass, bt_bass_src_func_t cb,
 				void *user_data, bt_bass_destroy_func_t destroy)
 {
@@ -1418,6 +1484,7 @@  static void bass_free(void *data)
 	bass_db_free(bass->rdb);
 	queue_destroy(bass->notify, NULL);
 	queue_destroy(bass->src_cbs, bass_src_changed_free);
+	queue_destroy(bass->cp_handlers, bass_cp_handler_free);
 
 	free(bass);
 }
@@ -1513,6 +1580,7 @@  struct bt_bass *bt_bass_new(struct gatt_db *ldb, struct gatt_db *rdb,
 	bass->ldb = db;
 	bass->notify = queue_new();
 	bass->src_cbs = queue_new();
+	bass->cp_handlers = queue_new();
 
 	if (!rdb)
 		goto done;
diff --git a/src/shared/bass.h b/src/shared/bass.h
index 086fe335e..2ca659cca 100644
--- a/src/shared/bass.h
+++ b/src/shared/bass.h
@@ -99,6 +99,9 @@  typedef void (*bt_bass_debug_func_t)(const char *str, void *user_data);
 typedef void (*bt_bass_src_func_t)(uint8_t id, uint32_t bid, uint8_t enc,
 					uint32_t bis_sync, void *user_data);
 
+typedef int (*bt_bass_cp_handler_func_t)(struct bt_bcast_src *bcast_src,
+		uint8_t op, void *params, void *user_data);
+
 struct bt_att *bt_bass_get_att(struct bt_bass *bass);
 struct bt_gatt_client *bt_bass_get_client(struct bt_bass *bass);
 unsigned int bt_bass_register(bt_bass_func_t attached, bt_bass_func_t detached,
@@ -120,3 +123,9 @@  int bt_bass_send(struct bt_bass *bass,
 unsigned int bt_bass_src_register(struct bt_bass *bass, bt_bass_src_func_t cb,
 			void *user_data, bt_bass_destroy_func_t destroy);
 bool bt_bass_src_unregister(struct bt_bass *bass, unsigned int id);
+unsigned int bt_bass_cp_handler_register(struct bt_bass *bass,
+				bt_bass_cp_handler_func_t handler,
+				bt_bass_destroy_func_t destroy,
+				void *user_data);
+bool bt_bass_cp_handler_unregister(struct bt_bass *bass,
+				unsigned int id);