1 /*
2 * Audio Video Distribution Protocol
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 */
7
8 #include <zephyr/kernel.h>
9 #include <string.h>
10 #include <strings.h>
11 #include <errno.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <zephyr/sys/util.h>
15
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/l2cap.h>
19 #include <zephyr/bluetooth/classic/avdtp.h>
20
21 #include "host/hci_core.h"
22 #include "host/conn_internal.h"
23 #include "l2cap_br_internal.h"
24 #include "avdtp_internal.h"
25
26 #define LOG_LEVEL CONFIG_BT_AVDTP_LOG_LEVEL
27 #include <zephyr/logging/log.h>
28 LOG_MODULE_REGISTER(bt_avdtp);
29
30 #define AVDTP_MSG_POISTION 0x00
31 #define AVDTP_PKT_POSITION 0x02
32 #define AVDTP_TID_POSITION 0x04
33 #define AVDTP_SIGID_MASK 0x3f
34
35 #define AVDTP_GET_TR_ID(hdr) ((hdr & 0xf0) >> AVDTP_TID_POSITION)
36 #define AVDTP_GET_MSG_TYPE(hdr) (hdr & 0x03)
37 #define AVDTP_GET_PKT_TYPE(hdr) ((hdr & 0x0c) >> AVDTP_PKT_POSITION)
38 #define AVDTP_GET_SIG_ID(s) (s & AVDTP_SIGID_MASK)
39
40 static struct bt_avdtp_event_cb *event_cb;
41 static sys_slist_t seps;
42
43 #define AVDTP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_avdtp, br_chan.chan)
44
45 #define AVDTP_KWORK(_work) CONTAINER_OF(CONTAINER_OF(_work, struct k_work_delayable, work),\
46 struct bt_avdtp, timeout_work)
47
48 #define DISCOVER_REQ(_req) CONTAINER_OF(_req, struct bt_avdtp_discover_params, req)
49 #define GET_CAP_REQ(_req) CONTAINER_OF(_req, struct bt_avdtp_get_capabilities_params, req)
50 #define SET_CONF_REQ(_req) CONTAINER_OF(_req, struct bt_avdtp_set_configuration_params, req)
51 #define OPEN_REQ(_req) CONTAINER_OF(_req, struct bt_avdtp_open_params, req)
52 #define START_REQ(_req) CONTAINER_OF(_req, struct bt_avdtp_start_params, req)
53
54 #define AVDTP_TIMEOUT K_SECONDS(6)
55
56 K_MUTEX_DEFINE(avdtp_mutex);
57 #define AVDTP_LOCK() k_mutex_lock(&avdtp_mutex, K_FOREVER)
58 #define AVDTP_UNLOCK() k_mutex_unlock(&avdtp_mutex)
59
60 enum sep_state {
61 AVDTP_IDLE = 0,
62 AVDTP_CONFIGURED,
63 /* establishing the transport sessions. */
64 AVDTP_OPENING,
65 AVDTP_OPEN,
66 AVDTP_STREAMING,
67 AVDTP_CLOSING,
68 AVDTP_ABORTING,
69 };
70
71 /* L2CAP Interface callbacks */
bt_avdtp_media_l2cap_connected(struct bt_l2cap_chan * chan)72 void bt_avdtp_media_l2cap_connected(struct bt_l2cap_chan *chan)
73 {
74 struct bt_avdtp *session;
75 struct bt_avdtp_sep *sep =
76 CONTAINER_OF(chan, struct bt_avdtp_sep, chan.chan);
77
78 if (!chan) {
79 LOG_ERR("Invalid AVDTP chan");
80 return;
81 }
82
83 session = sep->session;
84 if (session == NULL) {
85 return;
86 }
87
88 LOG_DBG("chan %p session %p", chan, session);
89 sep->state = AVDTP_OPEN;
90 if (session->req != NULL) {
91 struct bt_avdtp_req *req = session->req;
92
93 OPEN_REQ(req)->status = 0;
94 AVDTP_LOCK();
95 session->req = NULL;
96 AVDTP_UNLOCK();
97 if (req->func != NULL) {
98 req->func(req);
99 }
100 }
101 }
102
bt_avdtp_media_l2cap_disconnected(struct bt_l2cap_chan * chan)103 void bt_avdtp_media_l2cap_disconnected(struct bt_l2cap_chan *chan)
104 {
105 struct bt_avdtp_sep *sep =
106 CONTAINER_OF(chan, struct bt_avdtp_sep, chan.chan);
107
108 LOG_DBG("chan %p", chan);
109 chan->conn = NULL;
110 if (sep->state > AVDTP_OPENING) {
111 sep->state = AVDTP_OPENING;
112 }
113 }
114
bt_avdtp_media_l2cap_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)115 int bt_avdtp_media_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
116 {
117 /* media data is received */
118 struct bt_avdtp_sep *sep =
119 CONTAINER_OF(chan, struct bt_avdtp_sep, chan.chan);
120
121 if (sep->media_data_cb != NULL) {
122 sep->media_data_cb(sep, buf);
123 }
124 return 0;
125 }
126
avdtp_media_connect(struct bt_avdtp * session,struct bt_avdtp_sep * sep)127 static int avdtp_media_connect(struct bt_avdtp *session, struct bt_avdtp_sep *sep)
128 {
129 static const struct bt_l2cap_chan_ops ops = {
130 .connected = bt_avdtp_media_l2cap_connected,
131 .disconnected = bt_avdtp_media_l2cap_disconnected,
132 .recv = bt_avdtp_media_l2cap_recv
133 };
134
135 if (!session) {
136 return -EINVAL;
137 }
138
139 sep->session = session;
140 sep->chan.rx.mtu = BT_L2CAP_RX_MTU;
141 sep->chan.chan.ops = &ops;
142 sep->chan.required_sec_level = BT_SECURITY_L2;
143
144 return bt_l2cap_chan_connect(session->br_chan.chan.conn, &sep->chan.chan,
145 BT_L2CAP_PSM_AVDTP);
146 }
147
avdtp_create_reply_pdu(uint8_t msg_type,uint8_t pkt_type,uint8_t sig_id,uint8_t tid)148 static struct net_buf *avdtp_create_reply_pdu(uint8_t msg_type,
149 uint8_t pkt_type,
150 uint8_t sig_id,
151 uint8_t tid)
152 {
153 struct net_buf *buf;
154 struct bt_avdtp_single_sig_hdr *hdr;
155
156 LOG_DBG("");
157
158 buf = bt_l2cap_create_pdu(NULL, 0);
159 if (!buf) {
160 LOG_ERR("Error: No Buff available");
161 return NULL;
162 }
163
164 hdr = net_buf_add(buf, sizeof(*hdr));
165
166 hdr->hdr = (msg_type | pkt_type << AVDTP_PKT_POSITION |
167 tid << AVDTP_TID_POSITION);
168 hdr->signal_id = sig_id & AVDTP_SIGID_MASK;
169
170 LOG_DBG("hdr = 0x%02X, Signal_ID = 0x%02X", hdr->hdr, hdr->signal_id);
171 return buf;
172 }
173
avdtp_discover_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)174 static void avdtp_discover_handler(struct bt_avdtp *session,
175 struct net_buf *buf, uint8_t msg_type,
176 uint8_t tid)
177 {
178 if (msg_type == BT_AVDTP_CMD) {
179 int err;
180 struct bt_avdtp_sep *sep;
181 struct net_buf *rsp_buf;
182 uint8_t error_code = 0;
183
184 if (session->ops->discovery_ind == NULL) {
185 err = -ENOTSUP;
186 } else {
187 err = session->ops->discovery_ind(session, &error_code);
188 }
189
190 rsp_buf = avdtp_create_reply_pdu(err ?
191 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
192 BT_AVDTP_PACKET_TYPE_SINGLE,
193 BT_AVDTP_DISCOVER, tid);
194 if (!rsp_buf) {
195 return;
196 }
197
198 if (err) {
199 if (error_code == 0) {
200 error_code = BT_AVDTP_BAD_STATE;
201 }
202 LOG_DBG("discover err code:%d", error_code);
203 net_buf_add_u8(rsp_buf, error_code);
204 } else {
205 struct bt_avdtp_sep_data sep_data;
206
207 SYS_SLIST_FOR_EACH_CONTAINER(&seps, sep, _node) {
208 memset(&sep_data, 0, sizeof(sep_data));
209 sep_data.inuse = sep->sep_info.inuse;
210 sep_data.id = sep->sep_info.id;
211 sep_data.tsep = sep->sep_info.tsep;
212 sep_data.media_type = sep->sep_info.media_type;
213 net_buf_add_mem(rsp_buf, &sep_data, sizeof(sep_data));
214 }
215 }
216
217 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
218 if (err < 0) {
219 net_buf_unref(rsp_buf);
220 LOG_ERR("Error:L2CAP send fail - result = %d", err);
221 return;
222 }
223 } else {
224 struct bt_avdtp_req *req = session->req;
225
226 if (session->req == NULL) {
227 return;
228 }
229 k_work_cancel_delayable(&session->timeout_work);
230 if (msg_type == BT_AVDTP_ACCEPT) {
231 DISCOVER_REQ(session->req)->status = 0;
232 DISCOVER_REQ(session->req)->buf = buf;
233 } else if (msg_type == BT_AVDTP_REJECT) {
234 DISCOVER_REQ(session->req)->status = net_buf_pull_u8(buf);
235 } else if (msg_type == BT_AVDTP_GEN_REJECT) {
236 DISCOVER_REQ(session->req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
237 }
238 AVDTP_LOCK();
239 session->req = NULL;
240 AVDTP_UNLOCK();
241 if (req->func != NULL) {
242 req->func(req);
243 }
244 }
245 }
246
avdtp_get_sep(uint8_t stream_endpoint_id)247 static struct bt_avdtp_sep *avdtp_get_sep(uint8_t stream_endpoint_id)
248 {
249 struct bt_avdtp_sep *sep = NULL;
250
251 SYS_SLIST_FOR_EACH_CONTAINER(&seps, sep, _node) {
252 if (sep->sep_info.id == stream_endpoint_id) {
253 break;
254 }
255 }
256
257 return sep;
258 }
259
avdtp_get_capabilities_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)260 static void avdtp_get_capabilities_handler(struct bt_avdtp *session,
261 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
262 {
263 if (msg_type == BT_AVDTP_CMD) {
264 int err = 0;
265 struct net_buf *rsp_buf;
266 struct bt_avdtp_sep *sep;
267 uint8_t error_code = 0;
268
269 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
270 if ((sep == NULL) || (session->ops->get_capabilities_ind == NULL)) {
271 err = -ENOTSUP;
272 } else {
273 rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_ACCEPT,
274 BT_AVDTP_PACKET_TYPE_SINGLE,
275 BT_AVDTP_GET_CAPABILITIES,
276 tid);
277 if (!rsp_buf) {
278 return;
279 }
280 err = session->ops->get_capabilities_ind(session,
281 sep, rsp_buf, &error_code);
282 if (err) {
283 net_buf_unref(rsp_buf);
284 }
285 }
286
287 if (err) {
288 rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_REJECT,
289 BT_AVDTP_PACKET_TYPE_SINGLE,
290 BT_AVDTP_GET_CAPABILITIES, tid);
291 if (!rsp_buf) {
292 return;
293 }
294
295 if (error_code == 0) {
296 error_code = BT_AVDTP_BAD_ACP_SEID;
297 }
298 LOG_DBG("get cap err code:%d", error_code);
299 net_buf_add_u8(rsp_buf, error_code);
300 }
301
302 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
303 if (err < 0) {
304 net_buf_unref(rsp_buf);
305 LOG_ERR("Error:L2CAP send fail - result = %d", err);
306 return;
307 }
308 } else {
309 struct bt_avdtp_req *req = session->req;
310
311 if (session->req == NULL) {
312 return;
313 }
314 k_work_cancel_delayable(&session->timeout_work);
315 GET_CAP_REQ(session->req)->buf = NULL;
316
317 if (msg_type == BT_AVDTP_ACCEPT) {
318 GET_CAP_REQ(session->req)->status = 0;
319 if (session->req != NULL) {
320 GET_CAP_REQ(session->req)->buf = buf;
321 }
322 } else if (msg_type == BT_AVDTP_REJECT) {
323 GET_CAP_REQ(session->req)->status = net_buf_pull_u8(buf);
324 } else if (msg_type == BT_AVDTP_GEN_REJECT) {
325 GET_CAP_REQ(session->req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
326 }
327 AVDTP_LOCK();
328 session->req = NULL;
329 AVDTP_UNLOCK();
330 if (req->func != NULL) {
331 req->func(req);
332 }
333 }
334 }
335
avdtp_process_configuration(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)336 static void avdtp_process_configuration(struct bt_avdtp *session,
337 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
338 {
339 if (msg_type == BT_AVDTP_CMD) {
340 int err = 0;
341 struct bt_avdtp_sep *sep;
342 struct net_buf *rsp_buf;
343 uint8_t error_code = 0;
344
345 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
346 if ((sep == NULL) || (session->ops->set_configuration_ind == NULL)) {
347 err = -ENOTSUP;
348 } else {
349 if (sep->state == AVDTP_STREAMING) {
350 err = -ENOTSUP;
351 error_code = BT_AVDTP_BAD_STATE;
352 } else {
353 uint8_t int_seid;
354
355 /* INT Stream Endpoint ID */
356 int_seid = net_buf_pull_u8(buf);
357 err = session->ops->set_configuration_ind(session,
358 sep, int_seid, buf, &error_code);
359 }
360 }
361
362 rsp_buf = avdtp_create_reply_pdu(err ?
363 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
364 BT_AVDTP_PACKET_TYPE_SINGLE,
365 BT_AVDTP_SET_CONFIGURATION, tid);
366 if (!rsp_buf) {
367 return;
368 }
369
370 if (err) {
371 if (error_code == 0) {
372 error_code = BT_AVDTP_BAD_ACP_SEID;
373 }
374 LOG_DBG("set configuration err code:%d", error_code);
375 /* Service Category: Media Codec */
376 net_buf_add_u8(rsp_buf, BT_AVDTP_SERVICE_MEDIA_CODEC);
377 /* Length Of Service Capability */
378 net_buf_add_u8(rsp_buf, 0);
379 /* ERROR CODE */
380 net_buf_add_u8(rsp_buf, error_code);
381 } else {
382 sep->state = AVDTP_CONFIGURED;
383 }
384
385 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
386 if (err < 0) {
387 net_buf_unref(rsp_buf);
388 LOG_ERR("Error:L2CAP send fail - result = %d", err);
389 return;
390 }
391 } else {
392 struct bt_avdtp_req *req = session->req;
393
394 if (session->req == NULL) {
395 return;
396 }
397 k_work_cancel_delayable(&session->timeout_work);
398 if (msg_type == BT_AVDTP_ACCEPT) {
399 SET_CONF_REQ(req)->status = 0;
400 SET_CONF_REQ(req)->sep->state = AVDTP_CONFIGURED;
401 } else if (msg_type == BT_AVDTP_REJECT) {
402 /* Service Category */
403 net_buf_pull_u8(buf);
404 SET_CONF_REQ(req)->status = net_buf_pull_u8(buf);
405 } else if (msg_type == BT_AVDTP_GEN_REJECT) {
406 SET_CONF_REQ(req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
407 }
408 AVDTP_LOCK();
409 session->req = NULL;
410 AVDTP_UNLOCK();
411 if (req->func != NULL) {
412 req->func(req);
413 }
414 }
415 }
416
avdtp_set_configuration_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)417 static void avdtp_set_configuration_handler(struct bt_avdtp *session,
418 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
419 {
420 avdtp_process_configuration(session, buf, msg_type, tid);
421 }
422
avdtp_get_configuration_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)423 static void avdtp_get_configuration_handler(struct bt_avdtp *session,
424 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
425 {
426 /* todo: is not supported now, reply reject */
427 struct net_buf *rsp_buf;
428 int err;
429
430 rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_REJECT,
431 BT_AVDTP_PACKET_TYPE_SINGLE,
432 BT_AVDTP_GET_CONFIGURATION, tid);
433 if (!rsp_buf) {
434 LOG_ERR("Error: No Buff available");
435 return;
436 }
437
438 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
439 if (err < 0) {
440 net_buf_unref(rsp_buf);
441 LOG_ERR("Error:L2CAP send fail - result = %d", err);
442 return;
443 }
444 }
445
avdtp_re_configure_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)446 static void avdtp_re_configure_handler(struct bt_avdtp *session,
447 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
448 {
449 avdtp_process_configuration(session, buf, msg_type, tid);
450 }
451
avdtp_open_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)452 static void avdtp_open_handler(struct bt_avdtp *session,
453 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
454 {
455 if (msg_type == BT_AVDTP_CMD) {
456 int err = 0;
457 struct bt_avdtp_sep *sep;
458 struct net_buf *rsp_buf;
459 uint8_t error_code = 0;
460
461 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
462 if ((sep == NULL) || (session->ops->open_ind == NULL)) {
463 err = -ENOTSUP;
464 } else {
465 if (sep->state != AVDTP_CONFIGURED) {
466 err = -ENOTSUP;
467 error_code = BT_AVDTP_BAD_STATE;
468 } else {
469 err = session->ops->open_ind(session, sep, &error_code);
470 }
471 }
472
473 rsp_buf = avdtp_create_reply_pdu(err ?
474 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
475 BT_AVDTP_PACKET_TYPE_SINGLE,
476 BT_AVDTP_OPEN, tid);
477 if (!rsp_buf) {
478 return;
479 }
480
481 if (err) {
482 if (error_code == 0) {
483 error_code = BT_AVDTP_BAD_ACP_SEID;
484 }
485 LOG_DBG("open_ind err code:%d", error_code);
486 net_buf_add_u8(rsp_buf, error_code);
487 } else {
488 session->current_sep = sep;
489 sep->state = AVDTP_OPENING;
490 sep->sep_info.inuse = 1u;
491 }
492
493 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
494 if (err < 0) {
495 net_buf_unref(rsp_buf);
496 LOG_ERR("Error:L2CAP send fail - result = %d", err);
497 return;
498 }
499 } else {
500 struct bt_avdtp_req *req = session->req;
501
502 if (session->req == NULL) {
503 return;
504 }
505 k_work_cancel_delayable(&session->timeout_work);
506 if (msg_type == BT_AVDTP_ACCEPT) {
507 OPEN_REQ(req)->status = 0;
508 OPEN_REQ(req)->sep->state = AVDTP_OPENING;
509 if (!avdtp_media_connect(session, OPEN_REQ(req)->sep)) {
510 return;
511 }
512 } else if (msg_type == BT_AVDTP_REJECT) {
513 OPEN_REQ(req)->status = net_buf_pull_u8(buf);
514 } else if (msg_type == BT_AVDTP_GEN_REJECT) {
515 OPEN_REQ(req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
516 }
517 if (OPEN_REQ(req)->status) {
518 /* wait the media l2cap is established */
519 AVDTP_LOCK();
520 session->req = NULL;
521 AVDTP_UNLOCK();
522 if (req->func != NULL) {
523 req->func(req);
524 }
525 }
526 }
527 }
528
avdtp_start_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)529 static void avdtp_start_handler(struct bt_avdtp *session,
530 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
531 {
532 if (msg_type == BT_AVDTP_CMD) {
533 int err = 0;
534 struct bt_avdtp_sep *sep;
535 struct net_buf *rsp_buf;
536 uint8_t error_code = 0;
537
538 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
539 if ((sep == NULL) || (session->ops->start_ind == NULL)) {
540 err = -ENOTSUP;
541 } else {
542 if (sep->state != AVDTP_OPEN) {
543 err = -ENOTSUP;
544 error_code = BT_AVDTP_BAD_STATE;
545 } else {
546 err = session->ops->start_ind(session, sep, &error_code);
547 }
548 }
549
550 rsp_buf = avdtp_create_reply_pdu(err ?
551 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
552 BT_AVDTP_PACKET_TYPE_SINGLE,
553 BT_AVDTP_START, tid);
554 if (!rsp_buf) {
555 return;
556 }
557
558 if (err) {
559 if (error_code == 0) {
560 error_code = BT_AVDTP_BAD_ACP_SEID;
561 }
562 LOG_DBG("start err code:%d", error_code);
563 net_buf_add_u8(rsp_buf, error_code);
564 } else {
565 sep->state = AVDTP_STREAMING;
566 }
567
568 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
569 if (err < 0) {
570 net_buf_unref(rsp_buf);
571 LOG_ERR("Error:L2CAP send fail - result = %d", err);
572 return;
573 }
574 } else {
575 struct bt_avdtp_req *req = session->req;
576
577 if (session->req == NULL) {
578 return;
579 }
580 k_work_cancel_delayable(&session->timeout_work);
581 if (msg_type == BT_AVDTP_ACCEPT) {
582 START_REQ(req)->status = 0;
583 START_REQ(req)->sep->state = AVDTP_STREAMING;
584 } else if (msg_type == BT_AVDTP_REJECT) {
585 uint8_t acp_seid;
586
587 acp_seid = net_buf_pull_u8(buf);
588 if (acp_seid != START_REQ(req)->acp_stream_ep_id) {
589 return;
590 }
591
592 START_REQ(req)->status = net_buf_pull_u8(buf);
593 } else if (msg_type == BT_AVDTP_GEN_REJECT) {
594 START_REQ(req)->status = BT_AVDTP_NOT_SUPPORTED_COMMAND;
595 }
596 AVDTP_LOCK();
597 session->req = NULL;
598 AVDTP_UNLOCK();
599 if (req->func != NULL) {
600 req->func(req);
601 }
602 }
603 }
604
avdtp_close_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)605 static void avdtp_close_handler(struct bt_avdtp *session,
606 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
607 {
608 if (msg_type == BT_AVDTP_CMD) {
609 int err = 0;
610 struct bt_avdtp_sep *sep;
611 struct net_buf *rsp_buf;
612 uint8_t error_code = 0;
613
614 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
615 if ((sep == NULL) || (session->ops->close_ind == NULL)) {
616 err = -ENOTSUP;
617 } else {
618 if (sep->state != AVDTP_OPEN) {
619 err = -ENOTSUP;
620 error_code = BT_AVDTP_BAD_STATE;
621 } else {
622 err = session->ops->close_ind(session, sep, &error_code);
623 }
624 }
625
626 rsp_buf = avdtp_create_reply_pdu(err ?
627 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
628 BT_AVDTP_PACKET_TYPE_SINGLE,
629 BT_AVDTP_CLOSE, tid);
630 if (!rsp_buf) {
631 return;
632 }
633
634 if (err) {
635 if (error_code == 0) {
636 error_code = BT_AVDTP_BAD_ACP_SEID;
637 }
638 LOG_DBG("close err code:%d", error_code);
639 net_buf_add_u8(rsp_buf, error_code);
640 } else {
641 sep->state = AVDTP_CONFIGURED;
642 sep->sep_info.inuse = 0u;
643 }
644
645 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
646 if (err < 0) {
647 net_buf_unref(rsp_buf);
648 LOG_ERR("Error:L2CAP send fail - result = %d", err);
649 return;
650 }
651 }
652 }
653
avdtp_suspend_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)654 static void avdtp_suspend_handler(struct bt_avdtp *session,
655 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
656 {
657 if (msg_type == BT_AVDTP_CMD) {
658 int err = 0;
659 struct bt_avdtp_sep *sep;
660 struct net_buf *rsp_buf;
661 uint8_t error_code = 0;
662
663 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
664 if ((sep == NULL) || (session->ops->suspend_ind == NULL)) {
665 err = -ENOTSUP;
666 } else {
667 if (sep->state != AVDTP_STREAMING) {
668 err = -ENOTSUP;
669 error_code = BT_AVDTP_BAD_STATE;
670 } else {
671 err = session->ops->suspend_ind(session, sep, &error_code);
672 }
673 }
674
675 rsp_buf = avdtp_create_reply_pdu(err ?
676 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
677 BT_AVDTP_PACKET_TYPE_SINGLE,
678 BT_AVDTP_SUSPEND, tid);
679 if (!rsp_buf) {
680 return;
681 }
682
683 if (err) {
684 if (error_code == 0) {
685 error_code = BT_AVDTP_BAD_ACP_SEID;
686 }
687 LOG_DBG("suspend err code:%d", error_code);
688 net_buf_add_u8(rsp_buf, error_code);
689 } else {
690 sep->state = AVDTP_OPEN;
691 }
692
693 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
694 if (err < 0) {
695 net_buf_unref(rsp_buf);
696 LOG_ERR("Error:L2CAP send fail - result = %d", err);
697 return;
698 }
699 }
700 }
701
avdtp_abort_handler(struct bt_avdtp * session,struct net_buf * buf,uint8_t msg_type,uint8_t tid)702 static void avdtp_abort_handler(struct bt_avdtp *session,
703 struct net_buf *buf, uint8_t msg_type, uint8_t tid)
704 {
705 if (msg_type == BT_AVDTP_CMD) {
706 int err = 0;
707 struct bt_avdtp_sep *sep;
708 struct net_buf *rsp_buf;
709 uint8_t error_code = 0;
710
711 sep = avdtp_get_sep(net_buf_pull_u8(buf) >> 2);
712 if ((sep == NULL) || (session->ops->abort_ind == NULL)) {
713 err = -ENOTSUP;
714 } else {
715 err = session->ops->abort_ind(session, sep, &error_code);
716 }
717
718 rsp_buf = avdtp_create_reply_pdu(err ?
719 BT_AVDTP_REJECT : BT_AVDTP_ACCEPT,
720 BT_AVDTP_PACKET_TYPE_SINGLE,
721 BT_AVDTP_ABORT, tid);
722 if (!rsp_buf) {
723 return;
724 }
725
726 if (err) {
727 if (error_code == 0) {
728 error_code = BT_AVDTP_BAD_ACP_SEID;
729 }
730 LOG_DBG("abort err code:%d", error_code);
731 net_buf_add_u8(rsp_buf, error_code);
732 } else {
733 sep->state = AVDTP_IDLE;
734 }
735
736 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
737 if (err < 0) {
738 net_buf_unref(rsp_buf);
739 LOG_ERR("Error:L2CAP send fail - result = %d", err);
740 return;
741 }
742 }
743 }
744
745 /* Timeout handler */
avdtp_timeout(struct k_work * work)746 static void avdtp_timeout(struct k_work *work)
747 {
748 struct bt_avdtp_req *req = (AVDTP_KWORK(work))->req;
749
750 /* add process code */
751 /* Gracefully Disconnect the Signalling and streaming L2cap chann*/
752 if (req) {
753 LOG_DBG("Failed Signal_id = %d", req->sig);
754
755 switch (req->sig) {
756 case BT_AVDTP_DISCOVER:
757 DISCOVER_REQ(req)->status = BT_AVDTP_TIME_OUT;
758 req->func(req);
759 break;
760 case BT_AVDTP_GET_CAPABILITIES:
761 GET_CAP_REQ(req)->status = BT_AVDTP_TIME_OUT;
762 req->func(req);
763 break;
764 case BT_AVDTP_SET_CONFIGURATION:
765 SET_CONF_REQ(req)->status = BT_AVDTP_TIME_OUT;
766 req->func(req);
767 break;
768 case BT_AVDTP_OPEN:
769 OPEN_REQ(req)->status = BT_AVDTP_TIME_OUT;
770 req->func(req);
771 break;
772 case BT_AVDTP_START:
773 START_REQ(req)->status = BT_AVDTP_TIME_OUT;
774 req->func(req);
775 break;
776 default:
777 break;
778 }
779
780 AVDTP_KWORK(work)->req = NULL;
781 }
782 }
783
avdtp_send(struct bt_avdtp * session,struct net_buf * buf,struct bt_avdtp_req * req)784 static int avdtp_send(struct bt_avdtp *session,
785 struct net_buf *buf, struct bt_avdtp_req *req)
786 {
787 int result;
788 struct bt_avdtp_single_sig_hdr *hdr;
789
790 AVDTP_LOCK();
791 if (session->req != NULL) {
792 AVDTP_UNLOCK();
793 return -EBUSY;
794 }
795 session->req = req;
796 AVDTP_UNLOCK();
797 hdr = (struct bt_avdtp_single_sig_hdr *)buf->data;
798
799 result = bt_l2cap_chan_send(&session->br_chan.chan, buf);
800 if (result < 0) {
801 LOG_ERR("Error:L2CAP send fail - result = %d", result);
802 net_buf_unref(buf);
803 AVDTP_LOCK();
804 session->req = NULL;
805 AVDTP_UNLOCK();
806 return result;
807 }
808
809 /*Save the sent request*/
810 req->sig = AVDTP_GET_SIG_ID(hdr->signal_id);
811 req->tid = AVDTP_GET_TR_ID(hdr->hdr);
812 LOG_DBG("sig 0x%02X, tid 0x%02X", req->sig, req->tid);
813
814 /* Init the timer */
815 k_work_init_delayable(&session->timeout_work, avdtp_timeout);
816 /* Start timeout work */
817 k_work_reschedule(&session->timeout_work, AVDTP_TIMEOUT);
818 return result;
819 }
820
avdtp_create_pdu(uint8_t msg_type,uint8_t pkt_type,uint8_t sig_id)821 static struct net_buf *avdtp_create_pdu(uint8_t msg_type,
822 uint8_t pkt_type,
823 uint8_t sig_id)
824 {
825 struct net_buf *buf;
826 static uint8_t tid;
827 struct bt_avdtp_single_sig_hdr *hdr;
828
829 LOG_DBG("");
830
831 buf = bt_l2cap_create_pdu(NULL, 0);
832
833 hdr = net_buf_add(buf, sizeof(*hdr));
834
835 hdr->hdr = (msg_type | pkt_type << AVDTP_PKT_POSITION |
836 tid++ << AVDTP_TID_POSITION);
837 tid %= 16; /* Loop for 16*/
838 hdr->signal_id = sig_id & AVDTP_SIGID_MASK;
839
840 LOG_DBG("hdr = 0x%02X, Signal_ID = 0x%02X", hdr->hdr, hdr->signal_id);
841 return buf;
842 }
843
844 /* L2CAP Interface callbacks */
bt_avdtp_l2cap_connected(struct bt_l2cap_chan * chan)845 void bt_avdtp_l2cap_connected(struct bt_l2cap_chan *chan)
846 {
847 struct bt_avdtp *session;
848
849 if (!chan) {
850 LOG_ERR("Invalid AVDTP chan");
851 return;
852 }
853
854 session = AVDTP_CHAN(chan);
855 LOG_DBG("chan %p session %p", chan, session);
856
857 /* notify a2dp connection result */
858 session->ops->connected(session);
859 }
860
bt_avdtp_l2cap_disconnected(struct bt_l2cap_chan * chan)861 void bt_avdtp_l2cap_disconnected(struct bt_l2cap_chan *chan)
862 {
863 struct bt_avdtp *session = AVDTP_CHAN(chan);
864
865 LOG_DBG("chan %p session %p", chan, session);
866 session->br_chan.chan.conn = NULL;
867 session->signalling_l2cap_connected = 0;
868 /* todo: Clear the Pending req if set*/
869
870 /* notify a2dp disconnect */
871 session->ops->disconnected(session);
872 }
873
bt_avdtp_l2cap_encrypt_changed(struct bt_l2cap_chan * chan,uint8_t status)874 void bt_avdtp_l2cap_encrypt_changed(struct bt_l2cap_chan *chan, uint8_t status)
875 {
876 LOG_DBG("");
877 }
878
879 static const struct {
880 uint8_t sig_id;
881 void (*func)(struct bt_avdtp *session, struct net_buf *buf,
882 uint8_t msg_type, uint8_t tid);
883 } handler[] = {
884 {BT_AVDTP_DISCOVER, avdtp_discover_handler},
885 {BT_AVDTP_GET_CAPABILITIES, avdtp_get_capabilities_handler},
886 {BT_AVDTP_SET_CONFIGURATION, avdtp_set_configuration_handler},
887 {BT_AVDTP_GET_CONFIGURATION, avdtp_get_configuration_handler},
888 {BT_AVDTP_RECONFIGURE, avdtp_re_configure_handler},
889 {BT_AVDTP_OPEN, avdtp_open_handler},
890 {BT_AVDTP_START, avdtp_start_handler},
891 {BT_AVDTP_CLOSE, avdtp_close_handler},
892 {BT_AVDTP_SUSPEND, avdtp_suspend_handler},
893 {BT_AVDTP_ABORT, avdtp_abort_handler},
894 };
895
bt_avdtp_l2cap_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)896 int bt_avdtp_l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
897 {
898 struct bt_avdtp_single_sig_hdr *hdr;
899 struct bt_avdtp *session = AVDTP_CHAN(chan);
900 uint8_t i, msgtype, pack_type, sigid, tid;
901
902 if (buf->len < sizeof(*hdr)) {
903 LOG_ERR("Recvd Wrong AVDTP Header");
904 return 0;
905 }
906
907 hdr = net_buf_pull_mem(buf, sizeof(*hdr));
908 pack_type = AVDTP_GET_PKT_TYPE(hdr->hdr);
909 msgtype = AVDTP_GET_MSG_TYPE(hdr->hdr);
910 sigid = AVDTP_GET_SIG_ID(hdr->signal_id);
911 tid = AVDTP_GET_TR_ID(hdr->hdr);
912
913 LOG_DBG("pack_type[0x%02x] msg_type[0x%02x] sig_id[0x%02x] tid[0x%02x]",
914 pack_type, msgtype, sigid, tid);
915
916 /* TODO: only support single packet now */
917 if (pack_type != BT_AVDTP_PACKET_TYPE_SINGLE) {
918 if (pack_type == BT_AVDTP_PACKET_TYPE_START) {
919 struct net_buf *rsp_buf;
920 int err;
921
922 sigid = net_buf_pull_u8(buf);
923 rsp_buf = avdtp_create_reply_pdu(BT_AVDTP_REJECT,
924 BT_AVDTP_PACKET_TYPE_SINGLE,
925 sigid, tid);
926 if (!rsp_buf) {
927 LOG_ERR("Error: No Buff available");
928 return 0;
929 }
930 err = bt_l2cap_chan_send(&session->br_chan.chan, rsp_buf);
931 if (err < 0) {
932 net_buf_unref(rsp_buf);
933 LOG_ERR("Error:L2CAP send fail - result = %d", err);
934 }
935 }
936 return 0;
937 }
938
939 /* validate if there is an outstanding resp expected*/
940 if (msgtype != BT_AVDTP_CMD) {
941 if (session->req == NULL) {
942 LOG_DBG("Unexpected peer response");
943 return 0;
944 }
945
946 if (session->req->sig != sigid ||
947 session->req->tid != tid) {
948 LOG_DBG("Peer mismatch resp, expected sig[0x%02x]"
949 "tid[0x%02x]", session->req->sig,
950 session->req->tid);
951 return 0;
952 }
953 }
954
955 if (!session) {
956 LOG_DBG("Error: Session not valid");
957 return 0;
958 }
959
960 for (i = 0U; i < ARRAY_SIZE(handler); i++) {
961 if (sigid == handler[i].sig_id) {
962 handler[i].func(session, buf, msgtype, tid);
963 return 0;
964 }
965 }
966
967 return 0;
968 }
969
970 /*A2DP Layer interface */
bt_avdtp_connect(struct bt_conn * conn,struct bt_avdtp * session)971 int bt_avdtp_connect(struct bt_conn *conn, struct bt_avdtp *session)
972 {
973 static const struct bt_l2cap_chan_ops ops = {
974 .connected = bt_avdtp_l2cap_connected,
975 .disconnected = bt_avdtp_l2cap_disconnected,
976 .encrypt_change = bt_avdtp_l2cap_encrypt_changed,
977 .recv = bt_avdtp_l2cap_recv
978 };
979
980 if (!session) {
981 return -EINVAL;
982 }
983
984 session->signalling_l2cap_connected = 1;
985 session->br_chan.rx.mtu = BT_L2CAP_RX_MTU;
986 session->br_chan.chan.ops = &ops;
987 session->br_chan.required_sec_level = BT_SECURITY_L2;
988
989 return bt_l2cap_chan_connect(conn, &session->br_chan.chan,
990 BT_L2CAP_PSM_AVDTP);
991 }
992
bt_avdtp_disconnect(struct bt_avdtp * session)993 int bt_avdtp_disconnect(struct bt_avdtp *session)
994 {
995 if (!session) {
996 return -EINVAL;
997 }
998
999 LOG_DBG("session %p", session);
1000
1001 session->signalling_l2cap_connected = 0;
1002 return bt_l2cap_chan_disconnect(&session->br_chan.chan);
1003 }
1004
bt_avdtp_l2cap_accept(struct bt_conn * conn,struct bt_l2cap_server * server,struct bt_l2cap_chan ** chan)1005 int bt_avdtp_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
1006 struct bt_l2cap_chan **chan)
1007 {
1008 struct bt_avdtp *session = NULL;
1009 int result;
1010
1011 LOG_DBG("conn %p", conn);
1012 /* Get the AVDTP session from upper layer */
1013 result = event_cb->accept(conn, &session);
1014 if (result < 0) {
1015 return result;
1016 }
1017
1018 if (session->signalling_l2cap_connected == 0) {
1019 static const struct bt_l2cap_chan_ops ops = {
1020 .connected = bt_avdtp_l2cap_connected,
1021 .disconnected = bt_avdtp_l2cap_disconnected,
1022 .recv = bt_avdtp_l2cap_recv,
1023 };
1024 session->signalling_l2cap_connected = 1;
1025 session->br_chan.chan.ops = &ops;
1026 session->br_chan.rx.mtu = BT_L2CAP_RX_MTU;
1027 *chan = &session->br_chan.chan;
1028 } else {
1029 /* get the current opening endpoint */
1030 if (session->current_sep != NULL) {
1031 static const struct bt_l2cap_chan_ops ops = {
1032 .connected = bt_avdtp_media_l2cap_connected,
1033 .disconnected = bt_avdtp_media_l2cap_disconnected,
1034 .recv = bt_avdtp_media_l2cap_recv
1035 };
1036 session->current_sep->session = session;
1037 session->current_sep->chan.chan.ops = &ops;
1038 session->current_sep->chan.rx.mtu = BT_L2CAP_RX_MTU;
1039 session->current_sep->chan.required_sec_level =
1040 BT_SECURITY_L2;
1041 *chan = &session->current_sep->chan.chan;
1042 session->current_sep = NULL;
1043 }
1044 }
1045
1046 return 0;
1047 }
1048
1049 /* Application will register its callback */
bt_avdtp_register(struct bt_avdtp_event_cb * cb)1050 int bt_avdtp_register(struct bt_avdtp_event_cb *cb)
1051 {
1052 LOG_DBG("");
1053
1054 if (event_cb) {
1055 return -EALREADY;
1056 }
1057
1058 event_cb = cb;
1059
1060 return 0;
1061 }
1062
bt_avdtp_register_sep(uint8_t media_type,uint8_t role,struct bt_avdtp_sep * sep)1063 int bt_avdtp_register_sep(uint8_t media_type, uint8_t role,
1064 struct bt_avdtp_sep *sep)
1065 {
1066 LOG_DBG("");
1067
1068 static uint8_t bt_avdtp_sep = BT_AVDTP_MIN_SEID;
1069
1070 if (!sep) {
1071 return -EIO;
1072 }
1073
1074 if (bt_avdtp_sep == BT_AVDTP_MAX_SEID) {
1075 return -EIO;
1076 }
1077
1078 sep->sep_info.id = bt_avdtp_sep++;
1079 sep->sep_info.inuse = 0U;
1080 sep->sep_info.media_type = media_type;
1081 sep->sep_info.tsep = role;
1082 sep->state = AVDTP_IDLE;
1083
1084 sys_slist_append(&seps, &sep->_node);
1085
1086 return 0;
1087 }
1088
1089 /* init function */
bt_avdtp_init(void)1090 int bt_avdtp_init(void)
1091 {
1092 int err;
1093 static struct bt_l2cap_server avdtp_l2cap = {
1094 .psm = BT_L2CAP_PSM_AVDTP,
1095 .sec_level = BT_SECURITY_L2,
1096 .accept = bt_avdtp_l2cap_accept,
1097 };
1098
1099 LOG_DBG("");
1100
1101 /* Register AVDTP PSM with L2CAP */
1102 err = bt_l2cap_br_server_register(&avdtp_l2cap);
1103 if (err < 0) {
1104 LOG_ERR("AVDTP L2CAP Registration failed %d", err);
1105 }
1106
1107 return err;
1108 }
1109
1110 /* AVDTP Discover Request */
bt_avdtp_discover(struct bt_avdtp * session,struct bt_avdtp_discover_params * param)1111 int bt_avdtp_discover(struct bt_avdtp *session,
1112 struct bt_avdtp_discover_params *param)
1113 {
1114 struct net_buf *buf;
1115
1116 LOG_DBG("");
1117 if (!param || !session) {
1118 LOG_DBG("Error: Callback/Session not valid");
1119 return -EINVAL;
1120 }
1121
1122 buf = avdtp_create_pdu(BT_AVDTP_CMD,
1123 BT_AVDTP_PACKET_TYPE_SINGLE,
1124 BT_AVDTP_DISCOVER);
1125 if (!buf) {
1126 LOG_ERR("Error: No Buff available");
1127 return -ENOMEM;
1128 }
1129
1130 return avdtp_send(session, buf, ¶m->req);
1131 }
1132
bt_avdtp_parse_sep(struct net_buf * buf,struct bt_avdtp_sep_info * sep_info)1133 int bt_avdtp_parse_sep(struct net_buf *buf, struct bt_avdtp_sep_info *sep_info)
1134 {
1135 struct bt_avdtp_sep_data *sep_data;
1136
1137 if ((sep_info != NULL) && (buf != NULL)) {
1138 if (buf->len >= sizeof(*sep_data)) {
1139 sep_data = net_buf_pull_mem(buf, sizeof(*sep_data));
1140 sep_info->inuse = sep_data->inuse;
1141 sep_info->id = sep_data->id;
1142 sep_info->tsep = sep_data->tsep;
1143 sep_info->media_type = sep_data->media_type;
1144 return 0;
1145 }
1146 }
1147
1148 return -EINVAL;
1149 }
1150
1151 /* AVDTP Get Capabilities Request */
bt_avdtp_get_capabilities(struct bt_avdtp * session,struct bt_avdtp_get_capabilities_params * param)1152 int bt_avdtp_get_capabilities(struct bt_avdtp *session,
1153 struct bt_avdtp_get_capabilities_params *param)
1154 {
1155 struct net_buf *buf;
1156
1157 LOG_DBG("");
1158 if (!param || !session) {
1159 LOG_DBG("Error: Callback/Session not valid");
1160 return -EINVAL;
1161 }
1162
1163 buf = avdtp_create_pdu(BT_AVDTP_CMD,
1164 BT_AVDTP_PACKET_TYPE_SINGLE,
1165 BT_AVDTP_GET_CAPABILITIES);
1166 if (!buf) {
1167 LOG_ERR("Error: No Buff available");
1168 return -ENOMEM;
1169 }
1170
1171 /* Body of the message */
1172 net_buf_add_u8(buf, (param->stream_endpoint_id << 2u));
1173
1174 return avdtp_send(session, buf, ¶m->req);
1175 }
1176
bt_avdtp_parse_capability_codec(struct net_buf * buf,uint8_t * codec_type,uint8_t ** codec_info_element,uint16_t * codec_info_element_len)1177 int bt_avdtp_parse_capability_codec(struct net_buf *buf,
1178 uint8_t *codec_type, uint8_t **codec_info_element,
1179 uint16_t *codec_info_element_len)
1180 {
1181 uint8_t data;
1182 uint8_t length;
1183
1184 if (!buf) {
1185 LOG_DBG("Error: buf not valid");
1186 return -EINVAL;
1187 }
1188
1189 while (buf->len) {
1190 data = net_buf_pull_u8(buf);
1191 switch (data) {
1192 case BT_AVDTP_SERVICE_MEDIA_TRANSPORT:
1193 case BT_AVDTP_SERVICE_REPORTING:
1194 case BT_AVDTP_SERVICE_MEDIA_RECOVERY:
1195 case BT_AVDTP_SERVICE_CONTENT_PROTECTION:
1196 case BT_AVDTP_SERVICE_HEADER_COMPRESSION:
1197 case BT_AVDTP_SERVICE_MULTIPLEXING:
1198 case BT_AVDTP_SERVICE_DELAY_REPORTING:
1199 length = net_buf_pull_u8(buf);
1200 if (length > 0) {
1201 net_buf_pull_mem(buf, length);
1202 }
1203 break;
1204
1205 case BT_AVDTP_SERVICE_MEDIA_CODEC:
1206 length = net_buf_pull_u8(buf);
1207 if (length > 3) {
1208 data = net_buf_pull_u8(buf);
1209 if (net_buf_tailroom(buf) < (length - 1)) {
1210 return -EINVAL;
1211 }
1212 if (data == BT_AVDTP_AUDIO) {
1213 data = net_buf_pull_u8(buf);
1214 *codec_type = data;
1215 *codec_info_element_len = (length - 2);
1216 *codec_info_element =
1217 net_buf_pull_mem(buf, (*codec_info_element_len));
1218 return 0;
1219 }
1220 }
1221 break;
1222
1223 default:
1224 break;
1225 }
1226 }
1227 return -EIO;
1228 }
1229
avdtp_process_configure_command(struct bt_avdtp * session,uint8_t cmd,struct bt_avdtp_set_configuration_params * param)1230 static int avdtp_process_configure_command(struct bt_avdtp *session,
1231 uint8_t cmd,
1232 struct bt_avdtp_set_configuration_params *param)
1233 {
1234 struct net_buf *buf;
1235
1236 LOG_DBG("");
1237 if (!param || !session) {
1238 LOG_DBG("Error: Callback/Session not valid");
1239 return -EINVAL;
1240 }
1241
1242 buf = avdtp_create_pdu(BT_AVDTP_CMD,
1243 BT_AVDTP_PACKET_TYPE_SINGLE,
1244 cmd);
1245 if (!buf) {
1246 LOG_ERR("Error: No Buff available");
1247 return -ENOMEM;
1248 }
1249
1250 /* Body of the message */
1251 /* ACP Stream Endpoint ID */
1252 net_buf_add_u8(buf, (param->acp_stream_ep_id << 2u));
1253 /* INT Stream Endpoint ID */
1254 net_buf_add_u8(buf, (param->int_stream_endpoint_id << 2u));
1255 /* Service Category: Media Transport */
1256 net_buf_add_u8(buf, BT_AVDTP_SERVICE_MEDIA_TRANSPORT);
1257 /* LOSC */
1258 net_buf_add_u8(buf, 0);
1259 /* Service Category: Media Codec */
1260 net_buf_add_u8(buf, BT_AVDTP_SERVICE_MEDIA_CODEC);
1261 /* LOSC */
1262 net_buf_add_u8(buf, param->codec_specific_ie_len + 2);
1263 /* Media Type */
1264 net_buf_add_u8(buf, param->media_type << 4U);
1265 /* Media Codec Type */
1266 net_buf_add_u8(buf, param->media_codec_type);
1267 /* Codec Info Element */
1268 net_buf_add_mem(buf, param->codec_specific_ie, param->codec_specific_ie_len);
1269
1270 return avdtp_send(session, buf, ¶m->req);
1271 }
1272
bt_avdtp_set_configuration(struct bt_avdtp * session,struct bt_avdtp_set_configuration_params * param)1273 int bt_avdtp_set_configuration(struct bt_avdtp *session,
1274 struct bt_avdtp_set_configuration_params *param)
1275 {
1276 if (!param || !session || !param->sep) {
1277 LOG_DBG("Error: parameters not valid");
1278 return -EINVAL;
1279 }
1280
1281 if (param->sep->state != AVDTP_IDLE) {
1282 return -EINVAL;
1283 }
1284
1285 return avdtp_process_configure_command(session, BT_AVDTP_SET_CONFIGURATION, param);
1286 }
1287
bt_avdtp_reconfigure(struct bt_avdtp * session,struct bt_avdtp_set_configuration_params * param)1288 int bt_avdtp_reconfigure(struct bt_avdtp *session,
1289 struct bt_avdtp_set_configuration_params *param)
1290 {
1291 if (!param || !session || !param->sep) {
1292 LOG_DBG("Error: parameters not valid");
1293 return -EINVAL;
1294 }
1295
1296 if (param->sep->state != AVDTP_OPEN) {
1297 return -EINVAL;
1298 }
1299
1300 return avdtp_process_configure_command(session, BT_AVDTP_RECONFIGURE, param);
1301 }
1302
bt_avdtp_open(struct bt_avdtp * session,struct bt_avdtp_open_params * param)1303 int bt_avdtp_open(struct bt_avdtp *session,
1304 struct bt_avdtp_open_params *param)
1305 {
1306 struct net_buf *buf;
1307
1308 LOG_DBG("");
1309 if (!param || !session || !param->sep) {
1310 LOG_DBG("Error: parameters not valid");
1311 return -EINVAL;
1312 }
1313
1314 if (param->sep->state != AVDTP_CONFIGURED) {
1315 return -EINVAL;
1316 }
1317
1318 buf = avdtp_create_pdu(BT_AVDTP_CMD,
1319 BT_AVDTP_PACKET_TYPE_SINGLE,
1320 BT_AVDTP_OPEN);
1321 if (!buf) {
1322 LOG_ERR("Error: No Buff available");
1323 return -ENOMEM;
1324 }
1325
1326 /* Body of the message */
1327 /* ACP Stream Endpoint ID */
1328 net_buf_add_u8(buf, (param->acp_stream_ep_id << 2u));
1329
1330 return avdtp_send(session, buf, ¶m->req);
1331 }
1332
bt_avdtp_start(struct bt_avdtp * session,struct bt_avdtp_start_params * param)1333 int bt_avdtp_start(struct bt_avdtp *session,
1334 struct bt_avdtp_start_params *param)
1335 {
1336 struct net_buf *buf;
1337
1338 LOG_DBG("");
1339 if (!param || !session || !param->sep) {
1340 LOG_DBG("Error: parameters not valid");
1341 return -EINVAL;
1342 }
1343
1344 if (param->sep->state != AVDTP_OPEN) {
1345 return -EINVAL;
1346 }
1347
1348 buf = avdtp_create_pdu(BT_AVDTP_CMD,
1349 BT_AVDTP_PACKET_TYPE_SINGLE,
1350 BT_AVDTP_START);
1351 if (!buf) {
1352 LOG_ERR("Error: No Buff available");
1353 return -ENOMEM;
1354 }
1355
1356 /* Body of the message */
1357 /* ACP Stream Endpoint ID */
1358 net_buf_add_u8(buf, (param->acp_stream_ep_id << 2u));
1359
1360 return avdtp_send(session, buf, ¶m->req);
1361 }
1362
bt_avdtp_send_media_data(struct bt_avdtp_sep * sep,struct net_buf * buf)1363 int bt_avdtp_send_media_data(struct bt_avdtp_sep *sep, struct net_buf *buf)
1364 {
1365 int err;
1366
1367 if (sep->state != AVDTP_STREAMING) {
1368 return -EIO;
1369 }
1370
1371 err = bt_l2cap_chan_send(&sep->chan.chan, buf);
1372 if (err < 0) {
1373 LOG_ERR("Error:L2CAP send fail - err = %d", err);
1374 return err;
1375 }
1376
1377 return err;
1378 }
1379
bt_avdtp_get_media_mtu(struct bt_avdtp_sep * sep)1380 uint32_t bt_avdtp_get_media_mtu(struct bt_avdtp_sep *sep)
1381 {
1382 return sep->chan.tx.mtu;
1383 }
1384