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