Skip to content

Commit 3544546

Browse files
MarkWangChinesekartben
authored andcommitted
bluetooth: a2dp: implement the get_all_capabilities
From avdtp spec, the get_all_capablities should be used if the avdtp version is v1.3, otherwise the get_capabilities should be used. Signed-off-by: Mark Wang <yichang.wang@nxp.com>
1 parent d8f35a5 commit 3544546

File tree

7 files changed

+200
-62
lines changed

7 files changed

+200
-62
lines changed

include/zephyr/bluetooth/classic/a2dp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,15 @@ struct bt_a2dp_discover_param {
391391
* it save endpoint info internally.
392392
*/
393393
struct bt_avdtp_sep_info *seps_info;
394+
/** The AVDTP version of the peer's A2DP sdp service.
395+
* Stack uses it to determine using get_all_cap or get_cap cmd. When both
396+
* versions are v1.3 or bigger version, get_all_cap is used, otherwise
397+
* get_cap is used.
398+
* It is the same value of the avdtp sepcificaiton's version value.
399+
* For example: 0x0103 means version 1.3
400+
* If the value is 0 (unknown), stack process it as less than v1.3
401+
*/
402+
uint16_t avdtp_version;
394403
/** The max count of seps (stream endpoint) that can be got in this call route */
395404
uint8_t sep_count;
396405
};

include/zephyr/bluetooth/classic/avdtp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
extern "C" {
1616
#endif
1717

18+
#define AVDTP_VERSION_1_3 0x0103 /**< AVDTP version 1.3 value */
19+
20+
#define AVDTP_VERSION AVDTP_VERSION_1_3 /**< AVDTP version used by Zephyr */
21+
1822
/**
1923
* @brief AVDTP error code
2024
*/

subsys/bluetooth/host/classic/a2dp.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,13 @@ static int a2dp_discovery_ind(struct bt_avdtp *session, uint8_t *errcode)
125125
}
126126

127127
static int a2dp_get_capabilities_ind(struct bt_avdtp *session, struct bt_avdtp_sep *sep,
128-
struct net_buf *rsp_buf, uint8_t *errcode)
128+
struct net_buf *rsp_buf, bool get_all_caps, uint8_t *errcode)
129129
{
130+
/* The Reporting, Recovery, Content Protection, Header Compression, Multiplexing and
131+
* Delay Reporting services are not supported, so the same response is replied as
132+
* get_capabilities.
133+
*/
134+
ARG_UNUSED(get_all_caps);
130135
struct bt_a2dp_ep *ep;
131136

132137
__ASSERT(sep, "Invalid sep");
@@ -613,6 +618,17 @@ static int bt_a2dp_get_sep_caps(struct bt_a2dp *a2dp)
613618
a2dp->get_capabilities_param.req.func = bt_a2dp_get_capabilities_cb;
614619
a2dp->get_capabilities_param.stream_endpoint_id =
615620
a2dp->discover_cb_param->seps_info[a2dp->get_cap_index].id;
621+
622+
/* The legacy Get Capabilities procedure is deprecated in cases
623+
* where backwards compatibility with AVDTP 1.2 and earlier is irrelevant.
624+
*/
625+
if (AVDTP_VERSION >= AVDTP_VERSION_1_3 &&
626+
a2dp->discover_cb_param->avdtp_version >= AVDTP_VERSION_1_3) {
627+
a2dp->get_capabilities_param.get_all_caps = true;
628+
} else {
629+
a2dp->get_capabilities_param.get_all_caps = false;
630+
}
631+
616632
err = bt_avdtp_get_capabilities(&a2dp->session,
617633
&a2dp->get_capabilities_param);
618634

@@ -699,7 +715,6 @@ int bt_a2dp_discover(struct bt_a2dp *a2dp, struct bt_a2dp_discover_param *param)
699715
return -EBUSY;
700716
}
701717

702-
memset(&a2dp->discover_cb_param, 0U, sizeof(a2dp->discover_cb_param));
703718
a2dp->discover_cb_param = param;
704719
a2dp->discover_param.req.func = bt_a2dp_discover_cb;
705720

subsys/bluetooth/host/classic/avdtp.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ static struct bt_avdtp_sep *avdtp_get_cmd_sep(struct net_buf *buf, uint8_t *erro
356356
return sep;
357357
}
358358

359-
static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid)
359+
static void avdtp_get_caps_cmd_internal(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid,
360+
bool get_all_caps)
360361
{
361362
int err = 0;
362363
struct net_buf *rsp_buf;
@@ -369,19 +370,22 @@ static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf
369370
err = -ENOTSUP;
370371
} else {
371372
rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_ACCEPT, BT_AVDTP_PACKET_TYPE_SINGLE,
373+
get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES :
372374
BT_AVDTP_GET_CAPABILITIES, tid);
373375
if (!rsp_buf) {
374376
return;
375377
}
376378

