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