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