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