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