-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bluetooth: AVRCP: Implement unit message reception on the AVRCP target #85917
base: main
Are you sure you want to change the base?
Conversation
c4c6aa7
to
3dad734
Compare
@@ -177,6 +177,13 @@ struct bt_avrcp_cb { | |||
* @param rsp The response for PASS THROUGH command. | |||
*/ | |||
void (*passthrough_rsp)(struct bt_avrcp *avrcp, struct bt_avrcp_passthrough_rsp *rsp); | |||
/** @brief Callback function called when received unit info command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave one line between 179 and 180 would be better :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I remember there was no space before in these call back function list, and I'd like to keep it consistent. :) Anyway, I'll add a space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I remember there was no space before in these call back function list, and I'd like to keep it consistent. :) Anyway, I'll add a space.
Yes, I added it here #84367 :)
@@ -249,6 +256,17 @@ int bt_avrcp_get_subunit_info(struct bt_avrcp *avrcp); | |||
int 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); | |||
|
|||
/** @brief Response unit info command. | |||
* | |||
* Send the response unit info command when the receiver will be notified by the registered |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
response unit info command -> unit info response
int bt_avrcp_response_unit_info(struct bt_avrcp *avrcp, struct bt_avrcp_unit_info_rsp *rsp) | ||
{ | ||
struct net_buf *buf; | ||
uint8_t data[5]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to keep style consistent, e.g., use param[5].
rsp.unit_type = 0x9; | ||
rsp.company_id = 0x001958; /*BT SIG registered Company ID*/ | ||
|
||
err = bt_avrcp_response_unit_info(avrcp, &rsp); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution: this is in the callback thread, and might lead to assertion in net_buf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, let me check it
4f7f13f
to
510fc82
Compare
@@ -249,6 +257,16 @@ int bt_avrcp_get_subunit_info(struct bt_avrcp *avrcp); | |||
int 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set -> Send?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also okay to use "send". I use set because I want it to correspond to the above API bt_avrcp_get_unit_info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also okay to use "send". I use set because I want it to correspond to the above API bt_avrcp_get_unit_info.
I think set
usualy means to provide a value and save at the local device, or set a configuration to the remote.
However, this interface is to inform the remote device, rather than a configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, Here using "Send" here can indeed better express the actual meaning than "Set" for this function. I'll update the comments and the function name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally fine to me.
/* ToDo */ | ||
if ((avrcp_cb != NULL) && (avrcp_cb->unit_info_req != NULL)) { | ||
avrcp_hdr = (void *)buf->data; | ||
net_buf_pull(buf, sizeof(*avrcp_hdr)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The buf->len
needs to be checked before pulling the net buffer.
After checking the whole receiving data path, I found an issue that the buf->len
is also not checked before accessing the buf->data
in function avrcp_recv
.
zephyr/subsys/bluetooth/host/classic/avrcp.c
Lines 354 to 366 in 7ee4011
avctp_hdr = (void *)buf->data; | |
net_buf_pull(buf, sizeof(*avctp_hdr)); | |
if (buf->len < sizeof(*avrcp_hdr)) { | |
LOG_ERR("invalid AVRCP header received"); | |
return -EINVAL; | |
} | |
avrcp_hdr = (void *)buf->data; | |
tid = BT_AVCTP_HDR_GET_TRANSACTION_LABLE(avctp_hdr); | |
cr = BT_AVCTP_HDR_GET_CR(avctp_hdr); | |
rsp = BT_AVRCP_HDR_GET_CTYPE_OR_RSP(avrcp_hdr); | |
subunit_id = BT_AVRCP_HDR_GET_SUBUNIT_ID(avrcp_hdr); | |
subunit_type = BT_AVRCP_HDR_GET_SUBUNIT_TYPE(avrcp_hdr); |
@@ -253,9 +253,26 @@ static void avrcp_unit_info_handler(struct bt_avrcp *avrcp, struct net_buf *buf, | |||
{ | |||
struct bt_avrcp_header *avrcp_hdr; | |||
struct bt_avrcp_unit_info_rsp rsp; | |||
bt_avrcp_subunit_type_t subunit_type; | |||
|
|||
if (cr == BT_AVCTP_CMD) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to split the handler for request and response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will split the AVRCP code to handle with different role CT and CG.
if ((subunit_type != BT_AVRCP_SUBUNIT_TYPE_UNIT) || | ||
(avrcp_hdr->opcode != BT_AVRCP_OPC_UNIT_INFO)) { | ||
LOG_ERR("Invalid unit info command"); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the command, if the command is invalid, the response should be sent internally instead of ignoring it.
|
||
if (cr == BT_AVCTP_CMD) { | ||
/* ToDo */ | ||
if ((avrcp_cb != NULL) && (avrcp_cb->unit_info_req != NULL)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command handling should be controlled by the registered callback. Such as, if the command is not valid or the command is unsupported, the error response should be sent directly.
{ | ||
struct net_buf *buf; | ||
|
||
buf = avrcp_create_unit_pdu(avrcp, BT_AVCTP_RESPONSE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TID
should be same with the TID
of the command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TID should added as all function calls and callback parameter, handled in application code side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the TID cannot be set by application in your PR.
And I think if the TID need be set by application, the TID of command should also be notified to application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you comments as in #85910, these is only one command is ongoing , so also need the TID sent should be same with the TID of the command.
} | ||
|
||
/* Add additional info */ | ||
net_buf_add_u8(buf, 0x07); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the mean of 7
? I think the hard code should be defined as a MICRO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0x07
means page = 0
and extension_code = 7
page
shall only be greater than 0 when the number of extended units
exceeds 4, which is not possible at unit info response, where the number of extended units
is 0.
extension_code
is not defined currently, so all three bits are set to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UNIT INFO response generally has the same structure as SUBUNIT INFO response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@makeshi can use
FIELD_PREP(GENMASK(6, 4), AVRCP_SUBUNIT_PAGE) |
FIELD_PREP(GENMASK(2, 0), AVRCP_SUBUNIT_EXTENSION_COED);
Which exactly is 0x7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0x07
meanspage = 0
andextension_code = 7
page
shall only be greater than 0 when thenumber of extended units
exceeds 4, which is not possible at unit info response, where thenumber of extended units
is 0.extension_code
is not defined currently, so all three bits are set to 1.
The command is unit info
instead of subunit info
.
From UNIT INFO status command response format
, it is a hardcode without any comments. It seams the field has not yet explained of what it means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @makeshi @lylezhu2012
0x07
meanspage = 0
andextension_code = 7
page
shall only be greater than 0 when thenumber of extended units
exceeds 4, which is not possible at unit info response, where thenumber of extended units
is 0.extension_code
is not defined currently, so all three bits are set to 1.The command is
unit info
instead ofsubunit info
. FromUNIT INFO status command response format
, it is a hardcode without any comments. It seams the field has not yet explained of what it means.
Then just put 0x7
is fine, to exactly match the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's good to have at least a code comment pointing out that the constant is hard-coded in the spec
/* Add additional info */ | ||
net_buf_add_u8(buf, 0x07); | ||
/* Add Unit Type info */ | ||
net_buf_add_u8(buf, FIELD_PREP(GENMASK(7, 3), (rsp->unit_type))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For AVRCP
, the unit_type
should be Panel
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@makeshi @lylezhu2012
We may consider to expose bt_avrcp_subunit_type_t
(BT_AVRCP_SUBUNIT_TYPE_PANEL = 0x9
) to users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think we could expose it
Please set a readable and useful PR title and add more description the PR body, the PR body should be used for more details about the change and not to ask for reviews. |
510fc82
to
54dd129
Compare
54dd129
to
e772dc6
Compare
Add a new callback to support the situation when a unit info command is received, and add an API to respond to the unit info command. Signed-off-by: Make Shi <make.shi@nxp.com>
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>
e772dc6
to
865fe77
Compare
@gzh-terry Please help review it, thanks.