Bluetooth: AVRCP: allow to parse unit info resposne.

Add AVRCP handler for UNIT INFO responses.

Signed-off-by: Zihao Gao <gaozihao@xiaomi.com>
This commit is contained in:
Zihao Gao 2024-10-30 10:45:03 +08:00 committed by Anas Nashif
commit 1b8ad2cf40
3 changed files with 74 additions and 3 deletions

View file

@ -19,6 +19,11 @@ extern "C" {
/** @brief AVRCP structure */
struct bt_avrcp;
struct bt_avrcp_unit_info_rsp {
uint8_t unit_type;
uint32_t company_id;
};
struct bt_avrcp_cb {
/** @brief An AVRCP connection has been established.
*
@ -36,6 +41,14 @@ struct bt_avrcp_cb {
* @param avrcp AVRCP connection object.
*/
void (*disconnected)(struct bt_avrcp *avrcp);
/** @brief Callback function for bt_avrcp_get_unit_info()
*
* Called when the get unit info process is completed.
*
* @param avrcp AVRCP connection object.
* @param rsp The response for UNIT INFO command.
*/
void (*unit_info_rsp)(struct bt_avrcp *avrcp, struct bt_avrcp_unit_info_rsp *rsp);
};
/** @brief Connect AVRCP.

View file

@ -38,7 +38,10 @@ struct bt_avrcp {
uint8_t local_tid;
};
static struct bt_avrcp_cb *avrcp_cb;
struct avrcp_handler {
bt_avrcp_opcode_t opcode;
void (*func)(struct bt_avrcp *avrcp, struct net_buf *buf, bt_avctp_cr_t cr);
};
#define AVRCP_TIMEOUT K_SECONDS(3) /* Shell be greater than TMTP (1000ms) */
#define AVRCP_AVCTP(_avctp) CONTAINER_OF(_avctp, struct bt_avrcp, session)
@ -240,13 +243,56 @@ static void avrcp_disconnected(struct bt_avctp *session)
}
}
static void avrcp_vendor_dependent_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
bt_avctp_cr_t cr)
{
/* ToDo */
}
static void avrcp_unit_info_handler(struct bt_avrcp *avrcp, struct net_buf *buf, bt_avctp_cr_t cr)
{
struct bt_avrcp_header *avrcp_hdr;
struct bt_avrcp_unit_info_rsp rsp;
if (cr == BT_AVCTP_CMD) {
/* ToDo */
} else { /* BT_AVCTP_RESPONSE */
if ((avrcp_cb != NULL) && (avrcp_cb->unit_info_rsp != NULL)) {
net_buf_pull(buf, sizeof(*avrcp_hdr));
net_buf_pull_u8(buf); /* Always 0x07 */
rsp.unit_type = (net_buf_pull_u8(buf) >> 3); /* Bit [8:4] Shall be 0x09 */
rsp.company_id = net_buf_pull_be24(buf);
avrcp_cb->unit_info_rsp(avrcp, &rsp);
}
}
}
static void avrcp_subunit_info_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
bt_avctp_cr_t cr)
{
/* ToDo */
}
static void avrcp_pass_through_handler(struct bt_avrcp *avrcp, struct net_buf *buf,
bt_avctp_cr_t cr)
{
/* ToDo */
}
static const struct avrcp_handler handler[] = {
{ BT_AVRCP_OPC_VENDOR_DEPENDENT, avrcp_vendor_dependent_handler },
{ BT_AVRCP_OPC_UNIT_INFO, avrcp_unit_info_handler },
{ BT_AVRCP_OPC_SUBUNIT_INFO, avrcp_subunit_info_handler },
{ BT_AVRCP_OPC_PASS_THROUGH, avrcp_pass_through_handler },
};
/* 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;
uint8_t tid;
uint8_t tid, i;
bt_avctp_cr_t cr;
bt_avrcp_ctype_t ctype;
bt_avrcp_subunit_id_t subunit_id;
@ -284,7 +330,12 @@ static int avrcp_recv(struct bt_avctp *session, struct net_buf *buf)
}
}
/* TODO: add handlers */
for (i = 0U; i < ARRAY_SIZE(handler); i++) {
if (avrcp_hdr->opcode == handler[i].opcode) {
handler[i].func(avrcp, buf, cr);
return 0;
}
}
return 0;
}

View file

@ -42,9 +42,16 @@ static void avrcp_disconnected(struct bt_avrcp *avrcp)
shell_print(ctx_shell, "AVRCP disconnected");
}
static void avrcp_unit_info_rsp(struct bt_avrcp *avrcp, struct bt_avrcp_unit_info_rsp *rsp)
{
shell_print(ctx_shell, "AVRCP unit info received, unit type = 0x%02x, company_id = 0x%06x",
rsp->unit_type, rsp->company_id);
}
static struct bt_avrcp_cb avrcp_cb = {
.connected = avrcp_connected,
.disconnected = avrcp_disconnected,
.unit_info_rsp = avrcp_unit_info_rsp,
};
static int register_cb(const struct shell *sh)