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 API of the audio/video distribution transport
22 * protocol.
23 *
24 ******************************************************************************/
25
26 #include "avdt_api.h"
27 #include <string.h>
28 #include "avdt_int.h"
29 #include "avdtc_api.h"
30 #include "bt_target.h"
31 #include "bt_types.h"
32 #include "btm_api.h"
33 #include "btu.h"
34 #include "l2c_api.h"
35 #include "stack/include/a2dp_codec_api.h"
36
37 /* Control block for AVDTP */
38 AvdtpCb avdtp_cb;
39
avdt_ccb_idle_ccb_timer_timeout(void * data)40 void avdt_ccb_idle_ccb_timer_timeout(void* data) {
41 AvdtpCcb* p_ccb = (AvdtpCcb*)data;
42 uint8_t avdt_event = AVDT_CCB_IDLE_TOUT_EVT;
43 uint8_t err_code = AVDT_ERR_TIMEOUT;
44
45 tAVDT_CCB_EVT avdt_ccb_evt;
46 avdt_ccb_evt.err_code = err_code;
47 avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
48 }
49
avdt_ccb_ret_ccb_timer_timeout(void * data)50 void avdt_ccb_ret_ccb_timer_timeout(void* data) {
51 AvdtpCcb* p_ccb = (AvdtpCcb*)data;
52 uint8_t avdt_event = AVDT_CCB_RET_TOUT_EVT;
53 uint8_t err_code = AVDT_ERR_TIMEOUT;
54
55 tAVDT_CCB_EVT avdt_ccb_evt;
56 avdt_ccb_evt.err_code = err_code;
57 avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
58 }
59
avdt_ccb_rsp_ccb_timer_timeout(void * data)60 void avdt_ccb_rsp_ccb_timer_timeout(void* data) {
61 AvdtpCcb* p_ccb = (AvdtpCcb*)data;
62 uint8_t avdt_event = AVDT_CCB_RSP_TOUT_EVT;
63 uint8_t err_code = AVDT_ERR_TIMEOUT;
64
65 tAVDT_CCB_EVT avdt_ccb_evt;
66 avdt_ccb_evt.err_code = err_code;
67 avdt_ccb_event(p_ccb, avdt_event, &avdt_ccb_evt);
68 }
69
avdt_scb_transport_channel_timer_timeout(void * data)70 void avdt_scb_transport_channel_timer_timeout(void* data) {
71 AvdtpScb* p_scb = (AvdtpScb*)data;
72 uint8_t avdt_event = AVDT_SCB_TC_TOUT_EVT;
73
74 avdt_scb_event(p_scb, avdt_event, NULL);
75 }
76
77 /*******************************************************************************
78 *
79 * Function AVDT_Register
80 *
81 * Description This is the system level registration function for the
82 * AVDTP protocol. This function initializes AVDTP and
83 * prepares the protocol stack for its use. This function
84 * must be called once by the system or platform using AVDTP
85 * before the other functions of the API an be used.
86 *
87 *
88 * Returns void
89 *
90 ******************************************************************************/
AVDT_Register(AvdtpRcb * p_reg,tAVDT_CTRL_CBACK * p_cback)91 void AVDT_Register(AvdtpRcb* p_reg, tAVDT_CTRL_CBACK* p_cback) {
92 /* register PSM with L2CAP */
93 L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO*)&avdt_l2c_appl,
94 true /* enable_snoop */, nullptr, L2CAP_DEFAULT_MTU);
95
96 /* set security level */
97 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
98 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
99 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask,
100 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG);
101
102 /* do not use security on the media channel */
103 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
104 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
105 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
106 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA);
107
108 /* do not use security on the reporting channel */
109 BTM_SetSecurityLevel(true, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
110 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
111 BTM_SetSecurityLevel(false, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE,
112 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT);
113
114 /* initialize AVDTP data structures */
115 avdt_scb_init();
116 avdt_ccb_init();
117 avdt_ad_init();
118
119 /* copy registration struct */
120 avdtp_cb.rcb = *p_reg;
121 avdtp_cb.p_conn_cback = p_cback;
122 }
123
124 /*******************************************************************************
125 *
126 * Function AVDT_Deregister
127 *
128 * Description This function is called to deregister use AVDTP protocol.
129 * It is called when AVDTP is no longer being used by any
130 * application in the system. Before this function can be
131 * called, all streams must be removed with
132 * AVDT_RemoveStream().
133 *
134 *
135 * Returns void
136 *
137 ******************************************************************************/
AVDT_Deregister(void)138 void AVDT_Deregister(void) {
139 /* deregister PSM with L2CAP */
140 L2CA_Deregister(AVDT_PSM);
141 }
142
AVDT_AbortReq(uint8_t handle)143 void AVDT_AbortReq(uint8_t handle) {
144 AVDT_TRACE_WARNING("%s: avdt_handle=%d", __func__, handle);
145
146 AvdtpScb* p_scb = avdt_scb_by_hdl(handle);
147 if (p_scb != NULL) {
148 avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_REQ_EVT, NULL);
149 } else {
150 AVDT_TRACE_ERROR("%s Improper avdp_handle=%d, can not abort the stream",
151 __func__, handle);
152 }
153 }
154
155 /*******************************************************************************
156 *
157 * Function AVDT_CreateStream
158 *
159 * Description Create a stream endpoint. After a stream endpoint is
160 * created an application can initiate a connection between
161 * this endpoint and an endpoint on a peer device. In
162 * addition, a peer device can discover, get the capabilities,
163 * and connect to this endpoint.
164 *
165 *
166 * Returns AVDT_SUCCESS if successful, otherwise error.
167 *
168 ******************************************************************************/
AVDT_CreateStream(uint8_t peer_id,uint8_t * p_handle,const AvdtpStreamConfig & avdtp_stream_config)169 uint16_t AVDT_CreateStream(uint8_t peer_id, uint8_t* p_handle,
170 const AvdtpStreamConfig& avdtp_stream_config) {
171 uint16_t result = AVDT_SUCCESS;
172 AvdtpScb* p_scb;
173
174 AVDT_TRACE_DEBUG("%s: peer_id=%d", __func__, peer_id);
175
176 /* Verify parameters; if invalid, return failure */
177 if (((avdtp_stream_config.cfg.psc_mask & (~AVDT_PSC)) != 0) ||
178 (avdtp_stream_config.p_avdt_ctrl_cback == NULL)) {
179 result = AVDT_BAD_PARAMS;
180 }
181 /* Allocate scb; if no scbs, return failure */
182 else {
183 p_scb = avdt_scb_alloc(peer_id, avdtp_stream_config);
184 if (p_scb == NULL) {
185 result = AVDT_NO_RESOURCES;
186 } else {
187 *p_handle = avdt_scb_to_hdl(p_scb);
188 }
189 }
190
191 if (result != AVDT_SUCCESS) {
192 AVDT_TRACE_ERROR("%s: result=%d peer_id=%d scb_index=%d", __func__, result,
193 peer_id, avdtp_stream_config.scb_index);
194 }
195
196 return result;
197 }
198
199 /*******************************************************************************
200 *
201 * Function AVDT_RemoveStream
202 *
203 * Description Remove a stream endpoint. This function is called when
204 * the application is no longer using a stream endpoint.
205 * If this function is called when the endpoint is connected
206 * the connection is closed and then the stream endpoint
207 * is removed.
208 *
209 *
210 * Returns AVDT_SUCCESS if successful, otherwise error.
211 *
212 ******************************************************************************/
AVDT_RemoveStream(uint8_t handle)213 uint16_t AVDT_RemoveStream(uint8_t handle) {
214 uint16_t result = AVDT_SUCCESS;
215 AvdtpScb* p_scb;
216
217 AVDT_TRACE_DEBUG("%s: avdt_handle=%d", __func__, handle);
218
219 /* look up scb */
220 p_scb = avdt_scb_by_hdl(handle);
221 if (p_scb == NULL) {
222 result = AVDT_BAD_HANDLE;
223 } else {
224 /* send remove event to scb */
225 avdt_scb_event(p_scb, AVDT_SCB_API_REMOVE_EVT, NULL);
226 }
227
228 if (result != AVDT_SUCCESS) {
229 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
230 }
231
232 return result;
233 }
234
235 /*******************************************************************************
236 *
237 * Function AVDT_DiscoverReq
238 *
239 * Description This function initiates a connection to the AVDTP service
240 * on the peer device, if not already present, and discovers
241 * the stream endpoints on the peer device. (Please note
242 * that AVDTP discovery is unrelated to SDP discovery).
243 * This function can be called at any time regardless of
244 * whether there is an AVDTP connection to the peer device.
245 *
246 * When discovery is complete, an AVDT_DISCOVER_CFM_EVT
247 * is sent to the application via its callback function.
248 * The application must not call AVDT_GetCapReq() or
249 * AVDT_DiscoverReq() again to the same device until
250 * discovery is complete.
251 *
252 * The memory addressed by sep_info is allocated by the
253 * application. This memory is written to by AVDTP as part
254 * of the discovery procedure. This memory must remain
255 * accessible until the application receives the
256 * AVDT_DISCOVER_CFM_EVT.
257 *
258 * Returns AVDT_SUCCESS if successful, otherwise error.
259 *
260 ******************************************************************************/
AVDT_DiscoverReq(const RawAddress & bd_addr,uint8_t channel_index,tAVDT_SEP_INFO * p_sep_info,uint8_t max_seps,tAVDT_CTRL_CBACK * p_cback)261 uint16_t AVDT_DiscoverReq(const RawAddress& bd_addr, uint8_t channel_index,
262 tAVDT_SEP_INFO* p_sep_info, uint8_t max_seps,
263 tAVDT_CTRL_CBACK* p_cback) {
264 AvdtpCcb* p_ccb;
265 uint16_t result = AVDT_SUCCESS;
266 tAVDT_CCB_EVT evt;
267
268 AVDT_TRACE_DEBUG("%s", __func__);
269
270 /* find channel control block for this bd addr; if none, allocate one */
271 p_ccb = avdt_ccb_by_bd(bd_addr);
272 if (p_ccb == NULL) {
273 p_ccb = avdt_ccb_alloc_by_channel_index(bd_addr, channel_index);
274 if (p_ccb == NULL) {
275 /* could not allocate channel control block */
276 result = AVDT_NO_RESOURCES;
277 }
278 }
279
280 if (result == AVDT_SUCCESS) {
281 /* make sure no discovery or get capabilities req already in progress */
282 if (p_ccb->proc_busy) {
283 result = AVDT_BUSY;
284 }
285 /* send event to ccb */
286 else {
287 evt.discover.p_sep_info = p_sep_info;
288 evt.discover.num_seps = max_seps;
289 evt.discover.p_cback = p_cback;
290 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_REQ_EVT, &evt);
291 }
292 }
293
294 if (result != AVDT_SUCCESS) {
295 AVDT_TRACE_ERROR("%s: result=%d address=%s", __func__, result,
296 bd_addr.ToString().c_str());
297 }
298 return result;
299 }
300
301 /*******************************************************************************
302 *
303 * Function avdt_get_cap_req
304 *
305 * Description internal function to serve AVDT_GetCapReq
306 *
307 * Returns AVDT_SUCCESS if successful, otherwise error.
308 *
309 ******************************************************************************/
avdt_get_cap_req(const RawAddress & bd_addr,uint8_t channel_index,tAVDT_CCB_API_GETCAP * p_evt)310 static uint16_t avdt_get_cap_req(const RawAddress& bd_addr,
311 uint8_t channel_index,
312 tAVDT_CCB_API_GETCAP* p_evt) {
313 AvdtpCcb* p_ccb = NULL;
314 uint16_t result = AVDT_SUCCESS;
315
316 AVDT_TRACE_DEBUG("%s", __func__);
317
318 /* verify SEID */
319 if ((p_evt->single.seid < AVDT_SEID_MIN) ||
320 (p_evt->single.seid > AVDT_SEID_MAX)) {
321 AVDT_TRACE_ERROR("seid: %d", p_evt->single.seid);
322 result = AVDT_BAD_PARAMS;
323 }
324 /* find channel control block for this bd addr; if none, allocate one */
325 else {
326 p_ccb = avdt_ccb_by_bd(bd_addr);
327 if (p_ccb == NULL) {
328 p_ccb = avdt_ccb_alloc_by_channel_index(bd_addr, channel_index);
329 if (p_ccb == NULL) {
330 /* could not allocate channel control block */
331 result = AVDT_NO_RESOURCES;
332 }
333 }
334 }
335
336 if (result == AVDT_SUCCESS) {
337 /* make sure no discovery or get capabilities req already in progress */
338 if (p_ccb->proc_busy) {
339 result = AVDT_BUSY;
340 }
341 /* send event to ccb */
342 else {
343 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_REQ_EVT, (tAVDT_CCB_EVT*)p_evt);
344 }
345 }
346
347 if (result != AVDT_SUCCESS) {
348 AVDT_TRACE_ERROR("%s: result=%d address=%s", __func__, result,
349 bd_addr.ToString().c_str());
350 }
351 return result;
352 }
353
354 /*******************************************************************************
355 *
356 * Function AVDT_GetCapReq
357 *
358 * Description This function initiates a connection to the AVDTP service
359 * on the peer device, if not already present, and gets the
360 * capabilities of a stream endpoint on the peer device.
361 * This function can be called at any time regardless of
362 * whether there is an AVDTP connection to the peer device.
363 *
364 * When the procedure is complete, an AVDT_GETCAP_CFM_EVT is
365 * sent to the application via its callback function. The
366 * application must not call AVDT_GetCapReq() or
367 * AVDT_DiscoverReq() again until the procedure is complete.
368 *
369 * The memory pointed to by p_cfg is allocated by the
370 * application. This memory is written to by AVDTP as part
371 * of the get capabilities procedure. This memory must
372 * remain accessible until the application receives
373 * the AVDT_GETCAP_CFM_EVT.
374 *
375 * Returns AVDT_SUCCESS if successful, otherwise error.
376 *
377 ******************************************************************************/
AVDT_GetCapReq(const RawAddress & bd_addr,uint8_t channel_index,uint8_t seid,AvdtpSepConfig * p_cfg,tAVDT_CTRL_CBACK * p_cback,bool get_all_cap)378 uint16_t AVDT_GetCapReq(const RawAddress& bd_addr, uint8_t channel_index,
379 uint8_t seid, AvdtpSepConfig* p_cfg,
380 tAVDT_CTRL_CBACK* p_cback, bool get_all_cap) {
381 tAVDT_CCB_API_GETCAP getcap;
382 uint16_t result = AVDT_SUCCESS;
383
384 AVDT_TRACE_DEBUG("%s", __func__);
385
386 getcap.single.seid = seid;
387 if (get_all_cap) {
388 getcap.single.sig_id = AVDT_SIG_GET_ALLCAP;
389 } else {
390 getcap.single.sig_id = AVDT_SIG_GETCAP;
391 }
392 getcap.p_cfg = p_cfg;
393 getcap.p_cback = p_cback;
394 result = avdt_get_cap_req(bd_addr, channel_index, &getcap);
395
396 if (result != AVDT_SUCCESS) {
397 AVDT_TRACE_ERROR("%s: result=%d address=%s", __func__, result,
398 bd_addr.ToString().c_str());
399 }
400 return result;
401 }
402
403 /*******************************************************************************
404 *
405 * Function AVDT_DelayReport
406 *
407 * Description This functions sends a Delay Report to the peer device
408 * that is associated with a particular SEID.
409 * This function is called by SNK device.
410 *
411 * Returns AVDT_SUCCESS if successful, otherwise error.
412 *
413 ******************************************************************************/
AVDT_DelayReport(uint8_t handle,uint8_t seid,uint16_t delay)414 uint16_t AVDT_DelayReport(uint8_t handle, uint8_t seid, uint16_t delay) {
415 AvdtpScb* p_scb;
416 uint16_t result = AVDT_SUCCESS;
417 tAVDT_SCB_EVT evt;
418
419 AVDT_TRACE_DEBUG("%s: avdt_handle=%d seid=%d delay=%d", __func__, handle,
420 seid, delay);
421
422 /* map handle to scb */
423 p_scb = avdt_scb_by_hdl(handle);
424 if (p_scb == NULL) {
425 result = AVDT_BAD_HANDLE;
426 } else
427 /* send event to scb */
428 {
429 evt.apidelay.hdr.seid = seid;
430 evt.apidelay.delay = delay;
431 avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt);
432 }
433
434 if (result != AVDT_SUCCESS) {
435 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d seid=%d", __func__, result,
436 handle, seid);
437 }
438 return result;
439 }
440
441 /*******************************************************************************
442 *
443 * Function AVDT_OpenReq
444 *
445 * Description This function initiates a connection to the AVDTP service
446 * on the peer device, if not already present, and connects
447 * to a stream endpoint on a peer device. When the connection
448 * is completed, an AVDT_OPEN_CFM_EVT is sent to the
449 * application via the control callback function for this
450 * handle.
451 *
452 * Returns AVDT_SUCCESS if successful, otherwise error.
453 *
454 ******************************************************************************/
AVDT_OpenReq(uint8_t handle,const RawAddress & bd_addr,uint8_t channel_index,uint8_t seid,AvdtpSepConfig * p_cfg)455 uint16_t AVDT_OpenReq(uint8_t handle, const RawAddress& bd_addr,
456 uint8_t channel_index, uint8_t seid,
457 AvdtpSepConfig* p_cfg) {
458 AvdtpCcb* p_ccb = NULL;
459 AvdtpScb* p_scb = NULL;
460 uint16_t result = AVDT_SUCCESS;
461 tAVDT_SCB_EVT evt;
462
463 AVDT_TRACE_API("%s: address=%s avdt_handle=%d seid=%d", __func__,
464 bd_addr.ToString().c_str(), handle, seid);
465
466 /* verify SEID */
467 if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX)) {
468 result = AVDT_BAD_PARAMS;
469 }
470 /* map handle to scb */
471 else {
472 p_scb = avdt_scb_by_hdl(handle);
473 if (p_scb == NULL) {
474 result = AVDT_BAD_HANDLE;
475 }
476 /* find channel control block for this bd addr; if none, allocate one */
477 else {
478 p_ccb = avdt_ccb_by_bd(bd_addr);
479 if (p_ccb == NULL) {
480 p_ccb = avdt_ccb_alloc_by_channel_index(bd_addr, channel_index);
481 if (p_ccb == NULL) {
482 /* could not allocate channel control block */
483 result = AVDT_NO_RESOURCES;
484 }
485 }
486 }
487 }
488
489 /* send event to scb */
490 if (result == AVDT_SUCCESS) {
491 AVDT_TRACE_DEBUG("%s: codec: %s", __func__,
492 A2DP_CodecInfoString(p_cfg->codec_info).c_str());
493
494 evt.msg.config_cmd.hdr.seid = seid;
495 evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb);
496 evt.msg.config_cmd.int_seid = handle;
497 evt.msg.config_cmd.p_cfg = p_cfg;
498 avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt);
499 } else {
500 AVDT_TRACE_ERROR("%s: result=%d address=%s avdt_handle=%d", __func__,
501 result, bd_addr.ToString().c_str(), handle);
502 }
503
504 return result;
505 }
506
507 /*******************************************************************************
508 *
509 * Function AVDT_ConfigRsp
510 *
511 * Description Respond to a configure request from the peer device. This
512 * function must be called if the application receives an
513 * AVDT_CONFIG_IND_EVT through its control callback.
514 *
515 *
516 * Returns AVDT_SUCCESS if successful, otherwise error.
517 *
518 ******************************************************************************/
AVDT_ConfigRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t category)519 uint16_t AVDT_ConfigRsp(uint8_t handle, uint8_t label, uint8_t error_code,
520 uint8_t category) {
521 AvdtpScb* p_scb;
522 tAVDT_SCB_EVT evt;
523 uint16_t result = AVDT_SUCCESS;
524 uint8_t event_code;
525
526 AVDT_TRACE_DEBUG("%s: avdt_handle=%d label=%d error_code=0x%x category=%d",
527 __func__, handle, label, error_code, category);
528
529 /* map handle to scb */
530 p_scb = avdt_scb_by_hdl(handle);
531 if (p_scb == NULL) {
532 result = AVDT_BAD_HANDLE;
533 }
534 /* handle special case when this function is called but peer has not send
535 ** a configuration cmd; ignore and return error result
536 */
537 else if (!p_scb->in_use) {
538 result = AVDT_BAD_HANDLE;
539 }
540 /* send event to scb */
541 else {
542 evt.msg.hdr.err_code = error_code;
543 evt.msg.hdr.err_param = category;
544 evt.msg.hdr.label = label;
545 if (error_code == 0) {
546 event_code = AVDT_SCB_API_SETCONFIG_RSP_EVT;
547 } else {
548 event_code = AVDT_SCB_API_SETCONFIG_REJ_EVT;
549 }
550 avdt_scb_event(p_scb, event_code, &evt);
551 }
552
553 if (result != AVDT_SUCCESS) {
554 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
555 }
556 return result;
557 }
558
559 /*******************************************************************************
560 *
561 * Function AVDT_StartReq
562 *
563 * Description Start one or more stream endpoints. This initiates the
564 * transfer of media packets for the streams. All stream
565 * endpoints must previously be opened. When the streams
566 * are started, an AVDT_START_CFM_EVT is sent to the
567 * application via the control callback function for each
568 * stream.
569 *
570 *
571 * Returns AVDT_SUCCESS if successful, otherwise error.
572 *
573 ******************************************************************************/
AVDT_StartReq(uint8_t * p_handles,uint8_t num_handles)574 uint16_t AVDT_StartReq(uint8_t* p_handles, uint8_t num_handles) {
575 AvdtpScb* p_scb = NULL;
576 tAVDT_CCB_EVT evt;
577 uint16_t result = AVDT_SUCCESS;
578 int i;
579
580 AVDT_TRACE_DEBUG("%s: num_handles=%d", __func__, num_handles);
581
582 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
583 result = AVDT_BAD_PARAMS;
584 } else {
585 /* verify handles */
586 for (i = 0; i < num_handles; i++) {
587 p_scb = avdt_scb_by_hdl(p_handles[i]);
588 if (p_scb == NULL) {
589 result = AVDT_BAD_HANDLE;
590 break;
591 }
592 }
593 }
594
595 if (result == AVDT_SUCCESS) {
596 if (p_scb->p_ccb == NULL) {
597 result = AVDT_BAD_HANDLE;
598 } else {
599 /* send event to ccb */
600 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
601 evt.msg.multi.num_seps = num_handles;
602 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_START_REQ_EVT, &evt);
603 }
604 }
605
606 if (result != AVDT_SUCCESS) {
607 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
608 AVDT_TRACE_ERROR("%s: result=%d num_handles=%d invalid", __func__, result,
609 num_handles);
610 } else {
611 AVDT_TRACE_ERROR(
612 "%s: result=%d avdt_handle=%d", __func__, result,
613 (i < num_handles ? p_handles[i] : p_handles[num_handles - 1]));
614 }
615 }
616 return result;
617 }
618
619 /*******************************************************************************
620 *
621 * Function AVDT_SuspendReq
622 *
623 * Description Suspend one or more stream endpoints. This suspends the
624 * transfer of media packets for the streams. All stream
625 * endpoints must previously be open and started. When the
626 * streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to
627 * the application via the control callback function for
628 * each stream.
629 *
630 *
631 * Returns AVDT_SUCCESS if successful, otherwise error.
632 *
633 ******************************************************************************/
AVDT_SuspendReq(uint8_t * p_handles,uint8_t num_handles)634 uint16_t AVDT_SuspendReq(uint8_t* p_handles, uint8_t num_handles) {
635 AvdtpScb* p_scb = NULL;
636 tAVDT_CCB_EVT evt;
637 uint16_t result = AVDT_SUCCESS;
638 int i;
639
640 AVDT_TRACE_DEBUG("%s: num_handles=%d", __func__, num_handles);
641
642 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
643 result = AVDT_BAD_PARAMS;
644 } else {
645 /* verify handles */
646 for (i = 0; i < num_handles; i++) {
647 p_scb = avdt_scb_by_hdl(p_handles[i]);
648 if (p_scb == NULL) {
649 result = AVDT_BAD_HANDLE;
650 break;
651 }
652 }
653 }
654
655 if (result == AVDT_SUCCESS) {
656 if (p_scb->p_ccb == NULL) {
657 result = AVDT_BAD_HANDLE;
658 } else {
659 /* send event to ccb */
660 memcpy(evt.msg.multi.seid_list, p_handles, num_handles);
661 evt.msg.multi.num_seps = num_handles;
662 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_SUSPEND_REQ_EVT, &evt);
663 }
664 }
665
666 if (result != AVDT_SUCCESS) {
667 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) {
668 AVDT_TRACE_ERROR("%s: result=%d num_handles=%d invalid", __func__, result,
669 num_handles);
670 } else {
671 AVDT_TRACE_ERROR(
672 "%s: result=%d avdt_handle=%d", __func__, result,
673 (i < num_handles ? p_handles[i] : p_handles[num_handles - 1]));
674 }
675 }
676 return result;
677 }
678
679 /*******************************************************************************
680 *
681 * Function AVDT_CloseReq
682 *
683 * Description Close a stream endpoint. This stops the transfer of media
684 * packets and closes the transport channel associated with
685 * this stream endpoint. When the stream is closed, an
686 * AVDT_CLOSE_CFM_EVT is sent to the application via the
687 * control callback function for this handle.
688 *
689 *
690 * Returns AVDT_SUCCESS if successful, otherwise error.
691 *
692 ******************************************************************************/
AVDT_CloseReq(uint8_t handle)693 uint16_t AVDT_CloseReq(uint8_t handle) {
694 AvdtpScb* p_scb;
695 uint16_t result = AVDT_SUCCESS;
696
697 AVDT_TRACE_API("%s: avdt_handle=%d", __func__, handle);
698
699 /* map handle to scb */
700 p_scb = avdt_scb_by_hdl(handle);
701 if (p_scb == NULL) {
702 result = AVDT_BAD_HANDLE;
703 } else
704 /* send event to scb */
705 {
706 avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_REQ_EVT, NULL);
707 }
708
709 if (result != AVDT_SUCCESS) {
710 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
711 }
712 return result;
713 }
714
715 /*******************************************************************************
716 *
717 * Function AVDT_ReconfigReq
718 *
719 * Description Reconfigure a stream endpoint. This allows the application
720 * to change the codec or content protection capabilities of
721 * a stream endpoint after it has been opened. This function
722 * can only be called if the stream is opened but not started
723 * or if the stream has been suspended. When the procedure
724 * is completed, an AVDT_RECONFIG_CFM_EVT is sent to the
725 * application via the control callback function for this
726 * handle.
727 *
728 *
729 * Returns AVDT_SUCCESS if successful, otherwise error.
730 *
731 ******************************************************************************/
AVDT_ReconfigReq(uint8_t handle,AvdtpSepConfig * p_cfg)732 uint16_t AVDT_ReconfigReq(uint8_t handle, AvdtpSepConfig* p_cfg) {
733 AvdtpScb* p_scb;
734 uint16_t result = AVDT_SUCCESS;
735 tAVDT_SCB_EVT evt;
736
737 AVDT_TRACE_DEBUG("%s: avdt_handle=%d", __func__, handle);
738
739 /* map handle to scb */
740 p_scb = avdt_scb_by_hdl(handle);
741 if (p_scb == NULL) {
742 result = AVDT_BAD_HANDLE;
743 }
744 /* send event to scb */
745 else {
746 /* force psc_mask to zero */
747 p_cfg->psc_mask = 0;
748 evt.msg.reconfig_cmd.p_cfg = p_cfg;
749 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_REQ_EVT, &evt);
750 }
751
752 if (result != AVDT_SUCCESS) {
753 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
754 }
755 return result;
756 }
757
758 /*******************************************************************************
759 *
760 * Function AVDT_ReconfigRsp
761 *
762 * Description Respond to a reconfigure request from the peer device.
763 * This function must be called if the application receives
764 * an AVDT_RECONFIG_IND_EVT through its control callback.
765 *
766 *
767 * Returns AVDT_SUCCESS if successful, otherwise error.
768 *
769 ******************************************************************************/
AVDT_ReconfigRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t category)770 uint16_t AVDT_ReconfigRsp(uint8_t handle, uint8_t label, uint8_t error_code,
771 uint8_t category) {
772 AvdtpScb* p_scb;
773 tAVDT_SCB_EVT evt;
774 uint16_t result = AVDT_SUCCESS;
775
776 AVDT_TRACE_DEBUG("%s: avdt_handle=%d label=%d error_code=0x%x category=%d",
777 __func__, handle, label, error_code, category);
778
779 /* map handle to scb */
780 p_scb = avdt_scb_by_hdl(handle);
781 if (p_scb == NULL) {
782 result = AVDT_BAD_HANDLE;
783 }
784 /* send event to scb */
785 else {
786 evt.msg.hdr.err_code = error_code;
787 evt.msg.hdr.err_param = category;
788 evt.msg.hdr.label = label;
789 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, &evt);
790 }
791
792 if (result != AVDT_SUCCESS) {
793 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
794 }
795 return result;
796 }
797
798 /*******************************************************************************
799 *
800 * Function AVDT_SecurityReq
801 *
802 * Description Send a security request to the peer device. When the
803 * security procedure is completed, an AVDT_SECURITY_CFM_EVT
804 * is sent to the application via the control callback function
805 * for this handle. (Please note that AVDTP security
806 * procedures are unrelated to Bluetooth link level security.)
807 *
808 *
809 * Returns AVDT_SUCCESS if successful, otherwise error.
810 *
811 ******************************************************************************/
AVDT_SecurityReq(uint8_t handle,uint8_t * p_data,uint16_t len)812 uint16_t AVDT_SecurityReq(uint8_t handle, uint8_t* p_data, uint16_t len) {
813 AvdtpScb* p_scb;
814 uint16_t result = AVDT_SUCCESS;
815 tAVDT_SCB_EVT evt;
816
817 AVDT_TRACE_DEBUG("%s: avdt_handle=%d len=%d", __func__, handle, len);
818
819 /* map handle to scb */
820 p_scb = avdt_scb_by_hdl(handle);
821 if (p_scb == NULL) {
822 result = AVDT_BAD_HANDLE;
823 }
824 /* send event to scb */
825 else {
826 evt.msg.security_rsp.p_data = p_data;
827 evt.msg.security_rsp.len = len;
828 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_REQ_EVT, &evt);
829 }
830
831 if (result != AVDT_SUCCESS) {
832 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
833 }
834 return result;
835 }
836
837 /*******************************************************************************
838 *
839 * Function AVDT_SecurityRsp
840 *
841 * Description Respond to a security request from the peer device.
842 * This function must be called if the application receives
843 * an AVDT_SECURITY_IND_EVT through its control callback.
844 * (Please note that AVDTP security procedures are unrelated
845 * to Bluetooth link level security.)
846 *
847 *
848 * Returns AVDT_SUCCESS if successful, otherwise error.
849 *
850 ******************************************************************************/
AVDT_SecurityRsp(uint8_t handle,uint8_t label,uint8_t error_code,uint8_t * p_data,uint16_t len)851 uint16_t AVDT_SecurityRsp(uint8_t handle, uint8_t label, uint8_t error_code,
852 uint8_t* p_data, uint16_t len) {
853 AvdtpScb* p_scb;
854 uint16_t result = AVDT_SUCCESS;
855 tAVDT_SCB_EVT evt;
856
857 AVDT_TRACE_DEBUG("%s: avdt_handle=%d label=%d error_code=0x%x len=%d",
858 __func__, handle, label, error_code, len);
859
860 /* map handle to scb */
861 p_scb = avdt_scb_by_hdl(handle);
862 if (p_scb == NULL) {
863 result = AVDT_BAD_HANDLE;
864 }
865 /* send event to scb */
866 else {
867 evt.msg.security_rsp.hdr.err_code = error_code;
868 evt.msg.security_rsp.hdr.label = label;
869 evt.msg.security_rsp.p_data = p_data;
870 evt.msg.security_rsp.len = len;
871 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, &evt);
872 }
873
874 if (result != AVDT_SUCCESS) {
875 AVDT_TRACE_ERROR("%s: result=%d avdt_handle=%d", __func__, result, handle);
876 }
877 return result;
878 }
879
880 /*******************************************************************************
881 *
882 * Function AVDT_WriteReqOpt
883 *
884 * Description Send a media packet to the peer device. The stream must
885 * be started before this function is called. Also, this
886 * function can only be called if the stream is a SRC.
887 *
888 * When AVDTP has sent the media packet and is ready for the
889 * next packet, an AVDT_WRITE_CFM_EVT is sent to the
890 * application via the control callback. The application must
891 * wait for the AVDT_WRITE_CFM_EVT before it makes the next
892 * call to AVDT_WriteReq(). If the applications calls
893 * AVDT_WriteReq() before it receives the event the packet
894 * will not be sent. The application may make its first call
895 * to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
896 * or AVDT_START_IND_EVT.
897 *
898 * The application passes the packet using the BT_HDR
899 * structure.
900 * This structure is described in section 2.1. The offset
901 * field must be equal to or greater than AVDT_MEDIA_OFFSET
902 * (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used).
903 * This allows enough space in the buffer for the L2CAP and
904 * AVDTP headers.
905 *
906 * The memory pointed to by p_pkt must be a GKI buffer
907 * allocated by the application. This buffer will be freed
908 * by the protocol stack; the application must not free
909 * this buffer.
910 *
911 * The opt parameter allows passing specific options like:
912 * - NO_RTP : do not add the RTP header to buffer
913 *
914 * Returns AVDT_SUCCESS if successful, otherwise error.
915 *
916 ******************************************************************************/
AVDT_WriteReqOpt(uint8_t handle,BT_HDR * p_pkt,uint32_t time_stamp,uint8_t m_pt,tAVDT_DATA_OPT_MASK opt)917 uint16_t AVDT_WriteReqOpt(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
918 uint8_t m_pt, tAVDT_DATA_OPT_MASK opt) {
919 AvdtpScb* p_scb;
920 tAVDT_SCB_EVT evt;
921 uint16_t result = AVDT_SUCCESS;
922
923 AVDT_TRACE_DEBUG("%s: avdt_handle=%d timestamp=%d m_pt=0x%x opt=0x%x",
924 __func__, handle, time_stamp, m_pt, opt);
925
926 /* map handle to scb */
927 p_scb = avdt_scb_by_hdl(handle);
928 if (p_scb == NULL) {
929 result = AVDT_BAD_HANDLE;
930 } else {
931 evt.apiwrite.p_buf = p_pkt;
932 evt.apiwrite.time_stamp = time_stamp;
933 evt.apiwrite.m_pt = m_pt;
934 evt.apiwrite.opt = opt;
935 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt);
936 }
937
938 AVDT_TRACE_DEBUG("%s: result=%d avdt_handle=%d", __func__, result, handle);
939 return result;
940 }
941
942 /*******************************************************************************
943 *
944 * Function AVDT_WriteReq
945 *
946 * Description Send a media packet to the peer device. The stream must
947 * be started before this function is called. Also, this
948 * function can only be called if the stream is a SRC.
949 *
950 * When AVDTP has sent the media packet and is ready for the
951 * next packet, an AVDT_WRITE_CFM_EVT is sent to the
952 * application via the control callback. The application must
953 * wait for the AVDT_WRITE_CFM_EVT before it makes the next
954 * call to AVDT_WriteReq(). If the applications calls
955 * AVDT_WriteReq() before it receives the event the packet
956 * will not be sent. The application may make its first call
957 * to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT
958 * or AVDT_START_IND_EVT.
959 *
960 * The application passes the packet using the BT_HDR
961 * structure.
962 * This structure is described in section 2.1. The offset
963 * field must be equal to or greater than AVDT_MEDIA_OFFSET.
964 * This allows enough space in the buffer for the L2CAP and
965 * AVDTP headers.
966 *
967 * The memory pointed to by p_pkt must be a GKI buffer
968 * allocated by the application. This buffer will be freed
969 * by the protocol stack; the application must not free
970 * this buffer.
971 *
972 *
973 * Returns AVDT_SUCCESS if successful, otherwise error.
974 *
975 ******************************************************************************/
AVDT_WriteReq(uint8_t handle,BT_HDR * p_pkt,uint32_t time_stamp,uint8_t m_pt)976 uint16_t AVDT_WriteReq(uint8_t handle, BT_HDR* p_pkt, uint32_t time_stamp,
977 uint8_t m_pt) {
978 return AVDT_WriteReqOpt(handle, p_pkt, time_stamp, m_pt, AVDT_DATA_OPT_NONE);
979 }
980
981 /*******************************************************************************
982 *
983 * Function AVDT_ConnectReq
984 *
985 * Description This function initiates an AVDTP signaling connection
986 * to the peer device. When the connection is completed, an
987 * AVDT_CONNECT_IND_EVT is sent to the application via its
988 * control callback function. If the connection attempt fails
989 * an AVDT_DISCONNECT_IND_EVT is sent. The security mask
990 * parameter overrides the outgoing security mask set in
991 * AVDT_Register().
992 *
993 * Returns AVDT_SUCCESS if successful, otherwise error.
994 *
995 ******************************************************************************/
AVDT_ConnectReq(const RawAddress & bd_addr,uint8_t channel_index,uint8_t sec_mask,tAVDT_CTRL_CBACK * p_cback)996 uint16_t AVDT_ConnectReq(const RawAddress& bd_addr, uint8_t channel_index,
997 uint8_t sec_mask, tAVDT_CTRL_CBACK* p_cback) {
998 AvdtpCcb* p_ccb = NULL;
999 uint16_t result = AVDT_SUCCESS;
1000 tAVDT_CCB_EVT evt;
1001
1002 AVDT_TRACE_WARNING("%s: address=%s channel_index=%d sec_mask=0x%x", __func__,
1003 bd_addr.ToString().c_str(), channel_index, sec_mask);
1004
1005 /* find channel control block for this bd addr; if none, allocate one */
1006 p_ccb = avdt_ccb_by_bd(bd_addr);
1007 if (p_ccb == NULL) {
1008 p_ccb = avdt_ccb_alloc_by_channel_index(bd_addr, channel_index);
1009 if (p_ccb == NULL) {
1010 /* could not allocate channel control block */
1011 result = AVDT_NO_RESOURCES;
1012 }
1013 } else if (!p_ccb->ll_opened) {
1014 AVDT_TRACE_WARNING("AVDT_ConnectReq: CCB LL is in the middle of opening");
1015
1016 /* ccb was already allocated for the incoming signalling. */
1017 result = AVDT_BUSY;
1018 }
1019
1020 if (result == AVDT_SUCCESS) {
1021 /* send event to ccb */
1022 evt.connect.p_cback = p_cback;
1023 evt.connect.sec_mask = sec_mask;
1024 avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt);
1025 }
1026
1027 AVDT_TRACE_WARNING("%s: address=%s result=%d", __func__,
1028 bd_addr.ToString().c_str(), result);
1029
1030 return result;
1031 }
1032
1033 /*******************************************************************************
1034 *
1035 * Function AVDT_DisconnectReq
1036 *
1037 * Description This function disconnect an AVDTP signaling connection
1038 * to the peer device. When disconnected an
1039 * AVDT_DISCONNECT_IND_EVT is sent to the application via its
1040 * control callback function.
1041 *
1042 * Returns AVDT_SUCCESS if successful, otherwise error.
1043 *
1044 ******************************************************************************/
AVDT_DisconnectReq(const RawAddress & bd_addr,tAVDT_CTRL_CBACK * p_cback)1045 uint16_t AVDT_DisconnectReq(const RawAddress& bd_addr,
1046 tAVDT_CTRL_CBACK* p_cback) {
1047 AvdtpCcb* p_ccb = NULL;
1048 uint16_t result = AVDT_SUCCESS;
1049 tAVDT_CCB_EVT evt;
1050
1051 AVDT_TRACE_WARNING("%s: address=%s", __func__, bd_addr.ToString().c_str());
1052
1053 /* find channel control block for this bd addr; if none, error */
1054 p_ccb = avdt_ccb_by_bd(bd_addr);
1055 if (p_ccb == NULL) {
1056 result = AVDT_BAD_PARAMS;
1057 }
1058
1059 if (result == AVDT_SUCCESS) {
1060 /* send event to ccb */
1061 evt.disconnect.p_cback = p_cback;
1062 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt);
1063 } else {
1064 AVDT_TRACE_ERROR("%s: address=%s result=%d", __func__,
1065 bd_addr.ToString().c_str(), result);
1066 }
1067
1068 return result;
1069 }
1070
1071 /*******************************************************************************
1072 *
1073 * Function AVDT_GetL2CapChannel
1074 *
1075 * Description Get the L2CAP CID used by the handle.
1076 *
1077 * Returns CID if successful, otherwise 0.
1078 *
1079 ******************************************************************************/
AVDT_GetL2CapChannel(uint8_t handle)1080 uint16_t AVDT_GetL2CapChannel(uint8_t handle) {
1081 AvdtpScb* p_scb;
1082 AvdtpCcb* p_ccb;
1083 uint8_t tcid;
1084 uint16_t lcid = 0;
1085
1086 /* map handle to scb */
1087 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) &&
1088 ((p_ccb = p_scb->p_ccb) != NULL)) {
1089 /* get tcid from type, scb */
1090 tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb);
1091
1092 lcid = avdtp_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid;
1093 }
1094
1095 return (lcid);
1096 }
1097
1098 /*******************************************************************************
1099 *
1100 * Function AVDT_SendReport
1101 *
1102 * Description
1103 *
1104 *
1105 *
1106 * Returns
1107 *
1108 ******************************************************************************/
AVDT_SendReport(uint8_t handle,AVDT_REPORT_TYPE type,tAVDT_REPORT_DATA * p_data)1109 uint16_t AVDT_SendReport(uint8_t handle, AVDT_REPORT_TYPE type,
1110 tAVDT_REPORT_DATA* p_data) {
1111 AvdtpScb* p_scb;
1112 uint16_t result = AVDT_BAD_PARAMS;
1113 AvdtpTransportChannel* p_tbl;
1114 uint8_t *p, *plen, *pm1, *p_end;
1115 uint32_t ssrc;
1116 uint16_t len;
1117
1118 AVDT_TRACE_DEBUG("%s: avdt_handle=%d type=%d", __func__, handle, type);
1119
1120 /* map handle to scb && verify parameters */
1121 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) && (p_scb->p_ccb != NULL) &&
1122 (((type == AVDT_RTCP_PT_SR) &&
1123 (p_scb->stream_config.tsep == AVDT_TSEP_SRC)) ||
1124 ((type == AVDT_RTCP_PT_RR) &&
1125 (p_scb->stream_config.tsep == AVDT_TSEP_SNK)) ||
1126 (type == AVDT_RTCP_PT_SDES))) {
1127 result = AVDT_NO_RESOURCES;
1128
1129 /* build SR - assume fit in one packet */
1130 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb);
1131 if (p_tbl->state == AVDT_AD_ST_OPEN) {
1132 BT_HDR* p_pkt = (BT_HDR*)osi_malloc(p_tbl->peer_mtu + sizeof(BT_HDR));
1133
1134 p_pkt->offset = L2CAP_MIN_OFFSET;
1135 p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1136 pm1 = p;
1137 *p++ = AVDT_MEDIA_OCTET1 | 1;
1138 *p++ = type;
1139 /* save the location for length */
1140 plen = p;
1141 p += 2;
1142 ssrc = avdt_scb_gen_ssrc(p_scb);
1143 UINT32_TO_BE_STREAM(p, ssrc);
1144
1145 switch (type) {
1146 case AVDT_RTCP_PT_SR: /* Sender Report */
1147 *pm1 = AVDT_MEDIA_OCTET1;
1148 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec);
1149 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac);
1150 UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time);
1151 UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count);
1152 UINT32_TO_BE_STREAM(p, p_data->sr.octet_count);
1153 break;
1154
1155 case AVDT_RTCP_PT_RR: /* Receiver Report */
1156 *p++ = p_data->rr.frag_lost;
1157 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1158 p_data->rr.packet_lost &= 0xFFFFFF;
1159 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost);
1160 UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost);
1161 UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd);
1162 UINT32_TO_BE_STREAM(p, p_data->rr.jitter);
1163 UINT32_TO_BE_STREAM(p, p_data->rr.lsr);
1164 UINT32_TO_BE_STREAM(p, p_data->rr.dlsr);
1165 break;
1166
1167 case AVDT_RTCP_PT_SDES: /* Source Description */
1168 *p++ = AVDT_RTCP_SDES_CNAME;
1169 len = strlen((char*)p_data->cname);
1170 if (len > AVDT_MAX_CNAME_SIZE) len = AVDT_MAX_CNAME_SIZE;
1171 *p++ = (uint8_t)len;
1172 strlcpy((char*)p, (char*)p_data->cname, len + 1);
1173 p += len;
1174 break;
1175 }
1176 p_end = p;
1177 len = p - pm1 - 1;
1178 UINT16_TO_BE_STREAM(plen, len);
1179
1180 /* set the actual payload length */
1181 p_pkt->len = p_end - p;
1182 /* send the packet */
1183 if (L2CAP_DW_FAILED !=
1184 avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt))
1185 result = AVDT_SUCCESS;
1186 }
1187 }
1188
1189 if (result != AVDT_SUCCESS) {
1190 AVDT_TRACE_WARNING("%s: result=%d avdt_handle=%d", __func__, result,
1191 handle);
1192 }
1193
1194 return result;
1195 }
1196
1197 /******************************************************************************
1198 *
1199 * Function AVDT_SetTraceLevel
1200 *
1201 * Description Sets the trace level for AVDT. If 0xff is passed, the
1202 * current trace level is returned.
1203 *
1204 * Input Parameters:
1205 * new_level: The level to set the AVDT tracing to:
1206 * 0xff-returns the current setting.
1207 * 0-turns off tracing.
1208 * >= 1-Errors.
1209 * >= 2-Warnings.
1210 * >= 3-APIs.
1211 * >= 4-Events.
1212 * >= 5-Debug.
1213 *
1214 * Returns The new trace level or current trace level if
1215 * the input parameter is 0xff.
1216 *
1217 *****************************************************************************/
AVDT_SetTraceLevel(uint8_t new_level)1218 uint8_t AVDT_SetTraceLevel(uint8_t new_level) {
1219 if (new_level != 0xFF) avdtp_cb.SetTraceLevel(new_level);
1220
1221 return avdtp_cb.TraceLevel();
1222 }
1223
stack_debug_avdtp_api_dump(int fd)1224 void stack_debug_avdtp_api_dump(int fd) {
1225 if (appl_trace_level < BT_TRACE_LEVEL_DEBUG) return;
1226
1227 dprintf(fd, "\nAVDTP Stack State:\n");
1228 dprintf(fd, " AVDTP signalling L2CAP channel MTU: %d\n",
1229 avdtp_cb.rcb.ctrl_mtu);
1230 dprintf(fd, " Security mask: 0x%x\n", avdtp_cb.rcb.sec_mask);
1231
1232 for (size_t i = 0; i < AVDT_NUM_LINKS; i++) {
1233 const AvdtpCcb& ccb = avdtp_cb.ccb[i];
1234 if (ccb.peer_addr.IsEmpty()) {
1235 continue;
1236 }
1237 dprintf(fd, "\n Channel control block: %zu peer: %s\n", i,
1238 ccb.peer_addr.ToString().c_str());
1239 dprintf(fd, " Allocated: %s\n", ccb.allocated ? "true" : "false");
1240 dprintf(fd, " State: %d\n", ccb.state);
1241 dprintf(fd, " Link-layer opened: %s\n",
1242 ccb.ll_opened ? "true" : "false");
1243 dprintf(fd, " Discover in progress: %s\n",
1244 ccb.proc_busy ? "true" : "false");
1245 dprintf(fd, " Congested: %s\n", ccb.cong ? "true" : "false");
1246 dprintf(fd, " Reinitiate connection on idle: %s\n",
1247 ccb.reconn ? "true" : "false");
1248 dprintf(fd, " Command retransmission count: %d\n", ccb.ret_count);
1249 dprintf(fd, " BTA AV SCB index: %d\n", ccb.BtaAvScbIndex());
1250
1251 for (size_t i = 0; i < AVDT_NUM_SEPS; i++) {
1252 const AvdtpScb& scb = ccb.scb[i];
1253 if (!scb.in_use) {
1254 continue;
1255 }
1256 dprintf(fd, "\n Stream control block: %zu\n", i);
1257 dprintf(fd, " SEP codec: %s\n",
1258 A2DP_CodecName(scb.stream_config.cfg.codec_info));
1259 dprintf(fd, " SEP protocol service capabilities: 0x%x\n",
1260 scb.stream_config.cfg.psc_mask);
1261 dprintf(fd, " SEP type: 0x%x\n", scb.stream_config.tsep);
1262 dprintf(fd, " Media type: 0x%x\n", scb.stream_config.media_type);
1263 dprintf(fd, " MTU: %d\n", scb.stream_config.mtu);
1264 dprintf(fd, " AVDT SCB handle: %d\n", scb.ScbHandle());
1265 dprintf(fd, " SCB index: %d\n", scb.stream_config.scb_index);
1266 dprintf(fd, " Configured codec: %s\n",
1267 A2DP_CodecName(scb.curr_cfg.codec_info));
1268 dprintf(fd, " Requested codec: %s\n",
1269 A2DP_CodecName(scb.req_cfg.codec_info));
1270 dprintf(fd, " Transport channel connect timer: %s\n",
1271 alarm_is_scheduled(scb.transport_channel_timer)
1272 ? "Scheduled"
1273 : "Not scheduled");
1274 dprintf(fd, " Channel control block peer: %s\n",
1275 (scb.p_ccb != nullptr) ? scb.p_ccb->peer_addr.ToString().c_str()
1276 : "null");
1277 dprintf(fd, " Allocated: %s\n", scb.allocated ? "true" : "false");
1278 dprintf(fd, " In use: %s\n", scb.in_use ? "true" : "false");
1279 dprintf(fd, " Role: 0x%x\n", scb.role);
1280 dprintf(fd, " Remove: %s\n", scb.remove ? "true" : "false");
1281 dprintf(fd, " State: %d\n", scb.state);
1282 dprintf(fd, " Peer SEID: %d\n", scb.peer_seid);
1283 dprintf(fd, " Current event: %d\n", scb.curr_evt);
1284 dprintf(fd, " Congested: %s\n", scb.cong ? "true" : "false");
1285 dprintf(fd, " Close response code: %d\n", scb.close_code);
1286 }
1287 }
1288 }
1289