377-
err = session->ops->get_capabilities_ind(session, sep, rsp_buf, &error_code);
379+
err = session->ops->get_capabilities_ind(session, sep, rsp_buf, get_all_caps,
380+
&error_code);
378381
if (err) {
379382
net_buf_unref(rsp_buf);
380383
}
381384
}
382385

383386
if (err) {
384387
rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_REJECT, BT_AVDTP_PACKET_TYPE_SINGLE,
388+
get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES :
385389
BT_AVDTP_GET_CAPABILITIES, tid);
386390
if (!rsp_buf) {
387391
return;
@@ -403,6 +407,17 @@ static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf
403407
}
404408
}
405409

410+
static void avdtp_get_capabilities_cmd(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid)
411+
{
412+
avdtp_get_caps_cmd_internal(session, buf, tid, false);
413+
}
414+
415+
static void avdtp_get_all_capabilities_cmd(struct bt_avdtp *session,
416+
struct net_buf *buf, uint8_t tid)
417+
{
418+
avdtp_get_caps_cmd_internal(session, buf, tid, true);
419+
}
420+
406421
static void avdtp_get_capabilities_rsp(struct bt_avdtp *session, struct net_buf *buf,
407422
uint8_t msg_type)
408423
{
@@ -1103,19 +1118,19 @@ void bt_avdtp_l2cap_disconnected(struct bt_l2cap_chan *chan)
11031118
}
11041119

11051120
void (*cmd_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t tid) = {
1106-
avdtp_discover_cmd, /* BT_AVDTP_DISCOVER */
1107-
avdtp_get_capabilities_cmd, /* BT_AVDTP_GET_CAPABILITIES */
1108-
avdtp_set_configuration_cmd, /* BT_AVDTP_SET_CONFIGURATION */
1109-
NULL, /* BT_AVDTP_GET_CONFIGURATION */
1110-
avdtp_re_configure_cmd, /* BT_AVDTP_RECONFIGURE */
1111-
avdtp_open_cmd, /* BT_AVDTP_OPEN */
1112-
avdtp_start_cmd, /* BT_AVDTP_START */
1113-
avdtp_close_cmd, /* BT_AVDTP_CLOSE */
1114-
avdtp_suspend_cmd, /* BT_AVDTP_SUSPEND */
1115-
avdtp_abort_cmd, /* BT_AVDTP_ABORT */
1116-
NULL, /* BT_AVDTP_SECURITY_CONTROL */
1117-
NULL, /* BT_AVDTP_GET_ALL_CAPABILITIES */
1118-
NULL, /* BT_AVDTP_DELAYREPORT */
1121+
avdtp_discover_cmd, /* BT_AVDTP_DISCOVER */
1122+
avdtp_get_capabilities_cmd, /* BT_AVDTP_GET_CAPABILITIES */
1123+
avdtp_set_configuration_cmd, /* BT_AVDTP_SET_CONFIGURATION */
1124+
NULL, /* BT_AVDTP_GET_CONFIGURATION */
1125+
avdtp_re_configure_cmd, /* BT_AVDTP_RECONFIGURE */
1126+
avdtp_open_cmd, /* BT_AVDTP_OPEN */
1127+
avdtp_start_cmd, /* BT_AVDTP_START */
1128+
avdtp_close_cmd, /* BT_AVDTP_CLOSE */
1129+
avdtp_suspend_cmd, /* BT_AVDTP_SUSPEND */
1130+
avdtp_abort_cmd, /* BT_AVDTP_ABORT */
1131+
NULL, /* BT_AVDTP_SECURITY_CONTROL */
1132+
avdtp_get_all_capabilities_cmd, /* BT_AVDTP_GET_ALL_CAPABILITIES */
1133+
NULL, /* BT_AVDTP_DELAYREPORT */
11191134
};
11201135

