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