Bluetooth : AVRCP: allow to receive an AVRCP message.

This patch received an AVRCP message and remove timeout timers.

Signed-off-by: Zihao Gao <gaozihao@xiaomi.com>
This commit is contained in:
Zihao Gao 2024-10-30 10:45:02 +08:00 committed by Anas Nashif
parent 4c932b4b80
commit 9af026dcbf
3 changed files with 64 additions and 22 deletions

View file

@ -93,8 +93,8 @@ static int avctp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
default:
LOG_ERR("unsupported AVCTP PID received: 0x%04x", sys_be16_to_cpu(hdr->pid));
if (hdr->cr == BT_AVCTP_CMD) {
rsp = bt_avctp_create_pdu(session, BT_AVCTP_RESPONSE,
BT_AVCTP_IPID_INVALID, &hdr->tid, hdr->pid);
rsp = bt_avctp_create_pdu(session, BT_AVCTP_RESPONSE, BT_AVCTP_IPID_INVALID,
&hdr->tid, hdr->pid);
if (!rsp) {
return -ENOMEM;
}

View file

@ -240,9 +240,49 @@ static void avrcp_disconnected(struct bt_avctp *session)
}
}
/* An AVRCP message received */
static int avrcp_recv(struct bt_avctp *session, struct net_buf *buf)
{
struct bt_avrcp *avrcp = AVRCP_AVCTP(session);
struct bt_avctp_header *avctp_hdr;
struct bt_avrcp_header *avrcp_hdr;
avctp_hdr = (void *)buf->data;
net_buf_pull(buf, sizeof(*avctp_hdr));
avrcp_hdr = (void *)buf->data;
if (avctp_hdr->pid != sys_cpu_to_be16(BT_SDP_AV_REMOTE_SVCLASS)) {
return -EINVAL; /* Ignore other profile */
}
LOG_DBG("AVRCP msg received, cr:0x%X, tid:0x%X, ctype: 0x%X, opc:0x%02X,", avctp_hdr->cr,
avctp_hdr->tid, avrcp_hdr->ctype, avrcp_hdr->opcode);
if (avctp_hdr->cr == BT_AVCTP_RESPONSE) {
if (avrcp_hdr->opcode == BT_AVRCP_OPC_VENDOR_DEPENDENT &&
avrcp_hdr->ctype == BT_AVRCP_CTYPE_CHANGED) {
/* Status changed notifiation, do not reset timer */
} else if (avrcp_hdr->opcode == BT_AVRCP_OPC_PASS_THROUGH) {
/* No max response time for pass through commands */
} else if (avrcp->req.tid != avctp_hdr->tid ||
avrcp->req.subunit != avrcp_hdr->subunit_id ||
avrcp->req.opcode != avrcp_hdr->opcode) {
LOG_WRN("unexpected AVRCP response, expected tid:0x%X, subunit:0x%X, "
"opc:0x%02X",
avrcp->req.tid, avrcp->req.subunit, avrcp->req.opcode);
} else {
k_work_cancel_delayable(&avrcp->timeout_work);
}
}
/* TODO: add handlers */
return 0;
}
static const struct bt_avctp_ops_cb avctp_ops = {
.connected = avrcp_connected,
.disconnected = avrcp_disconnected,
.recv = avrcp_recv,
};
static int avrcp_accept(struct bt_conn *conn, struct bt_avctp **session)
@ -379,7 +419,6 @@ static int avrcp_send(struct bt_avrcp *avrcp, struct net_buf *buf)
avrcp->req.opcode = avrcp_hdr.opcode;
k_work_reschedule(&avrcp->timeout_work, AVRCP_TIMEOUT);
/* TODO: k_work_cancel_delayable(&avrcp->timeout_work); when response received */
}
return 0;

View file

@ -31,14 +31,6 @@
struct bt_avrcp *default_avrcp;
static bool avrcp_registered;
#define CHECK_REGISTER_CALLBACKS(_sh, _errno) \
do { \
if (!avrcp_registered) { \
if (register_cb(_sh) != 0) \
return _errno; \
} \
} while (0)
static void avrcp_connected(struct bt_avrcp *avrcp)
{
default_avrcp = avrcp;
@ -88,7 +80,11 @@ static int cmd_register_cb(const struct shell *sh, int32_t argc, char *argv[])
static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[])
{
CHECK_REGISTER_CALLBACKS(sh, -ENOEXEC);
if (!avrcp_registered) {
if (register_cb(sh) != 0) {
return -ENOEXEC;
}
}
if (!default_conn) {
shell_error(sh, "BR/EDR not connected");
@ -105,7 +101,11 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[])
static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[])
{
CHECK_REGISTER_CALLBACKS(sh, -ENOEXEC);
if (!avrcp_registered) {
if (register_cb(sh) != 0) {
return -ENOEXEC;
}
}
if (default_avrcp != NULL) {
bt_avrcp_disconnect(default_avrcp);
@ -119,7 +119,11 @@ static int cmd_disconnect(const struct shell *sh, int32_t argc, char *argv[])
static int cmd_get_unit_info(const struct shell *sh, int32_t argc, char *argv[])
{
CHECK_REGISTER_CALLBACKS(sh, -ENOEXEC);
if (!avrcp_registered) {
if (register_cb(sh) != 0) {
return -ENOEXEC;
}
}
if (default_avrcp != NULL) {
bt_avrcp_get_unit_info(default_avrcp);
@ -131,12 +135,12 @@ static int cmd_get_unit_info(const struct shell *sh, int32_t argc, char *argv[])
}
SHELL_STATIC_SUBCMD_SET_CREATE(avrcp_cmds,
SHELL_CMD_ARG(register_cb, NULL, "register avrcp callbacks",
cmd_register_cb, 1, 0),
SHELL_CMD_ARG(connect, NULL, "<address>", cmd_connect, 2, 0),
SHELL_CMD_ARG(disconnect, NULL, "<address>", cmd_disconnect, 2, 0),
SHELL_CMD_ARG(get_unit, NULL, "<address>", cmd_get_unit_info, 2, 0),
SHELL_SUBCMD_SET_END);
SHELL_CMD_ARG(register_cb, NULL, "register avrcp callbacks",
cmd_register_cb, 1, 0),
SHELL_CMD_ARG(connect, NULL, "<address>", cmd_connect, 2, 0),
SHELL_CMD_ARG(disconnect, NULL, "<address>", cmd_disconnect, 2, 0),
SHELL_CMD_ARG(get_unit, NULL, "<address>", cmd_get_unit_info, 2, 0),
SHELL_SUBCMD_SET_END);
static int cmd_avrcp(const struct shell *sh, size_t argc, char **argv)
{
@ -151,5 +155,4 @@ static int cmd_avrcp(const struct shell *sh, size_t argc, char **argv)
return -ENOEXEC;
}
SHELL_CMD_ARG_REGISTER(avrcp, &avrcp_cmds, "Bluetooth AVRCP sh commands",
cmd_avrcp, 1, 1);
SHELL_CMD_ARG_REGISTER(avrcp, &avrcp_cmds, "Bluetooth AVRCP sh commands", cmd_avrcp, 1, 1);