-
Notifications
You must be signed in to change notification settings - Fork 8.3k
implement a2dp remain todo/interfaces #76101
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
implement a2dp remain todo/interfaces #76101
Conversation
329eb7c to
472de7f
Compare
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
NULL checks for CONTAINER_OF() are almost always wrong. It's not a function, rather just pointer arithmetic. The only way you'd get NULL is if you give it a pointer which isn't NULL but has exactly the value NULL + offsetof(struct bt_a2dp_ep, sep). Checking for something like that seems pretty odd to me.
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.
Removed the cases and add some more BT_ASSERT for parameter sep.
472de7f to
c97f4f4
Compare
subsys/bluetooth/host/classic/a2dp.c
Outdated
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's the reason for changing to BT_ASSERT()? My preference would be that we completely remove that API from the Bluetooth subsystem and only use the Zephyr-wide assert API.
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.
Updated all assert
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
Sorry, but this is just unreadable. Could you introduce some helper variables which you prepare before the call to a2dp_ctrl_ind(), so that the actual call itself doesn't contain any conditionals. The resulting compiled code will most like be exactly the same since the compiler will optimize this either way. Also, please make sure you're using correct alignment of N tabs + 0-7 spaces, so that the split lines start right after the ( on the first line.
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.
Updated all the cases.
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
Same here.
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here.
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here.
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here.
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
And here
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.
Why are you using capital U in some places but lower-case u in others?
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.
Change all to U
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.
You should really fix this global lock stuff. First of all, a semaphore would be better than a mutex, and second of all it should be per-context rather than a global variable.
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.
change to semaphore and move it to the avdtp instance struct.
ef97ecf to
340a6a0
Compare
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's still inconsistency here. Just look at the defines above this. They all use lower-case u. Furthermore, there's also a namespace violation: this is a public Bluetooth header file, so all defines and symbols must use a BT_* or bt_* prefix.
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.
fixed.
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.
fixed.
No, there's still A2DP_MAX_IE_LENGTH which doesn't have a BT_ prefix.
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.
Fixed.
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's the reason for this formatting change? I believe the convention in existing is to not have a space after :, e.g:
zephyr/subsys/bluetooth/mesh/net.h
Lines 133 to 138 in 34206f5
| uint8_t groups_changed:1, /* Friend Subscription List needs updating */ | |
| pending_poll:1, /* Poll to be sent after subscription */ | |
| disable:1, /* Disable LPN after clearing */ | |
| fsn:1, /* Friend Sequence Number */ | |
| established:1, /* Friendship established */ | |
| clear_success:1; /* Friend Clear Confirm received */ |
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.
clang-format do it. The CI suggest me to do the clang-format.
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.
Ok. That's interesting. Fair enough then, but make sure that style changes to existing code stays in separate commits. Also explain the reasoning in the commit message of such commits.
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.
OK, I will do as this way next time.
340a6a0 to
8f979fd
Compare
subsys/bluetooth/host/classic/a2dp.c
Outdated
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.
You're making this much more complicated than it needs to be. Since you have an array of contexts with CONFIG_BT_MAX_CONN elements, you can simply create a 1:1 mapping from bt_conn to that array with the help of bt_conn_index(): https://docs.zephyrproject.org/latest/doxygen/html/group__bt__conn.html#gad4aed76b80cc815f748ad0e84ae3d87c
I.e. something like:
static struct bt_a2dp *get_new_connection(struct bt_conn_conn)
{
return &connection[bt_conn_index(conn)];
}I don't think you'll need the A2DP_LOCK() stuff after that either.
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.
Theoretically more than one A2DP L2CAP connections can be created based on one ACL connection. Then they are not 1:1 mapping. Usually there is only one A2DP L2CAP connection for one ACL connection. If we need to support it, then the 1:1 mapping cannot be used.
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 know, but can't you just make the general decision (at least for now) that you only support a single A2DP connection per ACL? It seems like you're already doing it, since the code is simply returning the same context if it already exists:
if (connection[i].used == 1U && connection[i].session.br_chan.chan.conn == conn) {
LOG_DBG("Conn already exists");
A2DP_UNLOCK();
return &connection[i];
}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 understand you, but I don't think it is good to limit the A2DP function in order to let the codes simple. I can fix the above codes that you mention. Is it OK?
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'm struggling to understand your point
- What I'm proposing is not adding any new limits over what you already have in the PR
- I don't see how you could have multiple "sessions" (i.e. multiple signaling channels) over a single ACL, since the AVDTP spec doesn't define anything like that (AFAIK). It defines the initial signaling channel and how meaning is applied to subsequent L2CAP channels using the AVDTP PSM. There can be at most signaling + 3 other channels according to AVDTP spec 1.3 section 5.4.6. Also see section 1.2 where it only talks about the signaling channel in singular rather than plural.
- Even if it was theoretically possible to have multiple signaling channels for an ACL. I'm not aware of any devices that do that. Are you? Adding code complexity for non-existent theoretical situation is not a good practice IMO.
- The array of contexts you have uses
CONFIG_BT_MAX_CONN, implying that you really do want a 1:1 relationship. Otherwise it'd make more sense to define a new Kconfig option for this.
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.
OK, @jhedberg Thanks, I see the follow line in the spec too. I will update the codes.
The signaling channel (1) is only established once between two streaming devices.
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.
updated. please help to review again.
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.
Please never create macros that make this kind of assumptions of the environment that they're invoked in, i.e. in this case that there has to be a given variable with a specific name. You should instead pass the session as a macro parameter. That said, I'm not sure what's the benefit of using macros here, since I don't think you want to preserve the possibility of redefining them or similar. Can't these just be one-line functions (which the compiler will certainly inline)?
static void avdtp_lock(struct bt_avdtp *session)
{
k_sem_take(&session->sem_lock);
}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.
Updated as you suggested.
8f979fd to
138e2c7
Compare
Hi @jhedberg I have split the commit to three commits. I do the code format firstly with one commit. Then add one commit for the reconfig implementation and codes optimization. The last one is the new added close, suspend and abort. The second commit is still little big, but it is hard and need more effort to split because there are some common optimizations in it. Please help to review again. Thanks. |
|
@MarkWangChinese are you still working on this? There are several failed CI checks. |
Hi @jhedberg Sure, I am still working on it. I will fix it recently. Thanks |
e819e14 to
665fc3d
Compare
665fc3d to
76914c4
Compare
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.
Hierarchically, this lock has no corresponding unlock.
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.
Fixed
76914c4 to
614bef5
Compare
b92ff78 to
b598181
Compare
c65b1b0 to
3e2900a
Compare
3e2900a to
9aa0b6f
Compare
run clang-format Signed-off-by: Mark Wang <[email protected]>
Implement the bt_a2dp_stream_reconfig: Modify reconfig_req callback to pass codec_cfg to application. Remove reconfig_rsp callback, config_rsp is used. Remove reconfigured callback, configured callback is used. move the status to common struct bt_avdtp_req, use same bt_avdtp_ctrl_params to process control-like avdtp cmds (start, open etc), use the same a2dp_ctrl_ind to process control-like cmds (start, open etc), use the same bt_a2dp_ctrl_cb to process control-like cmds (start, open etc), use the same bt_avdtp_ctrl to process control-like cmds (start, open etc), optimize getting a2dp conn by index, use sem to replace mutex and optimze the lock codes to be based on context/instance. Signed-off-by: Mark Wang <[email protected]>
implement avdtp close, suspend and abort and the a2dp interfaces. Signed-off-by: Mark Wang <[email protected]>
jhedberg
left a comment
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.
This looks generally good enough to be merged. Just a few comments regarding x vs X in hex values (not sure why you want X when almost everywhere the code uses x)
add test for reconfigure, release, suspend, abort and disconnect. app_config_req and app_reconfig_req always accept the req, so don't need to handle reject case. Signed-off-by: Mark Wang <[email protected]>
9aa0b6f to
dc179c0
Compare
Implement the remain A2DP todo/interfaces as follow:
Implement the bt_a2dp_stream_reconfig: Modify reconfig_req callback to
pass codec_cfg to application. Remove reconfig_rsp callback,
config_rsp is used. Remove reconfigured callback, configured callback is used.
Implement the bt_a2dp_stream_release: The release_req,
release_rsp and released callbacks are already defined,
implement them in this change.
Implement the bt_a2dp_stream_suspend: The suspend_req,
suspend_rsp and suspended callbacks are already defined,
implement them in this change.
Add and implement the bt_a2dp_stream_abort: Add abort_req,
abort_rsp and aborted callbacks.
Implement bt_a2dp_disconnect.
Simplify the codes: (1) use the same bt_avdtp_ctrl_params to process open,
start, suspend, close and abort operations. (2) use same a2dp_ctrl_ind to
process open, start, suspend, close and abort operations. (3) use the same
bt_a2dp_ctrl_cb to process open, start, suspend, close and abort operations.
(4) use the same bt_avdtp_ctrl to process open, start, suspend, close and
abort operations. (5) move the status to common struct bt_avdtp_req.
Add shell test.