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