1 /******************************************************************************
2 *
3 * Copyright 2002-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This module contains the action functions associated with the stream
22 * control block state machine.
23 *
24 ******************************************************************************/
25
26 #define LOG_TAG "bluetooth-a2dp"
27
28 #include <bluetooth/log.h>
29 #include <string.h>
30
31 #include "a2dp_codec_api.h"
32 #include "avdt_api.h"
33 #include "avdt_int.h"
34 #include "internal_include/bt_target.h"
35 #include "os/log.h"
36 #include "osi/include/allocator.h"
37 #include "osi/include/osi.h"
38 #include "stack/include/bt_hdr.h"
39 #include "stack/include/bt_types.h"
40 #include "types/raw_address.h"
41
42 using namespace bluetooth;
43
44 /* This table is used to lookup the callback event that matches a particular
45 * state machine API request event. Note that state machine API request
46 * events are at the beginning of the event list starting at zero, thus
47 * allowing for this table.
48 */
49 const uint8_t avdt_scb_cback_evt[] = {
50 0, /* API_REMOVE_EVT (no event) */
51 AVDT_WRITE_CFM_EVT, /* API_WRITE_REQ_EVT */
52 0, /* API_GETCONFIG_REQ_EVT (no event) */
53 0, /* API_DELAY_RPT_REQ_EVT (no event) */
54 AVDT_OPEN_CFM_EVT, /* API_SETCONFIG_REQ_EVT */
55 AVDT_OPEN_CFM_EVT, /* API_OPEN_REQ_EVT */
56 AVDT_CLOSE_CFM_EVT, /* API_CLOSE_REQ_EVT */
57 AVDT_RECONFIG_CFM_EVT, /* API_RECONFIG_REQ_EVT */
58 AVDT_SECURITY_CFM_EVT, /* API_SECURITY_REQ_EVT */
59 0 /* API_ABORT_REQ_EVT (no event) */
60 };
61
62 /*******************************************************************************
63 *
64 * Function avdt_scb_gen_ssrc
65 *
66 * Description This function generates a SSRC number unique to the stream.
67 *
68 * Returns SSRC value.
69 *
70 ******************************************************************************/
avdt_scb_gen_ssrc(AvdtpScb * p_scb)71 uint32_t avdt_scb_gen_ssrc(AvdtpScb* p_scb) {
72 /* combine the value of the media type and codec type of the SCB */
73 return ((uint32_t)(p_scb->stream_config.cfg.codec_info[1] |
74 p_scb->stream_config.cfg.codec_info[2]));
75 }
76
77 /*******************************************************************************
78 *
79 * Function avdt_scb_hdl_abort_cmd
80 *
81 * Description This function sends the SCB an AVDT_SCB_API_ABORT_RSP_EVT
82 * to initiate sending of an abort response message.
83 *
84 * Returns Nothing.
85 *
86 ******************************************************************************/
avdt_scb_hdl_abort_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)87 void avdt_scb_hdl_abort_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
88 p_scb->role = AVDT_CLOSE_ACP;
89 avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_RSP_EVT, p_data);
90 }
91
92 /*******************************************************************************
93 *
94 * Function avdt_scb_hdl_abort_rsp
95 *
96 * Description This function is an empty function; it serves as a
97 * placeholder for a conformance API action function.
98 *
99 * Returns Nothing.
100 *
101 ******************************************************************************/
avdt_scb_hdl_abort_rsp(AvdtpScb *,tAVDT_SCB_EVT *)102 void avdt_scb_hdl_abort_rsp(AvdtpScb* /* p_scb */,
103 tAVDT_SCB_EVT* /* p_data */) {
104 return;
105 }
106
107 /*******************************************************************************
108 *
109 * Function avdt_scb_hdl_close_cmd
110 *
111 * Description This function sends the SCB an AVDT_SCB_API_CLOSE_RSP_EVT
112 * to initiate sending of a close response message.
113 *
114 * Returns Nothing.
115 *
116 ******************************************************************************/
avdt_scb_hdl_close_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)117 void avdt_scb_hdl_close_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
118 p_scb->role = AVDT_CLOSE_ACP;
119 avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_RSP_EVT, p_data);
120 }
121
122 /*******************************************************************************
123 *
124 * Function avdt_scb_hdl_close_rsp
125 *
126 * Description This function sets the close_code variable to the error
127 * code returned in the close response.
128 *
129 * Returns Nothing.
130 *
131 ******************************************************************************/
avdt_scb_hdl_close_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)132 void avdt_scb_hdl_close_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
133 p_scb->close_code = p_data->msg.hdr.err_code;
134 }
135
136 /*******************************************************************************
137 *
138 * Function avdt_scb_hdl_getconfig_cmd
139 *
140 * Description This function retrieves the configuration parameters of
141 * the SCB and sends the SCB an AVDT_SCB_API_GETCONFIG_RSP_EVT
142 * to initiate sending of a get configuration response message.
143 *
144 * Returns Nothing.
145 *
146 ******************************************************************************/
avdt_scb_hdl_getconfig_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)147 void avdt_scb_hdl_getconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
148 p_data->msg.svccap.p_cfg = &p_scb->curr_cfg;
149
150 avdt_scb_event(p_scb, AVDT_SCB_API_GETCONFIG_RSP_EVT, p_data);
151 }
152
153 /*******************************************************************************
154 *
155 * Function avdt_scb_hdl_getconfig_rsp
156 *
157 * Description This function is an empty function; it serves as a
158 * placeholder for a conformance API action function.
159 *
160 * Returns Nothing.
161 *
162 ******************************************************************************/
avdt_scb_hdl_getconfig_rsp(AvdtpScb *,tAVDT_SCB_EVT *)163 void avdt_scb_hdl_getconfig_rsp(AvdtpScb* /* p_scb */,
164 tAVDT_SCB_EVT* /* p_data */) {
165 return;
166 }
167
168 /*******************************************************************************
169 *
170 * Function avdt_scb_hdl_open_cmd
171 *
172 * Description This function sends the SCB an AVDT_SCB_API_OPEN_RSP_EVT
173 * to initiate sending of an open response message.
174 *
175 * Returns Nothing.
176 *
177 ******************************************************************************/
avdt_scb_hdl_open_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)178 void avdt_scb_hdl_open_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
179 avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_RSP_EVT, p_data);
180 }
181
182 /*******************************************************************************
183 *
184 * Function avdt_scb_hdl_open_rej
185 *
186 * Description This function calls the application callback function
187 * indicating the open request has failed. It initializes
188 * certain SCB variables and sends a AVDT_CCB_UL_CLOSE_EVT
189 * to the CCB.
190 *
191 * Returns Nothing.
192 *
193 ******************************************************************************/
avdt_scb_hdl_open_rej(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)194 void avdt_scb_hdl_open_rej(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
195 /* do exactly same as setconfig reject */
196 avdt_scb_hdl_setconfig_rej(p_scb, p_data);
197 }
198
199 /*******************************************************************************
200 *
201 * Function avdt_scb_hdl_open_rsp
202 *
203 * Description This function calls avdt_ad_open_req() to initiate
204 * connection of the transport channel for this stream.
205 *
206 * Returns Nothing.
207 *
208 ******************************************************************************/
avdt_scb_hdl_open_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT *)209 void avdt_scb_hdl_open_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
210 /* initiate opening of trans channels for this SEID */
211 p_scb->role = AVDT_OPEN_INT;
212 avdt_ad_open_req(AVDT_CHAN_MEDIA, p_scb->p_ccb, p_scb, AVDT_INT);
213
214 /* start tc connect timer */
215 alarm_set_on_mloop(p_scb->transport_channel_timer,
216 AVDT_SCB_TC_CONN_TIMEOUT_MS,
217 avdt_scb_transport_channel_timer_timeout, p_scb);
218 }
219
220 /*******************************************************************************
221 *
222 * Function avdt_scb_hdl_pkt_no_frag
223 *
224 * Description
225 *
226 * Returns Nothing.
227 *
228 ******************************************************************************/
avdt_scb_hdl_pkt_no_frag(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)229 void avdt_scb_hdl_pkt_no_frag(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
230 uint8_t *p, *p_start;
231 uint8_t o_v, o_p, o_x, o_cc;
232 uint8_t m_pt;
233 uint8_t marker;
234 uint16_t seq;
235 uint32_t time_stamp;
236 uint16_t offset;
237 uint16_t ex_len;
238 uint8_t pad_len = 0;
239 uint16_t len = p_data->p_pkt->len;
240
241 p = p_start = (uint8_t*)(p_data->p_pkt + 1) + p_data->p_pkt->offset;
242
243 /* parse media packet header */
244 offset = 12;
245 // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4
246 if (offset > len) goto length_error;
247 AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc);
248 AVDT_MSG_PRS_M_PT(p, m_pt, marker);
249 BE_STREAM_TO_UINT16(seq, p);
250 BE_STREAM_TO_UINT32(time_stamp, p);
251 p += 4;
252
253 /* skip over any csrc's in packet */
254 offset += o_cc * 4;
255 p += o_cc * 4;
256
257 /* check for and skip over extension header */
258 if (o_x) {
259 offset += 4;
260 if (offset > len) goto length_error;
261 p += 2;
262 BE_STREAM_TO_UINT16(ex_len, p);
263 p += ex_len * 4;
264 }
265
266 if ((p - p_start) >= len) {
267 osi_free_and_reset((void**)&p_data->p_pkt);
268 return;
269 }
270 offset = p - p_start;
271
272 /* adjust length for any padding at end of packet */
273 if (o_p) {
274 /* padding length in last byte of packet */
275 pad_len = *(p_start + len - 1);
276 }
277
278 /* do sanity check */
279 if (pad_len >= (len - offset)) {
280 log::warn("Got bad media packet");
281 osi_free_and_reset((void**)&p_data->p_pkt);
282 }
283 /* adjust offset and length and send it up */
284 else {
285 p_data->p_pkt->len -= (offset + pad_len);
286 p_data->p_pkt->offset += offset;
287
288 if (p_scb->stream_config.p_sink_data_cback != NULL) {
289 /* report sequence number */
290 p_data->p_pkt->layer_specific = seq;
291 (*p_scb->stream_config.p_sink_data_cback)(
292 avdt_scb_to_hdl(p_scb), p_data->p_pkt, time_stamp,
293 (uint8_t)(m_pt | (marker << 7)));
294 } else {
295 osi_free_and_reset((void**)&p_data->p_pkt);
296 }
297 }
298 return;
299 length_error:
300 log::warn("hdl packet length {} too short: must be at least {}", len, offset);
301 osi_free_and_reset((void**)&p_data->p_pkt);
302 }
303
304 /*******************************************************************************
305 *
306 * Function avdt_scb_hdl_report
307 *
308 * Description
309 *
310 * Returns Nothing.
311 *
312 ******************************************************************************/
avdt_scb_hdl_report(AvdtpScb * p_scb,uint8_t * p,uint16_t len)313 uint8_t* avdt_scb_hdl_report(AvdtpScb* p_scb, uint8_t* p, uint16_t len) {
314 uint16_t result = AVDT_SUCCESS;
315 uint8_t* p_start = p;
316 uint32_t ssrc;
317 uint8_t o_v, o_p, o_cc;
318 uint32_t min_len = 0;
319 AVDT_REPORT_TYPE pt;
320 tAVDT_REPORT_DATA report;
321
322 log::verbose("");
323 if (p_scb->stream_config.p_report_cback) {
324 /* parse report packet header */
325 min_len += 8;
326 if (min_len > len) {
327 log::warn("hdl packet length {} too short: must be at least {}", len,
328 min_len);
329 goto avdt_scb_hdl_report_exit;
330 }
331 AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc);
332 pt = *p++;
333 p += 2;
334 BE_STREAM_TO_UINT32(ssrc, p);
335
336 switch (pt) {
337 case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */
338 min_len += 20;
339 if (min_len > len) {
340 log::warn("hdl packet length {} too short: must be at least {}", len,
341 min_len);
342 goto avdt_scb_hdl_report_exit;
343 }
344 BE_STREAM_TO_UINT32(report.sr.ntp_sec, p);
345 BE_STREAM_TO_UINT32(report.sr.ntp_frac, p);
346 BE_STREAM_TO_UINT32(report.sr.rtp_time, p);
347 BE_STREAM_TO_UINT32(report.sr.pkt_count, p);
348 BE_STREAM_TO_UINT32(report.sr.octet_count, p);
349 break;
350
351 case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */
352 min_len += 20;
353 if (min_len > len) {
354 log::warn("hdl packet length {} too short: must be at least {}", len,
355 min_len);
356 goto avdt_scb_hdl_report_exit;
357 }
358 report.rr.frag_lost = *p;
359 BE_STREAM_TO_UINT32(report.rr.packet_lost, p);
360 report.rr.packet_lost &= 0xFFFFFF;
361 BE_STREAM_TO_UINT32(report.rr.seq_num_rcvd, p);
362 BE_STREAM_TO_UINT32(report.rr.jitter, p);
363 BE_STREAM_TO_UINT32(report.rr.lsr, p);
364 BE_STREAM_TO_UINT32(report.rr.dlsr, p);
365 break;
366
367 case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
368 uint8_t sdes_type;
369 min_len += 1;
370 if (min_len > len) {
371 log::warn("hdl packet length {} too short: must be at least {}", len,
372 min_len);
373 goto avdt_scb_hdl_report_exit;
374 }
375 BE_STREAM_TO_UINT8(sdes_type, p);
376 if (sdes_type == AVDT_RTCP_SDES_CNAME) {
377 uint8_t name_length;
378 min_len += 1;
379 if (min_len > len) {
380 log::warn("hdl packet length {} too short: must be at least {}",
381 len, min_len);
382 goto avdt_scb_hdl_report_exit;
383 }
384 BE_STREAM_TO_UINT8(name_length, p);
385 if (name_length > len - min_len ||
386 name_length > AVDT_MAX_CNAME_SIZE) {
387 result = AVDT_BAD_PARAMS;
388 } else {
389 BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length);
390 }
391 } else {
392 if (min_len + 1 > len) {
393 log::warn("hdl packet length {} too short: must be at least {}",
394 len, min_len);
395 goto avdt_scb_hdl_report_exit;
396 }
397 log::warn("SDES SSRC=0x{:08x} sc={} {} len={}", ssrc, o_cc, sdes_type,
398 *p);
399 result = AVDT_BUSY;
400 }
401 break;
402
403 default:
404 log::error("Bad Report pkt - packet type: {}", pt);
405 result = AVDT_BAD_PARAMS;
406 }
407
408 if (result == AVDT_SUCCESS)
409 (*p_scb->stream_config.p_report_cback)(avdt_scb_to_hdl(p_scb), pt,
410 &report);
411 }
412 avdt_scb_hdl_report_exit:
413 p_start += len;
414 return p_start;
415 }
416
417 /*******************************************************************************
418 *
419 * Function avdt_scb_hdl_pkt
420 *
421 * Description
422 *
423 * Returns Nothing.
424 *
425 ******************************************************************************/
avdt_scb_hdl_pkt(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)426 void avdt_scb_hdl_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
427 if (p_data->p_pkt->layer_specific == AVDT_CHAN_REPORT) {
428 uint8_t* p = (uint8_t*)(p_data->p_pkt + 1) + p_data->p_pkt->offset;
429 avdt_scb_hdl_report(p_scb, p, p_data->p_pkt->len);
430 osi_free_and_reset((void**)&p_data->p_pkt);
431 } else {
432 avdt_scb_hdl_pkt_no_frag(p_scb, p_data);
433 }
434 }
435
436 /*******************************************************************************
437 *
438 * Function avdt_scb_drop_pkt
439 *
440 * Description Drop an incoming media packet. This function is called if
441 * a media packet is received in any state besides streaming.
442 *
443 * Returns Nothing.
444 *
445 ******************************************************************************/
avdt_scb_drop_pkt(AvdtpScb *,tAVDT_SCB_EVT * p_data)446 void avdt_scb_drop_pkt(AvdtpScb* /* p_scb */, tAVDT_SCB_EVT* p_data) {
447 log::error("dropped incoming media packet");
448 osi_free_and_reset((void**)&p_data->p_pkt);
449 }
450
451 /*******************************************************************************
452 *
453 * Function avdt_scb_hdl_reconfig_cmd
454 *
455 * Description This function calls the application callback function
456 * with a reconfiguration indication.
457 *
458 * Returns Nothing.
459 *
460 ******************************************************************************/
avdt_scb_hdl_reconfig_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)461 void avdt_scb_hdl_reconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
462 /* if command not supported */
463 if (p_scb->stream_config.nsc_mask & AvdtpStreamConfig::AVDT_NSC_RECONFIG) {
464 /* send reject */
465 p_data->msg.hdr.err_code = AVDT_ERR_NSC;
466 p_data->msg.hdr.err_param = 0;
467 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, p_data);
468 } else {
469 /* store requested configuration */
470 p_scb->req_cfg = *p_data->msg.reconfig_cmd.p_cfg;
471
472 /* call application callback */
473 (*p_scb->stream_config.p_avdt_ctrl_cback)(
474 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_RECONFIG_IND_EVT,
475 (tAVDT_CTRL*)&p_data->msg.reconfig_cmd, p_scb->stream_config.scb_index);
476 }
477 }
478
479 /*******************************************************************************
480 *
481 * Function avdt_scb_hdl_reconfig_rsp
482 *
483 * Description This function calls the application callback function
484 * with a reconfiguration confirm.
485 *
486 * Returns Nothing.
487 *
488 ******************************************************************************/
avdt_scb_hdl_reconfig_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)489 void avdt_scb_hdl_reconfig_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
490 if (p_data->msg.hdr.err_code == 0) {
491 /* store new configuration */
492 if (p_scb->req_cfg.num_codec > 0) {
493 p_scb->curr_cfg.num_codec = p_scb->req_cfg.num_codec;
494 memcpy(p_scb->curr_cfg.codec_info, p_scb->req_cfg.codec_info,
495 AVDT_CODEC_SIZE);
496 }
497 if (p_scb->req_cfg.num_protect > 0) {
498 p_scb->curr_cfg.num_protect = p_scb->req_cfg.num_protect;
499 memcpy(p_scb->curr_cfg.protect_info, p_scb->req_cfg.protect_info,
500 AVDT_PROTECT_SIZE);
501 }
502 }
503
504 p_data->msg.svccap.p_cfg = &p_scb->curr_cfg;
505
506 /* call application callback */
507 (*p_scb->stream_config.p_avdt_ctrl_cback)(
508 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_RECONFIG_CFM_EVT,
509 (tAVDT_CTRL*)&p_data->msg.svccap, p_scb->stream_config.scb_index);
510 }
511
512 /*******************************************************************************
513 *
514 * Function avdt_scb_hdl_security_cmd
515 *
516 * Description This function calls the application callback with a
517 * security indication.
518 *
519 * Returns Nothing.
520 *
521 ******************************************************************************/
avdt_scb_hdl_security_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)522 void avdt_scb_hdl_security_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
523 /* if command not supported */
524 if (p_scb->stream_config.nsc_mask & AvdtpStreamConfig::AVDT_NSC_SECURITY) {
525 /* send reject */
526 p_data->msg.hdr.err_code = AVDT_ERR_NSC;
527 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, p_data);
528 } else {
529 /* call application callback */
530 (*p_scb->stream_config.p_avdt_ctrl_cback)(
531 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_SECURITY_IND_EVT,
532 (tAVDT_CTRL*)&p_data->msg.security_cmd, p_scb->stream_config.scb_index);
533 }
534 }
535
536 /*******************************************************************************
537 *
538 * Function avdt_scb_hdl_security_rsp
539 *
540 * Description This function calls the application callback with a
541 * security confirm.
542 *
543 * Returns Nothing.
544 *
545 ******************************************************************************/
avdt_scb_hdl_security_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)546 void avdt_scb_hdl_security_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
547 /* call application callback */
548 (*p_scb->stream_config.p_avdt_ctrl_cback)(
549 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_SECURITY_CFM_EVT,
550 (tAVDT_CTRL*)&p_data->msg.security_cmd, p_scb->stream_config.scb_index);
551 }
552
553 /*******************************************************************************
554 *
555 * Function avdt_scb_hdl_setconfig_cmd
556 *
557 * Description This function marks the SCB as in use and copies the
558 * configuration and peer SEID to the SCB. It then calls
559 * the application callback with a configuration indication.
560 *
561 * Returns Nothing.
562 *
563 ******************************************************************************/
avdt_scb_hdl_setconfig_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)564 void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
565 log::verbose("p_scb->in_use={} p_avdt_scb={} scb_index={}", p_scb->in_use,
566 fmt::ptr(p_scb), p_scb->stream_config.scb_index);
567
568 if (!p_scb->in_use) {
569 log::verbose("codec: {}",
570 A2DP_CodecInfoString(p_scb->stream_config.cfg.codec_info));
571 log::verbose("codec: {}", A2DP_CodecInfoString(
572 p_data->msg.config_cmd.p_cfg->codec_info));
573 AvdtpSepConfig* p_cfg = p_data->msg.config_cmd.p_cfg;
574 if (A2DP_GetCodecType(p_scb->stream_config.cfg.codec_info) ==
575 A2DP_GetCodecType(p_cfg->codec_info)) {
576 /* copy info to scb */
577 AvdtpCcb* p_ccb = avdt_ccb_by_idx(p_data->msg.config_cmd.hdr.ccb_idx);
578 if (p_scb->p_ccb != p_ccb) {
579 log::error(
580 "mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb={} != p_ccb={}): "
581 "p_scb={} scb_handle={} ccb_idx={}",
582 fmt::ptr(p_scb->p_ccb), fmt::ptr(p_ccb), fmt::ptr(p_scb),
583 p_scb->ScbHandle(), p_data->msg.config_cmd.hdr.ccb_idx);
584 avdt_scb_rej_not_in_use(p_scb, p_data);
585 return;
586 }
587 /* set sep as in use */
588 p_scb->in_use = true;
589
590 p_scb->peer_seid = p_data->msg.config_cmd.int_seid;
591 p_scb->req_cfg = *p_cfg;
592 /* call app callback */
593 /* handle of scb- which is same as sep handle of bta_av_cb.p_scb*/
594 (*p_scb->stream_config.p_avdt_ctrl_cback)(
595 avdt_scb_to_hdl(p_scb),
596 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
597 AVDT_CONFIG_IND_EVT, (tAVDT_CTRL*)&p_data->msg.config_cmd,
598 p_scb->stream_config.scb_index);
599 } else {
600 p_data->msg.hdr.err_code = AVDT_ERR_UNSUP_CFG;
601 p_data->msg.hdr.err_param = 0;
602 avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx),
603 p_data->msg.hdr.sig_id, &p_data->msg);
604 }
605 } else {
606 log::verbose("calling avdt_scb_rej_in_use()");
607 avdt_scb_rej_in_use(p_scb, p_data);
608 }
609 }
610
611 /*******************************************************************************
612 *
613 * Function avdt_scb_hdl_setconfig_rej
614 *
615 * Description This function marks the SCB as not in use and calls the
616 * application callback with an open confirm indicating
617 * failure.
618 *
619 * Returns Nothing.
620 *
621 ******************************************************************************/
avdt_scb_hdl_setconfig_rej(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)622 void avdt_scb_hdl_setconfig_rej(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
623 /* clear scb variables */
624 avdt_scb_clr_vars(p_scb, p_data);
625
626 /* tell ccb we're done with signaling channel */
627 avdt_ccb_event(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx),
628 AVDT_CCB_UL_CLOSE_EVT, NULL);
629
630 /* call application callback */
631 (*p_scb->stream_config.p_avdt_ctrl_cback)(
632 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_OPEN_CFM_EVT,
633 (tAVDT_CTRL*)&p_data->msg.hdr, p_scb->stream_config.scb_index);
634 }
635
636 /*******************************************************************************
637 *
638 * Function avdt_scb_snd_snk_delay_rpt_req
639 *
640 * Description This function sends the delay report request once it is sink
641 *
642 * Returns Nothing.
643 *
644 ******************************************************************************/
avdt_scb_snd_snk_delay_rpt_req(AvdtpScb * p_scb,tAVDT_SCB_EVT *)645 void avdt_scb_snd_snk_delay_rpt_req(AvdtpScb* p_scb,
646 tAVDT_SCB_EVT* /* p_data */) {
647 if (p_scb->p_ccb == NULL) {
648 return;
649 }
650
651 // In sink mode, report a fixed delay value when this device is the sink
652 // side. Delay value in this function is in unit of 1/10ms.
653 if (p_scb->stream_config.tsep != AVDT_TSEP_SNK) {
654 return;
655 }
656
657 tAVDT_SCB_EVT evt;
658 evt.apidelay.hdr.seid = p_scb->peer_seid;
659 evt.apidelay.delay = AVDT_SINK_DELAY_MS * 10;
660 avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt);
661 }
662
663 /*******************************************************************************
664 *
665 * Function avdt_scb_hdl_setconfig_rsp
666 *
667 * Description This function sends the SCB an AVDT_SCB_API_OPEN_REQ_EVT
668 * to initiate sending of an open command message.
669 *
670 * This function sends the SCB an AVDT_SCB_API_DELAY_RPT_REQ_EVT
671 * to initiate sending of delay report command message only
672 * when the endpoint takes sink role.
673 *
674 * Returns Nothing.
675 *
676 ******************************************************************************/
avdt_scb_hdl_setconfig_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)677 void avdt_scb_hdl_setconfig_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
678 tAVDT_EVT_HDR single;
679
680 if (p_scb->p_ccb != NULL) {
681 /* save configuration */
682 p_scb->curr_cfg = p_scb->req_cfg;
683
684 // In sink mode, report delay value when this device initiates the connection.
685 // Delay reporting is sent before open request (i.e., in configured state).
686 avdt_scb_snd_snk_delay_rpt_req(p_scb, p_data);
687
688 /* initiate open */
689 single.seid = p_scb->peer_seid;
690 tAVDT_SCB_EVT avdt_scb_evt;
691 avdt_scb_evt.msg.single = single;
692 avdt_scb_event(p_scb, AVDT_SCB_API_OPEN_REQ_EVT, &avdt_scb_evt);
693 }
694 }
695
696 /*******************************************************************************
697 *
698 * Function avdt_scb_hdl_start_cmd
699 *
700 * Description This function calls the application callback with a
701 * start indication.
702 *
703 * Returns Nothing.
704 *
705 ******************************************************************************/
avdt_scb_hdl_start_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT *)706 void avdt_scb_hdl_start_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
707 (*p_scb->stream_config.p_avdt_ctrl_cback)(
708 avdt_scb_to_hdl(p_scb),
709 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
710 AVDT_START_IND_EVT, NULL, p_scb->stream_config.scb_index);
711 }
712
713 /*******************************************************************************
714 *
715 * Function avdt_scb_hdl_start_rsp
716 *
717 * Description This function calls the application callback with a
718 * start confirm.
719 *
720 * Returns Nothing.
721 *
722 ******************************************************************************/
avdt_scb_hdl_start_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)723 void avdt_scb_hdl_start_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
724 (*p_scb->stream_config.p_avdt_ctrl_cback)(
725 avdt_scb_to_hdl(p_scb),
726 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
727 AVDT_START_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr,
728 p_scb->stream_config.scb_index);
729 }
730
731 /*******************************************************************************
732 *
733 * Function avdt_scb_hdl_suspend_cmd
734 *
735 * Description This function calls the application callback with a suspend
736 * indication.
737 *
738 * Returns Nothing.
739 *
740 ******************************************************************************/
avdt_scb_hdl_suspend_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT *)741 void avdt_scb_hdl_suspend_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
742 (*p_scb->stream_config.p_avdt_ctrl_cback)(
743 avdt_scb_to_hdl(p_scb),
744 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
745 AVDT_SUSPEND_IND_EVT, NULL, p_scb->stream_config.scb_index);
746 }
747
748 /*******************************************************************************
749 *
750 * Function avdt_scb_hdl_suspend_rsp
751 *
752 * Description This function calls the application callback with a suspend
753 * confirm.
754 *
755 * Returns Nothing.
756 *
757 ******************************************************************************/
avdt_scb_hdl_suspend_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)758 void avdt_scb_hdl_suspend_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
759 (*p_scb->stream_config.p_avdt_ctrl_cback)(
760 avdt_scb_to_hdl(p_scb),
761 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
762 AVDT_SUSPEND_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr,
763 p_scb->stream_config.scb_index);
764 }
765
766 /*******************************************************************************
767 *
768 * Function avdt_scb_hdl_tc_close
769 *
770 * Description This function is called when the transport channel is
771 * closed. It marks the SCB as not in use and
772 * initializes certain SCB parameters. It then sends
773 * an AVDT_CCB_UL_CLOSE_EVT to the CCB if the SCB
774 * initiated the close. It then checks to see if the SCB
775 * is to be removed. If it is it deallocates the SCB.
776 * Finally, it calls the application callback with a close
777 * indication.
778 *
779 * Returns Nothing.
780 *
781 ******************************************************************************/
avdt_scb_hdl_tc_close(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)782 void avdt_scb_hdl_tc_close(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
783 uint8_t hdl = avdt_scb_to_hdl(p_scb);
784 tAVDT_CTRL_CBACK* p_avdt_ctrl_cback = p_scb->stream_config.p_avdt_ctrl_cback;
785 tAVDT_CTRL avdt_ctrl;
786 uint8_t event;
787 AvdtpCcb* p_ccb = p_scb->p_ccb;
788 RawAddress remote_addr = p_ccb->peer_addr;
789 uint8_t scb_index = p_scb->stream_config.scb_index;
790
791 /* set up hdr */
792 avdt_ctrl.hdr.err_code = p_scb->close_code;
793
794 /* clear sep variables */
795 avdt_scb_clr_vars(p_scb, p_data);
796 p_scb->media_seq = 0;
797 p_scb->cong = false;
798
799 /* free pkt we're holding, if any */
800 osi_free_and_reset((void**)&p_scb->p_pkt);
801
802 alarm_cancel(p_scb->transport_channel_timer);
803
804 if ((p_scb->role == AVDT_CLOSE_INT) || (p_scb->role == AVDT_OPEN_INT)) {
805 /* tell ccb we're done with signaling channel */
806 avdt_ccb_event(p_ccb, AVDT_CCB_UL_CLOSE_EVT, NULL);
807 }
808 event =
809 (p_scb->role == AVDT_CLOSE_INT) ? AVDT_CLOSE_CFM_EVT : AVDT_CLOSE_IND_EVT;
810 p_scb->role = AVDT_CLOSE_ACP;
811
812 if (p_scb->remove) {
813 avdt_scb_dealloc(p_scb, NULL);
814 }
815
816 /* call app callback */
817 (*p_avdt_ctrl_cback)(hdl, remote_addr, event, &avdt_ctrl, scb_index);
818 }
819
820 /*******************************************************************************
821 *
822 * Function avdt_scb_snd_delay_rpt_req
823 *
824 * Description This function calls the application callback with a delay
825 * report.
826 *
827 * Returns Nothing.
828 *
829 ******************************************************************************/
avdt_scb_snd_delay_rpt_req(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)830 void avdt_scb_snd_delay_rpt_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
831 if (p_scb->stream_config.cfg.psc_mask & AVDT_PSC_DELAY_RPT) {
832 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_DELAY_RPT,
833 (tAVDT_MSG*)&p_data->apidelay);
834 }
835 }
836
837 /*******************************************************************************
838 *
839 * Function avdt_scb_hdl_delay_rpt_cmd
840 *
841 * Description This function calls the application callback with a delay
842 * report.
843 *
844 * Returns Nothing.
845 *
846 ******************************************************************************/
avdt_scb_hdl_delay_rpt_cmd(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)847 void avdt_scb_hdl_delay_rpt_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
848 (*p_scb->stream_config.p_avdt_ctrl_cback)(
849 avdt_scb_to_hdl(p_scb),
850 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
851 AVDT_DELAY_REPORT_EVT, (tAVDT_CTRL*)&p_data->msg.hdr,
852 p_scb->stream_config.scb_index);
853
854 if (p_scb->p_ccb)
855 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_DELAY_RPT, &p_data->msg);
856 else
857 avdt_scb_rej_not_in_use(p_scb, p_data);
858 }
859
860 /*******************************************************************************
861 *
862 * Function avdt_scb_hdl_delay_rpt_rsp
863 *
864 * Description This function calls the application callback with a delay
865 * report.
866 *
867 * Returns Nothing.
868 *
869 ******************************************************************************/
avdt_scb_hdl_delay_rpt_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)870 void avdt_scb_hdl_delay_rpt_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
871 (*p_scb->stream_config.p_avdt_ctrl_cback)(
872 avdt_scb_to_hdl(p_scb),
873 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
874 AVDT_DELAY_REPORT_CFM_EVT, (tAVDT_CTRL*)&p_data->msg.hdr,
875 p_scb->stream_config.scb_index);
876 }
877
878 /*******************************************************************************
879 *
880 * Function avdt_scb_hdl_tc_close_sto
881 *
882 * Description This function is called when a channel is closed in OPEN
883 * state. Check the channel type and process accordingly.
884 *
885 * Returns Nothing.
886 *
887 ******************************************************************************/
avdt_scb_hdl_tc_close_sto(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)888 void avdt_scb_hdl_tc_close_sto(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
889 tAVDT_CTRL avdt_ctrl;
890 /* AVDT_CHAN_SIG does not visit this action */
891 if (p_data && p_data->close.type != AVDT_CHAN_MEDIA) {
892 /* it's reporting or recovery channel,
893 * the channel close in open state means the peer does not support it */
894 if (p_data->close.old_tc_state == AVDT_AD_ST_OPEN) {
895 avdt_ctrl.hdr.err_code = 0;
896 avdt_ctrl.hdr.err_param = 0;
897 /* call app callback */
898 (*p_scb->stream_config.p_avdt_ctrl_cback)(
899 avdt_scb_to_hdl(p_scb),
900 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
901 AVDT_REPORT_DISCONN_EVT, &avdt_ctrl, p_scb->stream_config.scb_index);
902 }
903 } else {
904 /* must be in OPEN state. need to go back to idle */
905 avdt_scb_event(p_scb, AVDT_SCB_MSG_ABORT_RSP_EVT, NULL);
906 avdt_scb_hdl_tc_close(p_scb, p_data);
907 }
908 }
909
910 /*******************************************************************************
911 *
912 * Function avdt_scb_hdl_tc_open
913 *
914 * Description This function is called when the transport channel is
915 * opened while in the opening state. It calls the
916 * application callback with an open indication or open
917 * confirm depending on who initiated the open procedure.
918 *
919 * Returns Nothing.
920 *
921 ******************************************************************************/
avdt_scb_hdl_tc_open(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)922 void avdt_scb_hdl_tc_open(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
923 uint8_t event;
924 uint8_t role;
925
926 alarm_cancel(p_scb->transport_channel_timer);
927
928 event =
929 (p_scb->role == AVDT_OPEN_INT) ? AVDT_OPEN_CFM_EVT : AVDT_OPEN_IND_EVT;
930 p_data->open.hdr.err_code = 0;
931
932 log::verbose("psc_mask: cfg: 0x{:x}, req:0x{:x}, cur: 0x{:x}",
933 p_scb->stream_config.cfg.psc_mask, p_scb->req_cfg.psc_mask,
934 p_scb->curr_cfg.psc_mask);
935 if (p_scb->curr_cfg.psc_mask & AVDT_PSC_REPORT) {
936 /* open the reporting channel, if both devices support it */
937 role = (p_scb->role == AVDT_OPEN_INT) ? AVDT_INT : AVDT_ACP;
938 avdt_ad_open_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, role);
939 }
940
941 /* call app callback */
942 (*p_scb->stream_config.p_avdt_ctrl_cback)(
943 avdt_scb_to_hdl(p_scb),
944 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty, event,
945 (tAVDT_CTRL*)&p_data->open, p_scb->stream_config.scb_index);
946 }
947
948 /*******************************************************************************
949 *
950 * Function avdt_scb_hdl_tc_open_sto
951 *
952 * Description This function is called when the transport channel is
953 * opened while in the opening state. It calls the
954 * application callback with an open indication or open
955 * confirm depending on who initiated the open procedure.
956 *
957 * Returns Nothing.
958 *
959 ******************************************************************************/
avdt_scb_hdl_tc_open_sto(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)960 void avdt_scb_hdl_tc_open_sto(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
961 tAVDT_CTRL avdt_ctrl;
962 /* open reporting channel here, when it is implemented */
963
964 /* call app callback */
965 if (p_data->open.hdr.err_code == AVDT_CHAN_REPORT) {
966 avdt_ctrl.hdr.err_code = 0;
967 avdt_ctrl.hdr.err_param = 1;
968 (*p_scb->stream_config.p_avdt_ctrl_cback)(
969 avdt_scb_to_hdl(p_scb),
970 p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
971 AVDT_REPORT_CONN_EVT, &avdt_ctrl, p_scb->stream_config.scb_index);
972 }
973 }
974
975 /*******************************************************************************
976 *
977 * Function avdt_scb_hdl_write_req
978 *
979 * Description This function frees the media packet currently stored in
980 * the SCB, if any. Then it builds a new media packet from
981 * with the passed in buffer and stores it in the SCB.
982 *
983 * Returns Nothing.
984 *
985 ******************************************************************************/
avdt_scb_hdl_write_req(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)986 void avdt_scb_hdl_write_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
987 uint8_t* p;
988 uint32_t ssrc;
989 bool add_rtp_header = !(p_data->apiwrite.opt & AVDT_DATA_OPT_NO_RTP);
990
991 /* free packet we're holding, if any; to be replaced with new */
992 if (p_scb->p_pkt != NULL) {
993 /* this shouldn't be happening */
994 log::warn("Dropped media packet; congested");
995 }
996 osi_free_and_reset((void**)&p_scb->p_pkt);
997
998 /* Recompute only if the RTP header wasn't disabled by the API */
999 if (add_rtp_header) {
1000 bool is_content_protection = (p_scb->curr_cfg.num_protect > 0);
1001 add_rtp_header =
1002 A2DP_UsesRtpHeader(is_content_protection, p_scb->curr_cfg.codec_info);
1003 }
1004
1005 /* Build a media packet, and add an RTP header if required. */
1006 if (add_rtp_header) {
1007 if (p_data->apiwrite.p_buf->offset < AVDT_MEDIA_HDR_SIZE) {
1008 return;
1009 }
1010
1011 ssrc = avdt_scb_gen_ssrc(p_scb);
1012
1013 p_data->apiwrite.p_buf->len += AVDT_MEDIA_HDR_SIZE;
1014 p_data->apiwrite.p_buf->offset -= AVDT_MEDIA_HDR_SIZE;
1015 p_scb->media_seq++;
1016 p = (uint8_t*)(p_data->apiwrite.p_buf + 1) + p_data->apiwrite.p_buf->offset;
1017
1018 UINT8_TO_BE_STREAM(p, AVDT_MEDIA_OCTET1);
1019 UINT8_TO_BE_STREAM(p, p_data->apiwrite.m_pt);
1020 UINT16_TO_BE_STREAM(p, p_scb->media_seq);
1021 UINT32_TO_BE_STREAM(p, p_data->apiwrite.time_stamp);
1022 UINT32_TO_BE_STREAM(p, ssrc);
1023 }
1024
1025 /* store it */
1026 p_scb->p_pkt = p_data->apiwrite.p_buf;
1027 }
1028
1029 /*******************************************************************************
1030 *
1031 * Function avdt_scb_snd_abort_req
1032 *
1033 * Description This function sends an abort command message.
1034 *
1035 * Returns Nothing.
1036 *
1037 ******************************************************************************/
avdt_scb_snd_abort_req(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1038 void avdt_scb_snd_abort_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1039 tAVDT_EVT_HDR hdr;
1040
1041 log::verbose("p_scb->p_ccb={}", fmt::ptr(p_scb->p_ccb));
1042
1043 if (p_scb->p_ccb != NULL) {
1044 p_scb->role = AVDT_CLOSE_INT;
1045
1046 hdr.seid = p_scb->peer_seid;
1047
1048 tAVDT_MSG avdt_msg;
1049 avdt_msg.hdr = hdr;
1050 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_ABORT, &avdt_msg);
1051 }
1052 }
1053
1054 /*******************************************************************************
1055 *
1056 * Function avdt_scb_snd_abort_rsp
1057 *
1058 * Description This function sends an abort response message.
1059 *
1060 * Returns Nothing.
1061 *
1062 ******************************************************************************/
avdt_scb_snd_abort_rsp(AvdtpScb *,tAVDT_SCB_EVT * p_data)1063 void avdt_scb_snd_abort_rsp(AvdtpScb* /* p_scb */, tAVDT_SCB_EVT* p_data) {
1064 avdt_msg_send_rsp(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx), AVDT_SIG_ABORT,
1065 &p_data->msg);
1066 }
1067
1068 /*******************************************************************************
1069 *
1070 * Function avdt_scb_snd_close_req
1071 *
1072 * Description This function sends a close command message.
1073 *
1074 * Returns Nothing.
1075 *
1076 ******************************************************************************/
avdt_scb_snd_close_req(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1077 void avdt_scb_snd_close_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1078 tAVDT_EVT_HDR hdr;
1079
1080 p_scb->role = AVDT_CLOSE_INT;
1081
1082 hdr.seid = p_scb->peer_seid;
1083
1084 tAVDT_MSG avdt_msg;
1085 avdt_msg.hdr = hdr;
1086 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_CLOSE, &avdt_msg);
1087 }
1088
1089 /*******************************************************************************
1090 *
1091 * Function avdt_scb_snd_stream_close
1092 *
1093 * Description This function sends a close command message.
1094 *
1095 * Returns Nothing.
1096 *
1097 ******************************************************************************/
avdt_scb_snd_stream_close(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1098 void avdt_scb_snd_stream_close(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1099 osi_free_and_reset((void**)&p_scb->p_pkt);
1100 avdt_scb_snd_close_req(p_scb, p_data);
1101 }
1102
1103 /*******************************************************************************
1104 *
1105 * Function avdt_scb_snd_close_rsp
1106 *
1107 * Description This function sends a close response message.
1108 *
1109 * Returns Nothing.
1110 *
1111 ******************************************************************************/
avdt_scb_snd_close_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1112 void avdt_scb_snd_close_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1113 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_CLOSE, &p_data->msg);
1114 }
1115
1116 /*******************************************************************************
1117 *
1118 * Function avdt_scb_snd_getconfig_req
1119 *
1120 * Description This function sends a get configuration command message.
1121 *
1122 * Returns Nothing.
1123 *
1124 ******************************************************************************/
avdt_scb_snd_getconfig_req(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1125 void avdt_scb_snd_getconfig_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1126 tAVDT_EVT_HDR hdr;
1127
1128 hdr.seid = p_scb->peer_seid;
1129
1130 tAVDT_MSG avdt_msg;
1131 avdt_msg.hdr = hdr;
1132 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_GETCONFIG, &avdt_msg);
1133 }
1134
1135 /*******************************************************************************
1136 *
1137 * Function avdt_scb_snd_getconfig_rsp
1138 *
1139 * Description This function sends a get configuration response message.
1140 *
1141 * Returns Nothing.
1142 *
1143 ******************************************************************************/
avdt_scb_snd_getconfig_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1144 void avdt_scb_snd_getconfig_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1145 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_GETCONFIG, &p_data->msg);
1146 }
1147
1148 /*******************************************************************************
1149 *
1150 * Function avdt_scb_snd_open_req
1151 *
1152 * Description This function sends an open command message.
1153 *
1154 * Returns Nothing.
1155 *
1156 ******************************************************************************/
avdt_scb_snd_open_req(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1157 void avdt_scb_snd_open_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1158 tAVDT_EVT_HDR hdr;
1159
1160 hdr.seid = p_scb->peer_seid;
1161
1162 tAVDT_MSG avdt_msg;
1163 avdt_msg.hdr = hdr;
1164 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_OPEN, &avdt_msg);
1165 }
1166
1167 /*******************************************************************************
1168 *
1169 * Function avdt_scb_snd_open_rsp
1170 *
1171 * Description This function sends an open response message. It also
1172 * calls avdt_ad_open_req() to accept a transport channel
1173 * connection.
1174 *
1175 * Returns Nothing.
1176 *
1177 ******************************************************************************/
avdt_scb_snd_open_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1178 void avdt_scb_snd_open_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1179 /* notify adaption that we're waiting for transport channel open */
1180 p_scb->role = AVDT_OPEN_ACP;
1181 avdt_ad_open_req(AVDT_CHAN_MEDIA, p_scb->p_ccb, p_scb, AVDT_ACP);
1182
1183 /* send response */
1184 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_OPEN, &p_data->msg);
1185
1186 alarm_set_on_mloop(p_scb->transport_channel_timer,
1187 AVDT_SCB_TC_CONN_TIMEOUT_MS,
1188 avdt_scb_transport_channel_timer_timeout, p_scb);
1189 }
1190
1191 /*******************************************************************************
1192 *
1193 * Function avdt_scb_snd_reconfig_req
1194 *
1195 * Description This function stores the configuration parameters in the
1196 * SCB and sends a reconfiguration command message.
1197 *
1198 * Returns Nothing.
1199 *
1200 ******************************************************************************/
avdt_scb_snd_reconfig_req(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1201 void avdt_scb_snd_reconfig_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1202 log::verbose("p_scb->peer_seid={} p_data->msg.hdr.seid={}", p_scb->peer_seid,
1203 p_data->msg.hdr.seid);
1204 log::verbose("codec: {}",
1205 A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info));
1206
1207 p_scb->req_cfg = *p_data->msg.config_cmd.p_cfg;
1208 p_data->msg.hdr.seid = p_scb->peer_seid;
1209 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_RECONFIG, &p_data->msg);
1210 }
1211
1212 /*******************************************************************************
1213 *
1214 * Function avdt_scb_snd_reconfig_rsp
1215 *
1216 * Description This function stores the configuration parameters in the
1217 * SCB and sends a reconfiguration response message.
1218 *
1219 * Returns Nothing.
1220 *
1221 ******************************************************************************/
avdt_scb_snd_reconfig_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1222 void avdt_scb_snd_reconfig_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1223 if (p_data->msg.hdr.err_code == 0) {
1224 /* store new configuration */
1225 if (p_scb->req_cfg.num_codec > 0) {
1226 p_scb->curr_cfg.num_codec = p_scb->req_cfg.num_codec;
1227 memcpy(p_scb->curr_cfg.codec_info, p_scb->req_cfg.codec_info,
1228 AVDT_CODEC_SIZE);
1229 }
1230 if (p_scb->req_cfg.num_protect > 0) {
1231 p_scb->curr_cfg.num_protect = p_scb->req_cfg.num_protect;
1232 memcpy(p_scb->curr_cfg.protect_info, p_scb->req_cfg.protect_info,
1233 AVDT_PROTECT_SIZE);
1234 }
1235
1236 /* send response */
1237 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_RECONFIG, &p_data->msg);
1238 } else {
1239 /* send reject */
1240 avdt_msg_send_rej(p_scb->p_ccb, AVDT_SIG_RECONFIG, &p_data->msg);
1241 }
1242 }
1243
1244 /*******************************************************************************
1245 *
1246 * Function avdt_scb_snd_security_req
1247 *
1248 * Description This function sends a security command message.
1249 *
1250 * Returns Nothing.
1251 *
1252 ******************************************************************************/
avdt_scb_snd_security_req(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1253 void avdt_scb_snd_security_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1254 p_data->msg.hdr.seid = p_scb->peer_seid;
1255 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_SECURITY, &p_data->msg);
1256 }
1257
1258 /*******************************************************************************
1259 *
1260 * Function avdt_scb_snd_security_rsp
1261 *
1262 * Description This function sends a security response message.
1263 *
1264 * Returns Nothing.
1265 *
1266 ******************************************************************************/
avdt_scb_snd_security_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1267 void avdt_scb_snd_security_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1268 if (p_data->msg.hdr.err_code == 0) {
1269 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_SECURITY, &p_data->msg);
1270 } else {
1271 avdt_msg_send_rej(p_scb->p_ccb, AVDT_SIG_SECURITY, &p_data->msg);
1272 }
1273 }
1274
1275 /*******************************************************************************
1276 *
1277 * Function avdt_scb_snd_setconfig_rej
1278 *
1279 * Description This function marks the SCB as not in use and sends a
1280 * set configuration reject message.
1281 *
1282 * Returns Nothing.
1283 *
1284 ******************************************************************************/
avdt_scb_snd_setconfig_rej(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1285 void avdt_scb_snd_setconfig_rej(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1286 if (p_scb->p_ccb != NULL) {
1287 avdt_msg_send_rej(p_scb->p_ccb, AVDT_SIG_SETCONFIG, &p_data->msg);
1288
1289 /* clear scb variables */
1290 avdt_scb_clr_vars(p_scb, p_data);
1291 }
1292 }
1293
1294 /*******************************************************************************
1295 *
1296 * Function avdt_scb_snd_setconfig_req
1297 *
1298 * Description This function marks the SCB as in use and copies the
1299 * configuration parameters to the SCB. Then the function
1300 * sends a set configuration command message and initiates
1301 * opening of the signaling channel.
1302 *
1303 * Returns Nothing.
1304 *
1305 ******************************************************************************/
avdt_scb_snd_setconfig_req(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1306 void avdt_scb_snd_setconfig_req(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1307 log::verbose("codec: {}",
1308 A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info));
1309
1310 /* copy API parameters to scb, set scb as in use */
1311
1312 AvdtpCcb* p_ccb = avdt_ccb_by_idx(p_data->msg.config_cmd.hdr.ccb_idx);
1313 if (p_scb->p_ccb != p_ccb) {
1314 log::error(
1315 "mismatch in AVDTP SCB/CCB state: (p_scb->p_ccb={} != p_ccb={}): "
1316 "p_scb={} scb_handle={} ccb_idx={}",
1317 fmt::ptr(p_scb->p_ccb), fmt::ptr(p_ccb), fmt::ptr(p_scb),
1318 p_scb->ScbHandle(), p_data->msg.config_cmd.hdr.ccb_idx);
1319 avdt_scb_rej_not_in_use(p_scb, p_data);
1320 return;
1321 }
1322 p_scb->in_use = true;
1323 p_scb->peer_seid = p_data->msg.config_cmd.hdr.seid;
1324 p_scb->req_cfg = *p_data->msg.config_cmd.p_cfg;
1325
1326 avdt_msg_send_cmd(p_scb->p_ccb, p_scb, AVDT_SIG_SETCONFIG, &p_data->msg);
1327
1328 /* tell ccb to open channel */
1329 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_UL_OPEN_EVT, NULL);
1330 }
1331
1332 /*******************************************************************************
1333 *
1334 * Function avdt_scb_snd_setconfig_rsp
1335 *
1336 * Description This function copies the requested configuration into the
1337 * current configuration and sends a set configuration
1338 * response message.
1339 *
1340 * Returns Nothing.
1341 *
1342 ******************************************************************************/
avdt_scb_snd_setconfig_rsp(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1343 void avdt_scb_snd_setconfig_rsp(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1344 if (p_scb->p_ccb != NULL) {
1345 p_scb->curr_cfg = p_scb->req_cfg;
1346
1347 avdt_msg_send_rsp(p_scb->p_ccb, AVDT_SIG_SETCONFIG, &p_data->msg);
1348 }
1349 }
1350
1351 /*******************************************************************************
1352 *
1353 * Function avdt_scb_snd_tc_close
1354 *
1355 * Description This function calls avdt_ad_close_req() to close the
1356 * transport channel for this SCB.
1357 *
1358 * Returns Nothing.
1359 *
1360 ******************************************************************************/
avdt_scb_snd_tc_close(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1361 void avdt_scb_snd_tc_close(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1362 if (p_scb->curr_cfg.psc_mask & AVDT_PSC_REPORT)
1363 avdt_ad_close_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
1364 avdt_ad_close_req(AVDT_CHAN_MEDIA, p_scb->p_ccb, p_scb);
1365 }
1366
1367 /*******************************************************************************
1368 *
1369 * Function avdt_scb_cb_err
1370 *
1371 * Description This function calls the application callback function
1372 * indicating an error.
1373 *
1374 * Returns Nothing.
1375 *
1376 ******************************************************************************/
avdt_scb_cb_err(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1377 void avdt_scb_cb_err(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1378 tAVDT_CTRL avdt_ctrl;
1379
1380 /* set error code and parameter */
1381 avdt_ctrl.hdr.err_code = AVDT_ERR_BAD_STATE;
1382 avdt_ctrl.hdr.err_param = 0;
1383
1384 /* call callback, using lookup table to get callback event */
1385 (*p_scb->stream_config.p_avdt_ctrl_cback)(
1386 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty,
1387 avdt_scb_cback_evt[p_scb->curr_evt], &avdt_ctrl,
1388 p_scb->stream_config.scb_index);
1389 }
1390
1391 /*******************************************************************************
1392 *
1393 * Function avdt_scb_cong_state
1394 *
1395 * Description This function sets the congestion state of the SCB media
1396 * transport channel.
1397 *
1398 * Returns Nothing.
1399 *
1400 ******************************************************************************/
avdt_scb_cong_state(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1401 void avdt_scb_cong_state(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1402 p_scb->cong = p_data->llcong;
1403 }
1404
1405 /*******************************************************************************
1406 *
1407 * Function avdt_scb_rej_state
1408 *
1409 * Description This function sends a reject message to the peer indicating
1410 * incorrect state for the received command message.
1411 *
1412 * Returns Nothing.
1413 *
1414 ******************************************************************************/
avdt_scb_rej_state(AvdtpScb *,tAVDT_SCB_EVT * p_data)1415 void avdt_scb_rej_state(AvdtpScb* /* p_scb */, tAVDT_SCB_EVT* p_data) {
1416 p_data->msg.hdr.err_code = AVDT_ERR_BAD_STATE;
1417 p_data->msg.hdr.err_param = 0;
1418 avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx),
1419 p_data->msg.hdr.sig_id, &p_data->msg);
1420 }
1421
1422 /*******************************************************************************
1423 *
1424 * Function avdt_scb_rej_in_use
1425 *
1426 * Description This function sends a reject message to the peer indicating
1427 * the stream is in use.
1428 *
1429 * Returns Nothing.
1430 *
1431 ******************************************************************************/
avdt_scb_rej_in_use(AvdtpScb *,tAVDT_SCB_EVT * p_data)1432 void avdt_scb_rej_in_use(AvdtpScb* /* p_scb */, tAVDT_SCB_EVT* p_data) {
1433 p_data->msg.hdr.err_code = AVDT_ERR_IN_USE;
1434 p_data->msg.hdr.err_param = 0;
1435 avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx),
1436 p_data->msg.hdr.sig_id, &p_data->msg);
1437 }
1438
1439 /*******************************************************************************
1440 *
1441 * Function avdt_scb_rej_not_in_use
1442 *
1443 * Description This function sends a reject message to the peer indicating
1444 * the stream is in use.
1445 *
1446 * Returns Nothing.
1447 *
1448 ******************************************************************************/
avdt_scb_rej_not_in_use(AvdtpScb *,tAVDT_SCB_EVT * p_data)1449 void avdt_scb_rej_not_in_use(AvdtpScb* /* p_scb */, tAVDT_SCB_EVT* p_data) {
1450 p_data->msg.hdr.err_code = AVDT_ERR_NOT_IN_USE;
1451 p_data->msg.hdr.err_param = 0;
1452 avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx),
1453 p_data->msg.hdr.sig_id, &p_data->msg);
1454 }
1455
1456 /*******************************************************************************
1457 *
1458 * Function avdt_scb_set_remove
1459 *
1460 * Description This function marks an SCB to be removed.
1461 *
1462 * Returns Nothing.
1463 *
1464 ******************************************************************************/
avdt_scb_set_remove(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1465 void avdt_scb_set_remove(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1466 p_scb->remove = true;
1467 }
1468
1469 /*******************************************************************************
1470 *
1471 * Function avdt_scb_free_pkt
1472 *
1473 * Description This function frees the media packet passed in.
1474 *
1475 * Returns Nothing.
1476 *
1477 ******************************************************************************/
avdt_scb_free_pkt(AvdtpScb * p_scb,tAVDT_SCB_EVT * p_data)1478 void avdt_scb_free_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
1479 tAVDT_CTRL avdt_ctrl;
1480
1481 /* set error code and parameter */
1482 avdt_ctrl.hdr.err_code = AVDT_ERR_BAD_STATE;
1483 avdt_ctrl.hdr.err_param = 0;
1484
1485 osi_free_and_reset((void**)&p_data->apiwrite.p_buf);
1486
1487 log::warn("Dropped media packet");
1488
1489 /* we need to call callback to keep data flow going */
1490 (*p_scb->stream_config.p_avdt_ctrl_cback)(
1491 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_WRITE_CFM_EVT,
1492 &avdt_ctrl, p_scb->stream_config.scb_index);
1493 }
1494
1495 /*******************************************************************************
1496 *
1497 * Function avdt_scb_clr_pkt
1498 *
1499 * Description This function frees the media packet stored in the SCB.
1500 *
1501 * Returns Nothing.
1502 *
1503 ******************************************************************************/
avdt_scb_clr_pkt(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1504 void avdt_scb_clr_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1505 tAVDT_CTRL avdt_ctrl;
1506 AvdtpCcb* p_ccb;
1507 uint8_t tcid;
1508 uint16_t lcid;
1509
1510 /* set error code and parameter */
1511 avdt_ctrl.hdr.err_code = AVDT_ERR_BAD_STATE;
1512 avdt_ctrl.hdr.err_param = 0;
1513 /* flush the media data queued at L2CAP */
1514 p_ccb = p_scb->p_ccb;
1515 if (p_ccb != NULL) {
1516 /* get tcid from type, scb */
1517 tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
1518
1519 lcid = avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1520 const uint16_t buffers_left =
1521 L2CA_FlushChannel(lcid, L2CAP_FLUSH_CHANS_ALL);
1522 if (buffers_left) {
1523 log::warn(
1524 "Unable to flush L2CAP ALL channel peer:{} cid:{} buffers_left:{}",
1525 p_ccb->peer_addr, lcid, buffers_left);
1526 }
1527 }
1528
1529 if (p_scb->p_pkt != NULL) {
1530 osi_free_and_reset((void**)&p_scb->p_pkt);
1531
1532 log::verbose("Dropped stored media packet");
1533
1534 /* we need to call callback to keep data flow going */
1535 (*p_scb->stream_config.p_avdt_ctrl_cback)(
1536 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_WRITE_CFM_EVT,
1537 &avdt_ctrl, p_scb->stream_config.scb_index);
1538 }
1539 }
1540
1541 /*******************************************************************************
1542 *
1543 * Function avdt_scb_chk_snd_pkt
1544 *
1545 * Description This function checks if the SCB is congested, and if not
1546 * congested it sends a stored media packet, if any. After it
1547 * sends the packet it calls the application callback function
1548 * with a write confirm.
1549 *
1550 * Returns Nothing.
1551 *
1552 ******************************************************************************/
avdt_scb_chk_snd_pkt(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1553 void avdt_scb_chk_snd_pkt(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1554 tAVDT_CTRL avdt_ctrl;
1555 BT_HDR* p_pkt;
1556
1557 avdt_ctrl.hdr.err_code = 0;
1558
1559 if (!p_scb->cong) {
1560 if (p_scb->p_pkt != NULL) {
1561 p_pkt = p_scb->p_pkt;
1562 p_scb->p_pkt = NULL;
1563 avdt_ad_write_req(AVDT_CHAN_MEDIA, p_scb->p_ccb, p_scb, p_pkt);
1564
1565 (*p_scb->stream_config.p_avdt_ctrl_cback)(
1566 avdt_scb_to_hdl(p_scb), RawAddress::kEmpty, AVDT_WRITE_CFM_EVT,
1567 &avdt_ctrl, p_scb->stream_config.scb_index);
1568 }
1569 }
1570 }
1571
1572 /*******************************************************************************
1573 *
1574 * Function avdt_scb_transport_channel_timer
1575 *
1576 * Description This function is called to start a timer when the peer
1577 * initiates closing of the stream. The timer verifies that
1578 * the peer disconnects the transport channel.
1579 *
1580 * Returns Nothing.
1581 *
1582 ******************************************************************************/
avdt_scb_transport_channel_timer(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1583 void avdt_scb_transport_channel_timer(AvdtpScb* p_scb,
1584 tAVDT_SCB_EVT* /* p_data */) {
1585 alarm_set_on_mloop(p_scb->transport_channel_timer,
1586 AVDT_SCB_TC_DISC_TIMEOUT_MS,
1587 avdt_scb_transport_channel_timer_timeout, p_scb);
1588 }
1589
1590 /*******************************************************************************
1591 *
1592 * Function avdt_scb_clr_vars
1593 *
1594 * Description This function initializes certain SCB variables.
1595 *
1596 * Returns Nothing.
1597 *
1598 ******************************************************************************/
avdt_scb_clr_vars(AvdtpScb * p_scb,tAVDT_SCB_EVT *)1599 void avdt_scb_clr_vars(AvdtpScb* p_scb, tAVDT_SCB_EVT* /* p_data */) {
1600 p_scb->in_use = false;
1601 p_scb->peer_seid = 0;
1602 }
1603