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