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