Bluetooth: Shell: AVRCP: support unit info request and response
Add avrcp_unit_info_req callback function in shell and a command to set the unit info response. Signed-off-by: Make Shi <make.shi@nxp.com>
This commit is contained in:
parent
c95d3167e2
commit
ba05d5c2b2
@ -30,8 +30,11 @@
|
||||
#include "common/bt_shell_private.h"
|
||||
|
||||
struct bt_avrcp_ct *default_ct;
|
||||
struct bt_avrcp_tg *default_tg;
|
||||
static bool avrcp_ct_registered;
|
||||
static bool avrcp_tg_registered;
|
||||
static uint8_t local_tid;
|
||||
static uint8_t tg_tid;
|
||||
|
||||
static uint8_t get_next_tid(void)
|
||||
{
|
||||
@ -54,6 +57,7 @@ static void avrcp_ct_disconnected(struct bt_avrcp_ct *ct)
|
||||
{
|
||||
bt_shell_print("AVRCP CT disconnected");
|
||||
local_tid = 0;
|
||||
default_ct = NULL;
|
||||
}
|
||||
|
||||
static void avrcp_get_cap_rsp(struct bt_avrcp_ct *ct, uint8_t tid,
|
||||
@ -111,7 +115,7 @@ static void avrcp_passthrough_rsp(struct bt_avrcp_ct *ct, uint8_t tid, bt_avrcp_
|
||||
}
|
||||
}
|
||||
|
||||
static struct bt_avrcp_ct_cb avrcp_ct_cb = {
|
||||
static struct bt_avrcp_ct_cb app_avrcp_ct_cb = {
|
||||
.connected = avrcp_ct_connected,
|
||||
.disconnected = avrcp_ct_disconnected,
|
||||
.get_cap_rsp = avrcp_get_cap_rsp,
|
||||
@ -120,6 +124,30 @@ static struct bt_avrcp_ct_cb avrcp_ct_cb = {
|
||||
.passthrough_rsp = avrcp_passthrough_rsp,
|
||||
};
|
||||
|
||||
static void avrcp_tg_connected(struct bt_conn *conn, struct bt_avrcp_tg *tg)
|
||||
{
|
||||
bt_shell_print("AVRCP TG connected");
|
||||
default_tg = tg;
|
||||
}
|
||||
|
||||
static void avrcp_tg_disconnected(struct bt_avrcp_tg *tg)
|
||||
{
|
||||
bt_shell_print("AVRCP TG disconnected");
|
||||
default_tg = NULL;
|
||||
}
|
||||
|
||||
static void avrcp_unit_info_req(struct bt_avrcp_tg *tg, uint8_t tid)
|
||||
{
|
||||
bt_shell_print("AVRCP unit info request received");
|
||||
tg_tid = tid;
|
||||
}
|
||||
|
||||
static struct bt_avrcp_tg_cb app_avrcp_tg_cb = {
|
||||
.connected = avrcp_tg_connected,
|
||||
.disconnected = avrcp_tg_disconnected,
|
||||
.unit_info_req = avrcp_unit_info_req,
|
||||
};
|
||||
|
||||
static int register_ct_cb(const struct shell *sh)
|
||||
{
|
||||
int err;
|
||||
@ -128,12 +156,12 @@ static int register_ct_cb(const struct shell *sh)
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bt_avrcp_ct_register_cb(&avrcp_ct_cb);
|
||||
err = bt_avrcp_ct_register_cb(&app_avrcp_ct_cb);
|
||||
if (!err) {
|
||||
avrcp_ct_registered = true;
|
||||
shell_print(sh, "AVRCP callbacks registered");
|
||||
shell_print(sh, "AVRCP CT callbacks registered");
|
||||
} else {
|
||||
shell_print(sh, "failed to register callbacks");
|
||||
shell_print(sh, "failed to register AVRCP CT callbacks");
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -151,14 +179,47 @@ static int cmd_register_ct_cb(const struct shell *sh, int32_t argc, char *argv[]
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int register_tg_cb(const struct shell *sh)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (avrcp_tg_registered) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bt_avrcp_tg_register_cb(&app_avrcp_tg_cb);
|
||||
if (!err) {
|
||||
avrcp_tg_registered = true;
|
||||
shell_print(sh, "AVRCP TG callbacks registered");
|
||||
} else {
|
||||
shell_print(sh, "failed to register AVRCP TG callbacks");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_register_tg_cb(const struct shell *sh, int32_t argc, char *argv[])
|
||||
{
|
||||
if (avrcp_tg_registered) {
|
||||
shell_print(sh, "already registered");
|
||||
return 0;
|
||||
}
|
||||
|
||||
register_tg_cb(sh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[])
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!avrcp_ct_registered && register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (!avrcp_tg_registered && register_tg_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (!default_conn) {
|
||||
@ -167,7 +228,7 @@ static int cmd_connect(const struct shell *sh, int32_t argc, char *argv[])
|
||||
}
|
||||
|
||||
err = bt_avrcp_connect(default_conn);
|
||||
if (!err) {
|
||||
if (err) {
|
||||
shell_error(sh, "fail to connect AVRCP");
|
||||
}
|
||||
|
||||
@ -176,15 +237,18 @@ 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[])
|
||||
{
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if ((!avrcp_ct_registered) && (!avrcp_tg_registered)) {
|
||||
shell_error(sh, "Neither CT nor TG callbacks are registered.");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (default_ct != NULL) {
|
||||
if (!default_conn) {
|
||||
shell_print(sh, "Not connected");
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if ((default_ct != NULL) || (default_tg != NULL)) {
|
||||
bt_avrcp_disconnect(default_conn);
|
||||
default_ct = NULL;
|
||||
} else {
|
||||
shell_error(sh, "AVRCP is not connected");
|
||||
}
|
||||
@ -194,10 +258,8 @@ 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[])
|
||||
{
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!avrcp_ct_registered && register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (default_ct != NULL) {
|
||||
@ -209,12 +271,36 @@ static int cmd_get_unit_info(const struct shell *sh, int32_t argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_send_unit_info_rsp(const struct shell *sh, int32_t argc, char *argv[])
|
||||
{
|
||||
struct bt_avrcp_unit_info_rsp rsp;
|
||||
int err;
|
||||
|
||||
if (!avrcp_tg_registered && register_tg_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
rsp.unit_type = BT_AVRCP_SUBUNIT_TYPE_PANEL;
|
||||
rsp.company_id = BT_AVRCP_COMPANY_ID_BLUETOOTH_SIG;
|
||||
|
||||
if (default_tg != NULL) {
|
||||
err = bt_avrcp_tg_send_unit_info_rsp(default_tg, tg_tid, &rsp);
|
||||
if (!err) {
|
||||
shell_print(sh, "AVRCP send unit info response");
|
||||
} else {
|
||||
shell_error(sh, "Failed to send unit info response");
|
||||
}
|
||||
} else {
|
||||
shell_error(sh, "AVRCP is not connected");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_get_subunit_info(const struct shell *sh, int32_t argc, char *argv[])
|
||||
{
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!avrcp_ct_registered && register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (default_ct != NULL) {
|
||||
@ -229,17 +315,15 @@ static int cmd_get_subunit_info(const struct shell *sh, int32_t argc, char *argv
|
||||
static int cmd_passthrough(const struct shell *sh, bt_avrcp_opid_t opid, const uint8_t *payload,
|
||||
uint8_t len)
|
||||
{
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!avrcp_ct_registered && register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (default_ct != NULL) {
|
||||
bt_avrcp_ct_passthrough(default_ct, get_next_tid(), opid, BT_AVRCP_BUTTON_PRESSED,
|
||||
payload, len);
|
||||
payload, len);
|
||||
bt_avrcp_ct_passthrough(default_ct, get_next_tid(), opid, BT_AVRCP_BUTTON_RELEASED,
|
||||
payload, len);
|
||||
payload, len);
|
||||
} else {
|
||||
shell_error(sh, "AVRCP is not connected");
|
||||
}
|
||||
@ -261,10 +345,8 @@ static int cmd_get_cap(const struct shell *sh, int32_t argc, char *argv[])
|
||||
{
|
||||
const char *cap_id;
|
||||
|
||||
if (!avrcp_ct_registered) {
|
||||
if (register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (!avrcp_ct_registered && register_ct_cb(sh) != 0) {
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (default_ct == NULL) {
|
||||
@ -284,7 +366,7 @@ static int cmd_get_cap(const struct shell *sh, int32_t argc, char *argv[])
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
ct_cmds,
|
||||
SHELL_CMD_ARG(register_ct_cb, NULL, "register avrcp callbacks", cmd_register_ct_cb, 1, 0),
|
||||
SHELL_CMD_ARG(register_cb, NULL, "register avrcp ct callbacks", cmd_register_ct_cb, 1, 0),
|
||||
SHELL_CMD_ARG(get_unit, NULL, "get unit info", cmd_get_unit_info, 1, 0),
|
||||
SHELL_CMD_ARG(get_subunit, NULL, "get subunit info", cmd_get_subunit_info, 1, 0),
|
||||
SHELL_CMD_ARG(get_cap, NULL, "get capabilities <cap_id: company or events>", cmd_get_cap, 2,
|
||||
@ -293,6 +375,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
SHELL_CMD_ARG(pause, NULL, "request a pause at the remote player", cmd_pause, 1, 0),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
tg_cmds,
|
||||
SHELL_CMD_ARG(register_cb, NULL, "register avrcp tg callbacks", cmd_register_tg_cb, 1, 0),
|
||||
SHELL_CMD_ARG(send_unit_rsp, NULL, "send unit info response", cmd_send_unit_info_rsp, 1, 0),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
static int cmd_avrcp(const struct shell *sh, size_t argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
@ -310,7 +398,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
|
||||
avrcp_cmds,
|
||||
SHELL_CMD_ARG(connect, NULL, "connect AVRCP", cmd_connect, 1, 0),
|
||||
SHELL_CMD_ARG(disconnect, NULL, "disconnect AVRCP", cmd_disconnect, 1, 0),
|
||||
SHELL_CMD(ct, &ct_cmds, "AVRCP CT shell commands", cmd_avrcp),
|
||||
SHELL_CMD(ct, &ct_cmds, "AVRCP CT shell commands", cmd_avrcp),
|
||||
SHELL_CMD(tg, &tg_cmds, "AVRCP TG shell commands", cmd_avrcp),
|
||||
SHELL_SUBCMD_SET_END);
|
||||
|
||||
SHELL_CMD_ARG_REGISTER(avrcp, &avrcp_cmds, "Bluetooth AVRCP sh commands", cmd_avrcp, 1, 1);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user