11211136
void (*rsp_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t msg_type) = {
@@ -1130,7 +1145,7 @@ void (*rsp_handler[])(struct bt_avdtp *session, struct net_buf *buf, uint8_t msg
11301145
avdtp_suspend_rsp, /* BT_AVDTP_SUSPEND */
11311146
avdtp_abort_rsp, /* BT_AVDTP_ABORT */
11321147
NULL, /* BT_AVDTP_SECURITY_CONTROL */
1133-
NULL, /* BT_AVDTP_GET_ALL_CAPABILITIES */
1148+
avdtp_get_capabilities_rsp, /* BT_AVDTP_GET_ALL_CAPABILITIES */
11341149
NULL, /* BT_AVDTP_DELAYREPORT */
11351150
};
11361151

@@ -1436,6 +1451,7 @@ int bt_avdtp_get_capabilities(struct bt_avdtp *session,
14361451
}
14371452

14381453
buf = avdtp_create_pdu(BT_AVDTP_CMD, BT_AVDTP_PACKET_TYPE_SINGLE,
1454+
param->get_all_caps ? BT_AVDTP_GET_ALL_CAPABILITIES :
14391455
BT_AVDTP_GET_CAPABILITIES);
14401456
if (!buf) {
14411457
LOG_ERR("Error: No Buff available");

subsys/bluetooth/host/classic/avdtp_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct bt_avdtp_discover_params {
153153
struct bt_avdtp_get_capabilities_params {
154154
struct bt_avdtp_req req;
155155
uint8_t stream_endpoint_id;
156+
bool get_all_caps;
156157
};
157158

158159
struct bt_avdtp_set_configuration_params {
@@ -183,7 +184,7 @@ struct bt_avdtp_ops_cb {
183184
int (*discovery_ind)(struct bt_avdtp *session, uint8_t *errcode);
184185

185186
int (*get_capabilities_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep,
186-
struct net_buf *rsp_buf, uint8_t *errcode);
187+
struct net_buf *rsp_buf, bool get_all_caps, uint8_t *errcode);
187188

188189
int (*set_configuration_ind)(struct bt_avdtp *session, struct bt_avdtp_sep *sep,
189190
uint8_t int_seid, struct net_buf *buf, uint8_t *errcode);

subsys/bluetooth/host/classic/shell/a2dp.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static struct bt_sdp_attribute a2dp_sink_attrs[] = {
9999
},
100100
{
101101
BT_SDP_TYPE_SIZE(BT_SDP_UINT16), /* 09 */
102-
BT_SDP_ARRAY_16(0x0100U) /* AVDTP version: 01 00 */
102+
BT_SDP_ARRAY_16(AVDTP_VERSION) /* AVDTP version: 01 03 */
103103
},
104104
)
105105
},
@@ -168,7 +168,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = {
168168
},
169169
{
170170
BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
171-
BT_SDP_ARRAY_16(0x0100U)
171+
BT_SDP_ARRAY_16(AVDTP_VERSION)
172172
},
173173
)
174174
},
@@ -193,7 +193,7 @@ static struct bt_sdp_attribute a2dp_source_attrs[] = {
193193
},
194194
)
195195
),
196-
BT_SDP_SERVICE_NAME("A2DPSink"),
196+
BT_SDP_SERVICE_NAME("A2DPSource"),
197197
BT_SDP_SUPPORTED_FEATURES(0x0001U),
198198
};
199199

@@ -677,13 +677,22 @@ struct bt_a2dp_discover_param discover_param = {
677677

678678
static int cmd_get_peer_eps(const struct shell *sh, int32_t argc, char *argv[])
679679
{
680+
int err = 0;
681+
680682
if (a2dp_initied == 0) {
681683
shell_print(sh, "need to register a2dp connection callbacks");
682684
return -ENOEXEC;
683685
}
684686

685687
if (default_a2dp != NULL) {
686-
int err = bt_a2dp_discover(default_a2dp, &discover_param);
688+
discover_param.avdtp_version = (uint16_t)shell_strtoul(argv[1], 0, &err);
689+
if (err != 0) {
690+
shell_error(sh, "failed to parse avdtp version: %d", err);
691+
692+
return -ENOEXEC;
693+
}
694+
695+
err = bt_a2dp_discover(default_a2dp, &discover_param);
687696

688697
if (err) {
689698
shell_error(sh, "discover fail");
@@ -798,7 +807,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(a2dp_cmds,
798807
cmd_register_ep, 3, 0),
799808
SHELL_CMD_ARG(connect, NULL, HELP_NONE, cmd_connect, 1, 0),
800809
SHELL_CMD_ARG(disconnect, NULL, HELP_NONE, cmd_disconnect, 1, 0),
801-
SHELL_CMD_ARG(discover_peer_eps, NULL, HELP_NONE, cmd_get_peer_eps, 1, 0),
810+
SHELL_CMD_ARG(discover_peer_eps, NULL, "<avdtp version value>", cmd_get_peer_eps, 2, 0),
802811
SHELL_CMD_ARG(configure, NULL, "\"configure/enable the stream\"", cmd_configure, 1, 0),
803812
SHELL_CMD_ARG(establish, NULL, "\"establish the stream\"", cmd_establish, 1, 0),
804813
SHELL_CMD_ARG(reconfigure, NULL, "\"reconfigure the stream\"", cmd_reconfigure, 1, 0),

0 commit comments

Comments
 (0)