Skip to content

Commit

Permalink
Bluetooth : AVRCP: allow to receive an AVRCP message.
Browse files Browse the repository at this point in the history
This patch received an AVRCP message and remove timeout timers.

Signed-off-by: Zihao Gao <[email protected]>
  • Loading branch information
Zihao Gao committed Oct 14, 2024
1 parent 8284f18 commit 7dfbae4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 22 deletions.
4 changes: 2 additions & 2 deletions subsys/bluetooth/host/classic/avctp.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,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;
}
Expand Down
41 changes: 40 additions & 1 deletion subsys/bluetooth/host/classic/avrcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,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)
Expand Down Expand Up @@ -397,7 +437,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;
Expand Down
41 changes: 22 additions & 19 deletions subsys/bluetooth/host/classic/shell/avrcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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)
{
Expand All @@ -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);

0 comments on commit 7dfbae4

Please sign in to comment.