1 /** @file
2  *  @brief Audio Video Remote Control Profile
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  * Copyright (C) 2024 Xiaomi Corporation
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <string.h>
13 #include <errno.h>
14 #include <zephyr/sys/atomic.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/sys/printk.h>
18 
19 #include <zephyr/bluetooth/bluetooth.h>
20 #include <zephyr/bluetooth/classic/avrcp.h>
21 #include <zephyr/bluetooth/classic/sdp.h>
22 #include <zephyr/bluetooth/l2cap.h>
23 
24 #include "host/hci_core.h"
25 #include "host/conn_internal.h"
26 #include "host/l2cap_internal.h"
27 #include "avctp_internal.h"
28 #include "avrcp_internal.h"
29 
30 #define LOG_LEVEL CONFIG_BT_AVRCP_LOG_LEVEL
31 #include <zephyr/logging/log.h>
32 LOG_MODULE_REGISTER(bt_avrcp);
33 
34 struct bt_avrcp {
35 	struct bt_avctp session;
36 	struct bt_avrcp_req req;
37 	struct k_work_delayable timeout_work;
38 	uint8_t local_tid;
39 };
40 
41 struct avrcp_handler {
42 	bt_avrcp_opcode_t opcode;
43 	void (*func)(struct bt_avrcp *avrcp, struct net_buf *buf, bt_avctp_cr_t cr);
44 };
45 
46 #define AVRCP_TIMEOUT       K_SECONDS(3) /* Shell be greater than TMTP (1000ms) */
47 #define AVRCP_AVCTP(_avctp) CONTAINER_OF(_avctp, struct bt_avrcp, session)
48 #define AVRCP_KWORK(_work)                                                                         \
49 	CONTAINER_OF(CONTAINER_OF(_work, struct k_work_delayable, work), struct bt_avrcp,          \
50 		     timeout_work)
51 
52 static const struct bt_avrcp_cb *avrcp_cb;
53 static struct bt_avrcp avrcp_connection[CONFIG_BT_MAX_CONN];
54 
55 #if defined(CONFIG_BT_AVRCP_TARGET)
56 static struct bt_sdp_attribute avrcp_tg_attrs[] = {
57 	BT_SDP_NEW_SERVICE,
58 	BT_SDP_LIST(
59 		BT_SDP_ATTR_SVCLASS_ID_LIST,
60 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3),
61 		BT_SDP_DATA_ELEM_LIST(
62 		{
63 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
64 			BT_SDP_ARRAY_16(BT_SDP_AV_REMOTE_TARGET_SVCLASS)
65 		},
66 		)
67 	),
68 	BT_SDP_LIST(
69 		BT_SDP_ATTR_PROTO_DESC_LIST,
70 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16),
71 		BT_SDP_DATA_ELEM_LIST(
72 		{
73 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
74 			BT_SDP_DATA_ELEM_LIST({BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
75 			BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP)},
76 			{
77 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
78 				BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL)
79 			},
80 			)
81 		},
82 		{
83 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
84 			BT_SDP_DATA_ELEM_LIST(
85 			{
86 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
87 				BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL)
88 			},
89 			{
90 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
91 				BT_SDP_ARRAY_16(AVCTP_VER_1_4)
92 			},
93 			)
94 		},
95 		)
96 	),
97 	/* C1: Browsing not supported */
98 	/* C2: Cover Art not supported */
99 	BT_SDP_LIST(
100 		BT_SDP_ATTR_PROFILE_DESC_LIST,
101 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8),
102 		BT_SDP_DATA_ELEM_LIST(
103 		{
104 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
105 			BT_SDP_DATA_ELEM_LIST(
106 			{
107 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
108 				BT_SDP_ARRAY_16(BT_SDP_AV_REMOTE_SVCLASS)
109 			},
110 			{
111 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
112 				BT_SDP_ARRAY_16(AVRCP_VER_1_6)
113 			},
114 			)
115 		},
116 		)
117 	),
118 	BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2),
119 	/* O: Provider Name not presented */
120 	BT_SDP_SERVICE_NAME("AVRCP Target"),
121 };
122 
123 static struct bt_sdp_record avrcp_tg_rec = BT_SDP_RECORD(avrcp_tg_attrs);
124 #endif /* CONFIG_BT_AVRCP_TARGET */
125 
126 #if defined(CONFIG_BT_AVRCP_CONTROLLER)
127 static struct bt_sdp_attribute avrcp_ct_attrs[] = {
128 	BT_SDP_NEW_SERVICE,
129 	BT_SDP_LIST(
130 		BT_SDP_ATTR_SVCLASS_ID_LIST,
131 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
132 		BT_SDP_DATA_ELEM_LIST(
133 		{
134 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
135 			BT_SDP_ARRAY_16(BT_SDP_AV_REMOTE_SVCLASS)
136 		},
137 		{
138 			BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
139 			BT_SDP_ARRAY_16(BT_SDP_AV_REMOTE_CONTROLLER_SVCLASS)
140 		},
141 		)
142 	),
143 	BT_SDP_LIST(
144 		BT_SDP_ATTR_PROTO_DESC_LIST,
145 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 16),
146 		BT_SDP_DATA_ELEM_LIST(
147 		{
148 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
149 			BT_SDP_DATA_ELEM_LIST(
150 			{
151 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
152 				BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP)
153 			},
154 			{
155 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
156 				BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL)
157 			},
158 			)
159 		},
160 		{
161 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
162 			BT_SDP_DATA_ELEM_LIST(
163 			{
164 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
165 				BT_SDP_ARRAY_16(BT_UUID_AVCTP_VAL)
166 			},
167 			{
168 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
169 				BT_SDP_ARRAY_16(AVCTP_VER_1_4)
170 			},
171 			)
172 		},
173 		)
174 	),
175 	/* C1: Browsing not supported */
176 	BT_SDP_LIST(
177 		BT_SDP_ATTR_PROFILE_DESC_LIST,
178 		BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8),
179 		BT_SDP_DATA_ELEM_LIST(
180 		{
181 			BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
182 			BT_SDP_DATA_ELEM_LIST(
183 			{
184 				BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
185 				BT_SDP_ARRAY_16(BT_SDP_AV_REMOTE_SVCLASS)
186 			},
187 			{
188 				BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
189 				BT_SDP_ARRAY_16(AVRCP_VER_1_6)
190 			},
191 			)
192 		},
193 		)
194 	),
195 	BT_SDP_SUPPORTED_FEATURES(AVRCP_CAT_1 | AVRCP_CAT_2),
196 	/* O: Provider Name not presented */
197 	BT_SDP_SERVICE_NAME("AVRCP Controller"),
198 };
199 
200 static struct bt_sdp_record avrcp_ct_rec = BT_SDP_RECORD(avrcp_ct_attrs);
201 #endif /* CONFIG_BT_AVRCP_CONTROLLER */
202 
get_new_connection(struct bt_conn * conn)203 static struct bt_avrcp *get_new_connection(struct bt_conn *conn)
204 {
205 	struct bt_avrcp *avrcp;
206 
207 	if (!conn) {
208 		LOG_ERR("Invalid Input (err: %d)", -EINVAL);
209 		return NULL;
210 	}
211 
212 	avrcp = &avrcp_connection[bt_conn_index(conn)];
213 	memset(avrcp, 0, sizeof(struct bt_avrcp));
214 	return avrcp;
215 }
216 
avrcp_timeout(struct k_work * work)217 static void avrcp_timeout(struct k_work *work)
218 {
219 	struct bt_avrcp *avrcp = AVRCP_KWORK(work);
220 
221 	LOG_WRN("Timeout: tid 0x%X, opc 0x%02X", avrcp->req.tid, avrcp->req.opcode);
222 }
223 
224 /* The AVCTP L2CAP channel established */
avrcp_connected(struct bt_avctp * session)225 static void avrcp_connected(struct bt_avctp *session)
226 {
227 	struct bt_avrcp *avrcp = AVRCP_AVCTP(session);
228 
229 	if ((avrcp_cb != NULL) && (avrcp_cb->connected != NULL)) {
230 		avrcp_cb->connected(avrcp);
231 	}
232 
233 	k_work_init_delayable(&avrcp->timeout_work, avrcp_timeout);
234 }
235 
236 /* The AVCTP L2CAP channel released */
avrcp_disconnected(struct bt_avctp * session)237 static void avrcp_disconnected(struct bt_avctp *session)
238 {
239 	struct bt_avrcp *avrcp = AVRCP_AVCTP(session);
240 
241 	if ((avrcp_cb != NULL) && (avrcp_cb->disconnected != NULL)) {
242 		avrcp_cb->disconnected(avrcp);
243 	}
244 }
245 
avrcp_vendor_dependent_handler(struct bt_avrcp * avrcp,struct net_buf * buf,bt_avctp_cr_t cr)246 static void avrcp_vendor_dependent_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
247 					   bt_avctp_cr_t cr)
248 {
249 	/* ToDo */
250 }
251 
avrcp_unit_info_handler(struct bt_avrcp * avrcp,struct net_buf * buf,bt_avctp_cr_t cr)252 static void avrcp_unit_info_handler(struct bt_avrcp *avrcp, struct net_buf *buf, bt_avctp_cr_t cr)
253 {
254 	struct bt_avrcp_header *avrcp_hdr;
255 	struct bt_avrcp_unit_info_rsp rsp;
256 
257 	if (cr == BT_AVCTP_CMD) {
258 		/* ToDo */
259 	} else { /* BT_AVCTP_RESPONSE */
260 		if ((avrcp_cb != NULL) && (avrcp_cb->unit_info_rsp != NULL)) {
261 			net_buf_pull(buf, sizeof(*avrcp_hdr));
262 			if (buf->len != 5) {
263 				LOG_ERR("Invalid unit info length: %d", buf->len);
264 				return;
265 			}
266 			net_buf_pull_u8(buf); /* Always 0x07 */
267 			rsp.unit_type = FIELD_GET(GENMASK(7, 3), net_buf_pull_u8(buf));
268 			rsp.company_id = net_buf_pull_be24(buf);
269 			avrcp_cb->unit_info_rsp(avrcp, &rsp);
270 		}
271 	}
272 }
273 
avrcp_subunit_info_handler(struct bt_avrcp * avrcp,struct net_buf * buf,bt_avctp_cr_t cr)274 static void avrcp_subunit_info_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
275 					   bt_avctp_cr_t cr)
276 {
277 	struct bt_avrcp_header *avrcp_hdr;
278 	struct bt_avrcp_subunit_info_rsp rsp;
279 	uint8_t tmp;
280 
281 	if (cr == BT_AVCTP_CMD) {
282 		/* ToDo */
283 	} else { /* BT_AVCTP_RESPONSE */
284 		if ((avrcp_cb != NULL) && (avrcp_cb->subunit_info_rsp != NULL)) {
285 			net_buf_pull(buf, sizeof(*avrcp_hdr));
286 			if (buf->len < 5) {
287 				LOG_ERR("Invalid subunit info length: %d", buf->len);
288 				return;
289 			}
290 			net_buf_pull_u8(buf); /* Always 0x07 */
291 			tmp = net_buf_pull_u8(buf);
292 			rsp.subunit_type = FIELD_GET(GENMASK(7, 3), tmp);
293 			rsp.max_subunit_id = FIELD_GET(GENMASK(2, 0), tmp);
294 			if (buf->len < (rsp.max_subunit_id << 1)) {
295 				LOG_ERR("Invalid subunit info response");
296 				return;
297 			}
298 			rsp.extended_subunit_type = buf->data;
299 			rsp.extended_subunit_id = rsp.extended_subunit_type + rsp.max_subunit_id;
300 			avrcp_cb->subunit_info_rsp(avrcp, &rsp);
301 		}
302 	}
303 }
304 
avrcp_pass_through_handler(struct bt_avrcp * avrcp,struct net_buf * buf,bt_avctp_cr_t cr)305 static void avrcp_pass_through_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
306 					   bt_avctp_cr_t cr)
307 {
308 	struct bt_avrcp_header *avrcp_hdr;
309 	struct bt_avrcp_passthrough_rsp rsp;
310 	uint8_t tmp;
311 
312 	if (cr == BT_AVCTP_CMD) {
313 		/* ToDo */
314 	} else { /* BT_AVCTP_RESPONSE */
315 		if ((avrcp_cb != NULL) && (avrcp_cb->subunit_info_rsp != NULL)) {
316 			avrcp_hdr = (struct bt_avrcp_header *)buf->data;
317 			net_buf_pull(buf, sizeof(*avrcp_hdr));
318 			if (buf->len < 2) {
319 				LOG_ERR("Invalid passthrough length: %d", buf->len);
320 				return;
321 			}
322 
323 			rsp.response = BT_AVRCP_HDR_GET_CTYPE_OR_RSP(avrcp_hdr);
324 			tmp = net_buf_pull_u8(buf);
325 			rsp.operation_id = FIELD_GET(GENMASK(6, 0), tmp);
326 			rsp.state = FIELD_GET(GENMASK(7, 7), tmp);
327 			rsp.len = net_buf_pull_u8(buf);
328 			rsp.payload = rsp.len ? buf->data : NULL;
329 
330 			avrcp_cb->passthrough_rsp(avrcp, &rsp);
331 		}
332 	}
333 }
334 
335 static const struct avrcp_handler handler[] = {
336 	{ BT_AVRCP_OPC_VENDOR_DEPENDENT, avrcp_vendor_dependent_handler },
337 	{ BT_AVRCP_OPC_UNIT_INFO, avrcp_unit_info_handler },
338 	{ BT_AVRCP_OPC_SUBUNIT_INFO, avrcp_subunit_info_handler },
339 	{ BT_AVRCP_OPC_PASS_THROUGH, avrcp_pass_through_handler },
340 };
341 
342 /* An AVRCP message received */
avrcp_recv(struct bt_avctp * session,struct net_buf * buf)343 static int avrcp_recv(struct bt_avctp *session, struct net_buf *buf)
344 {
345 	struct bt_avrcp *avrcp = AVRCP_AVCTP(session);
346 	struct bt_avctp_header *avctp_hdr;
347 	struct bt_avrcp_header *avrcp_hdr;
348 	uint8_t tid, i;
349 	bt_avctp_cr_t cr;
350 	bt_avrcp_rsp_t rsp;
351 	bt_avrcp_subunit_id_t subunit_id;
352 	bt_avrcp_subunit_type_t subunit_type;
353 
354 	avctp_hdr = (void *)buf->data;
355 	net_buf_pull(buf, sizeof(*avctp_hdr));
356 	if (buf->len < sizeof(*avrcp_hdr)) {
357 		LOG_ERR("invalid AVRCP header received");
358 		return -EINVAL;
359 	}
360 
361 	avrcp_hdr = (void *)buf->data;
362 	tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(avctp_hdr);
363 	cr = BT_AVCTP_HDR_GET_CR(avctp_hdr);
364 	rsp = BT_AVRCP_HDR_GET_CTYPE_OR_RSP(avrcp_hdr);
365 	subunit_id = BT_AVRCP_HDR_GET_SUBUNIT_ID(avrcp_hdr);
366 	subunit_type = BT_AVRCP_HDR_GET_SUBUNIT_TYPE(avrcp_hdr);
367 
368 	if (avctp_hdr->pid != sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS)) {
369 		return -EINVAL; /* Ignore other profile */
370 	}
371 
372 	LOG_DBG("AVRCP msg received, cr:0x%X, tid:0x%X, rsp: 0x%X, opc:0x%02X,", cr, tid, rsp,
373 		avrcp_hdr->opcode);
374 	if (cr == BT_AVCTP_RESPONSE) {
375 		if (avrcp_hdr->opcode == BT_AVRCP_OPC_VENDOR_DEPENDENT &&
376 		    rsp == BT_AVRCP_RSP_CHANGED) {
377 			/* Status changed notifiation, do not reset timer */
378 		} else if (avrcp_hdr->opcode == BT_AVRCP_OPC_PASS_THROUGH) {
379 			/* No max response time for pass through commands  */
380 		} else if (tid != avrcp->req.tid || subunit_type != avrcp->req.subunit ||
381 			   avrcp_hdr->opcode != avrcp->req.opcode) {
382 			LOG_WRN("unexpected AVRCP response, expected tid:0x%X, subunit:0x%X, "
383 				"opc:0x%02X",
384 				avrcp->req.tid, avrcp->req.subunit, avrcp->req.opcode);
385 		} else {
386 			k_work_cancel_delayable(&avrcp->timeout_work);
387 		}
388 	}
389 
390 	for (i = 0U; i < ARRAY_SIZE(handler); i++) {
391 		if (avrcp_hdr->opcode == handler[i].opcode) {
392 			handler[i].func(avrcp, buf, cr);
393 			return 0;
394 		}
395 	}
396 
397 	return 0;
398 }
399 
400 static const struct bt_avctp_ops_cb avctp_ops = {
401 	.connected = avrcp_connected,
402 	.disconnected = avrcp_disconnected,
403 	.recv = avrcp_recv,
404 };
405 
avrcp_accept(struct bt_conn * conn,struct bt_avctp ** session)406 static int avrcp_accept(struct bt_conn *conn, struct bt_avctp **session)
407 {
408 	struct bt_avrcp *avrcp;
409 
410 	avrcp = get_new_connection(conn);
411 	if (!avrcp) {
412 		return -ENOMEM;
413 	}
414 
415 	*session = &(avrcp->session);
416 	avrcp->session.ops = &avctp_ops;
417 
418 	LOG_DBG("session: %p", &(avrcp->session));
419 
420 	return 0;
421 }
422 
423 static struct bt_avctp_event_cb avctp_cb = {
424 	.accept = avrcp_accept,
425 };
426 
bt_avrcp_init(void)427 int bt_avrcp_init(void)
428 {
429 	int err;
430 
431 	/* Register event handlers with AVCTP */
432 	err = bt_avctp_register(&avctp_cb);
433 	if (err < 0) {
434 		LOG_ERR("AVRCP registration failed");
435 		return err;
436 	}
437 
438 #if defined(CONFIG_BT_AVRCP_TARGET)
439 	bt_sdp_register_service(&avrcp_tg_rec);
440 #endif /* CONFIG_BT_AVRCP_CONTROLLER */
441 
442 #if defined(CONFIG_BT_AVRCP_CONTROLLER)
443 	bt_sdp_register_service(&avrcp_ct_rec);
444 #endif /* CONFIG_BT_AVRCP_CONTROLLER */
445 
446 	LOG_DBG("AVRCP Initialized successfully.");
447 	return 0;
448 }
449 
bt_avrcp_connect(struct bt_conn * conn)450 struct bt_avrcp *bt_avrcp_connect(struct bt_conn *conn)
451 {
452 	struct bt_avrcp *avrcp;
453 	int err;
454 
455 	avrcp = get_new_connection(conn);
456 	if (!avrcp) {
457 		LOG_ERR("Cannot allocate memory");
458 		return NULL;
459 	}
460 
461 	avrcp->session.ops = &avctp_ops;
462 	err = bt_avctp_connect(conn, &(avrcp->session));
463 	if (err < 0) {
464 		/* If error occurs, undo the saving and return the error */
465 		memset(avrcp, 0, sizeof(struct bt_avrcp));
466 		LOG_DBG("AVCTP Connect failed");
467 		return NULL;
468 	}
469 
470 	LOG_DBG("Connection request sent");
471 	return avrcp;
472 }
473 
bt_avrcp_disconnect(struct bt_avrcp * avrcp)474 int bt_avrcp_disconnect(struct bt_avrcp *avrcp)
475 {
476 	int err;
477 
478 	err = bt_avctp_disconnect(&(avrcp->session));
479 	if (err < 0) {
480 		LOG_DBG("AVCTP Disconnect failed");
481 		return err;
482 	}
483 
484 	return err;
485 }
486 
avrcp_create_pdu(struct bt_avrcp * avrcp,bt_avctp_cr_t cr)487 static struct net_buf *avrcp_create_pdu(struct bt_avrcp *avrcp, bt_avctp_cr_t cr)
488 {
489 	struct net_buf *buf;
490 
491 	buf = bt_avctp_create_pdu(&(avrcp->session), cr, BT_AVCTP_PKT_TYPE_SINGLE,
492 				  BT_AVCTP_IPID_NONE, &avrcp->local_tid,
493 				  sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS));
494 
495 	return buf;
496 }
497 
avrcp_create_unit_pdu(struct bt_avrcp * avrcp,bt_avctp_cr_t cr)498 static struct net_buf *avrcp_create_unit_pdu(struct bt_avrcp *avrcp, bt_avctp_cr_t cr)
499 {
500 	struct net_buf *buf;
501 	struct bt_avrcp_frame *cmd;
502 
503 	buf = avrcp_create_pdu(avrcp, cr);
504 	if (!buf) {
505 		return NULL;
506 	}
507 
508 	cmd = net_buf_add(buf, sizeof(*cmd));
509 	memset(cmd, 0, sizeof(*cmd));
510 	BT_AVRCP_HDR_SET_CTYPE_OR_RSP(&cmd->hdr, cr == BT_AVCTP_CMD ? BT_AVRCP_CTYPE_STATUS
511 								    : BT_AVRCP_RSP_STABLE);
512 	BT_AVRCP_HDR_SET_SUBUNIT_ID(&cmd->hdr, BT_AVRCP_SUBUNIT_ID_IGNORE);
513 	BT_AVRCP_HDR_SET_SUBUNIT_TYPE(&cmd->hdr, BT_AVRCP_SUBUNIT_TYPE_UNIT);
514 	cmd->hdr.opcode = BT_AVRCP_OPC_UNIT_INFO;
515 
516 	return buf;
517 }
518 
avrcp_create_subunit_pdu(struct bt_avrcp * avrcp,bt_avctp_cr_t cr)519 static struct net_buf *avrcp_create_subunit_pdu(struct bt_avrcp *avrcp, bt_avctp_cr_t cr)
520 {
521 	struct net_buf *buf;
522 	struct bt_avrcp_frame *cmd;
523 
524 	buf = avrcp_create_pdu(avrcp, cr);
525 	if (!buf) {
526 		return NULL;
527 	}
528 
529 	cmd = net_buf_add(buf, sizeof(*cmd));
530 	memset(cmd, 0, sizeof(*cmd));
531 	BT_AVRCP_HDR_SET_CTYPE_OR_RSP(&cmd->hdr, cr == BT_AVCTP_CMD ? BT_AVRCP_CTYPE_STATUS
532 								    : BT_AVRCP_RSP_STABLE);
533 	BT_AVRCP_HDR_SET_SUBUNIT_ID(&cmd->hdr, BT_AVRCP_SUBUNIT_ID_IGNORE);
534 	BT_AVRCP_HDR_SET_SUBUNIT_TYPE(&cmd->hdr, BT_AVRCP_SUBUNIT_TYPE_UNIT);
535 	cmd->hdr.opcode = BT_AVRCP_OPC_SUBUNIT_INFO;
536 
537 	return buf;
538 }
539 
avrcp_create_passthrough_pdu(struct bt_avrcp * avrcp,bt_avctp_cr_t cr,bt_avrcp_ctype_t ctype)540 static struct net_buf *avrcp_create_passthrough_pdu(struct bt_avrcp *avrcp, bt_avctp_cr_t cr,
541 						    bt_avrcp_ctype_t ctype)
542 {
543 	struct net_buf *buf;
544 	struct bt_avrcp_frame *cmd;
545 
546 	buf = avrcp_create_pdu(avrcp, cr);
547 	if (!buf) {
548 		return NULL;
549 	}
550 
551 	cmd = net_buf_add(buf, sizeof(*cmd));
552 	memset(cmd, 0, sizeof(*cmd));
553 	BT_AVRCP_HDR_SET_CTYPE_OR_RSP(&cmd->hdr, ctype);
554 	BT_AVRCP_HDR_SET_SUBUNIT_ID(&cmd->hdr, BT_AVRCP_SUBUNIT_ID_ZERO);
555 	BT_AVRCP_HDR_SET_SUBUNIT_TYPE(&cmd->hdr, BT_AVRCP_SUBUNIT_TYPE_PANEL);
556 	cmd->hdr.opcode = BT_AVRCP_OPC_PASS_THROUGH;
557 
558 	return buf;
559 }
560 
avrcp_send(struct bt_avrcp * avrcp,struct net_buf * buf)561 static int avrcp_send(struct bt_avrcp *avrcp, struct net_buf *buf)
562 {
563 	int err;
564 	struct bt_avctp_header *avctp_hdr = (struct bt_avctp_header *)(buf->data);
565 	struct bt_avrcp_header *avrcp_hdr =
566 		(struct bt_avrcp_header *)(buf->data + sizeof(*avctp_hdr));
567 	uint8_t tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(avctp_hdr);
568 	bt_avctp_cr_t cr = BT_AVCTP_HDR_GET_CR(avctp_hdr);
569 	bt_avrcp_ctype_t ctype = BT_AVRCP_HDR_GET_CTYPE_OR_RSP(avrcp_hdr);
570 	bt_avrcp_subunit_type_t subunit_type = BT_AVRCP_HDR_GET_SUBUNIT_TYPE(avrcp_hdr);
571 
572 	LOG_DBG("AVRCP send cr:0x%X, tid:0x%X, ctype: 0x%X, opc:0x%02X\n", cr, tid, ctype,
573 		avrcp_hdr->opcode);
574 	err = bt_avctp_send(&(avrcp->session), buf);
575 	if (err < 0) {
576 		net_buf_unref(buf);
577 		LOG_ERR("AVCTP send fail, err = %d", err);
578 		return err;
579 	}
580 
581 	if (cr == BT_AVCTP_CMD && avrcp_hdr->opcode != BT_AVRCP_OPC_PASS_THROUGH) {
582 		avrcp->req.tid = tid;
583 		avrcp->req.subunit = subunit_type;
584 		avrcp->req.opcode = avrcp_hdr->opcode;
585 
586 		k_work_reschedule(&avrcp->timeout_work, AVRCP_TIMEOUT);
587 	}
588 
589 	return 0;
590 }
591 
bt_avrcp_get_unit_info(struct bt_avrcp * avrcp)592 int bt_avrcp_get_unit_info(struct bt_avrcp *avrcp)
593 {
594 	struct net_buf *buf;
595 	uint8_t param[5];
596 
597 	buf = avrcp_create_unit_pdu(avrcp, BT_AVCTP_CMD);
598 	if (!buf) {
599 		return -ENOMEM;
600 	}
601 
602 	memset(param, 0xFF, ARRAY_SIZE(param));
603 	net_buf_add_mem(buf, param, sizeof(param));
604 
605 	return avrcp_send(avrcp, buf);
606 }
607 
bt_avrcp_get_subunit_info(struct bt_avrcp * avrcp)608 int bt_avrcp_get_subunit_info(struct bt_avrcp *avrcp)
609 {
610 	struct net_buf *buf;
611 	uint8_t param[5];
612 
613 	buf = avrcp_create_subunit_pdu(avrcp, BT_AVCTP_CMD);
614 	if (!buf) {
615 		return -ENOMEM;
616 	}
617 
618 	memset(param, 0xFF, ARRAY_SIZE(param));
619 	param[0] = FIELD_PREP(GENMASK(6, 4), AVRCP_SUBUNIT_PAGE) |
620 		   FIELD_PREP(GENMASK(2, 0), AVRCP_SUBUNIT_EXTENSION_COED);
621 	net_buf_add_mem(buf, param, sizeof(param));
622 
623 	return avrcp_send(avrcp, buf);
624 }
625 
bt_avrcp_passthrough(struct bt_avrcp * avrcp,bt_avrcp_opid_t operation_id,bt_avrcp_button_state_t state,const uint8_t * payload,uint8_t len)626 int bt_avrcp_passthrough(struct bt_avrcp *avrcp, bt_avrcp_opid_t operation_id,
627 			 bt_avrcp_button_state_t state, const uint8_t *payload, uint8_t len)
628 {
629 	struct net_buf *buf;
630 	uint8_t param[2];
631 
632 	buf = avrcp_create_passthrough_pdu(avrcp, BT_AVCTP_CMD, BT_AVRCP_CTYPE_CONTROL);
633 	if (!buf) {
634 		return -ENOMEM;
635 	}
636 
637 	param[0] = FIELD_PREP(GENMASK(7, 7), state) | FIELD_PREP(GENMASK(6, 0), operation_id);
638 	param[1] = len;
639 	net_buf_add_mem(buf, param, sizeof(param));
640 	if (len) {
641 		net_buf_add_mem(buf, payload, len);
642 	}
643 
644 	return avrcp_send(avrcp, buf);
645 }
646 
bt_avrcp_register_cb(const struct bt_avrcp_cb * cb)647 int bt_avrcp_register_cb(const struct bt_avrcp_cb *cb)
648 {
649 	avrcp_cb = cb;
650 	return 0;
651 }
652