• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2003-2016 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 control transport protocol.
22  *
23  ******************************************************************************/
24 
25 #include "avct_api.h"
26 
27 #include <string.h>
28 
29 #include "avct_int.h"
30 #include "bt_target.h"
31 #include "bta/include/bta_api.h"
32 #include "btm_api.h"
33 #include "l2c_api.h"
34 #include "l2cdefs.h"
35 #include "osi/include/allocator.h"
36 #include "osi/include/osi.h"
37 #include "stack/btm/btm_sec.h"
38 #include "stack/include/bt_hdr.h"
39 #include "types/raw_address.h"
40 
41 /* Control block for AVCT */
42 tAVCT_CB avct_cb;
43 uint8_t avct_trace_level = AVCT_INITIAL_TRACE_LEVEL;
44 
45 /*******************************************************************************
46  *
47  * Function         AVCT_Register
48  *
49  * Description      This is the system level registration function for the
50  *                  AVCTP protocol.  This function initializes AVCTP and
51  *                  prepares the protocol stack for its use.  This function
52  *                  must be called once by the system or platform using AVCTP
53  *                  before the other functions of the API an be used.
54  *
55  *
56  * Returns          void
57  *
58  ******************************************************************************/
AVCT_Register()59 void AVCT_Register() {
60   AVCT_TRACE_API("AVCT_Register");
61 
62   /* initialize AVCTP data structures */
63   memset(&avct_cb, 0, sizeof(tAVCT_CB));
64 
65   /* register PSM with L2CAP */
66   L2CA_Register2(AVCT_PSM, avct_l2c_appl, true /* enable_snoop */, nullptr,
67                  kAvrcMtu, 0, BTA_SEC_AUTHENTICATE);
68 
69   /* Include the browsing channel which uses eFCR */
70   tL2CAP_ERTM_INFO ertm_info;
71   ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE;
72 
73   L2CA_Register2(AVCT_BR_PSM, avct_l2c_br_appl, true /*enable_snoop*/,
74                  &ertm_info, kAvrcBrMtu, AVCT_MIN_BROWSE_MTU,
75                  BTA_SEC_AUTHENTICATE);
76 
77   avct_cb.trace_level = avct_trace_level;
78 }
79 
80 /*******************************************************************************
81  *
82  * Function         AVCT_Deregister
83  *
84  * Description      This function is called to deregister use AVCTP protocol.
85  *                  It is called when AVCTP is no longer being used by any
86  *                  application in the system.  Before this function can be
87  *                  called, all connections must be removed with
88  *                  AVCT_RemoveConn().
89  *
90  *
91  * Returns          void
92  *
93  ******************************************************************************/
AVCT_Deregister(void)94 void AVCT_Deregister(void) {
95   AVCT_TRACE_API("AVCT_Deregister");
96 
97   /* deregister PSM with L2CAP */
98   L2CA_Deregister(AVCT_PSM);
99 }
100 
101 /*******************************************************************************
102  *
103  * Function         AVCT_CreateConn
104  *
105  * Description      Create an AVCTP connection.  There are two types of
106  *                  connections, initiator and acceptor, as determined by
107  *                  the p_cc->role parameter.  When this function is called to
108  *                  create an initiator connection, an AVCTP connection to
109  *                  the peer device is initiated if one does not already exist.
110  *                  If an acceptor connection is created, the connection waits
111  *                  passively for an incoming AVCTP connection from a peer
112  *                  device.
113  *
114  *
115  * Returns          AVCT_SUCCESS if successful, otherwise error.
116  *
117  ******************************************************************************/
AVCT_CreateConn(uint8_t * p_handle,tAVCT_CC * p_cc,const RawAddress & peer_addr)118 uint16_t AVCT_CreateConn(uint8_t* p_handle, tAVCT_CC* p_cc,
119                          const RawAddress& peer_addr) {
120   uint16_t result = AVCT_SUCCESS;
121   tAVCT_CCB* p_ccb;
122   tAVCT_LCB* p_lcb;
123 
124   AVCT_TRACE_API("AVCT_CreateConn: %d, control:%d", p_cc->role, p_cc->control);
125 
126   /* Allocate ccb; if no ccbs, return failure */
127   p_ccb = avct_ccb_alloc(p_cc);
128   if (p_ccb == NULL) {
129     result = AVCT_NO_RESOURCES;
130   } else {
131     /* get handle */
132     *p_handle = avct_ccb_to_idx(p_ccb);
133 
134     /* if initiator connection */
135     if (p_cc->role == AVCT_INT) {
136       /* find link; if none allocate a new one */
137       p_lcb = avct_lcb_by_bd(peer_addr);
138       if (p_lcb == NULL) {
139         p_lcb = avct_lcb_alloc(peer_addr);
140         if (p_lcb == NULL) {
141           /* no link resources; free ccb as well */
142           avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
143           result = AVCT_NO_RESOURCES;
144         }
145       }
146       /* check if PID already in use */
147       else if (avct_lcb_has_pid(p_lcb, p_cc->pid)) {
148         avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
149         result = AVCT_PID_IN_USE;
150       }
151 
152       if (result == AVCT_SUCCESS) {
153         /* bind lcb to ccb */
154         p_ccb->p_lcb = p_lcb;
155         AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
156         tAVCT_LCB_EVT avct_lcb_evt;
157         avct_lcb_evt.p_ccb = p_ccb;
158         avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
159       }
160     }
161   }
162   return result;
163 }
164 
165 /*******************************************************************************
166  *
167  * Function         AVCT_RemoveConn
168  *
169  * Description      Remove an AVCTP connection.  This function is called when
170  *                  the application is no longer using a connection.  If this
171  *                  is the last connection to a peer the L2CAP channel for AVCTP
172  *                  will be closed.
173  *
174  *
175  * Returns          AVCT_SUCCESS if successful, otherwise error.
176  *
177  ******************************************************************************/
AVCT_RemoveConn(uint8_t handle)178 uint16_t AVCT_RemoveConn(uint8_t handle) {
179   uint16_t result = AVCT_SUCCESS;
180   tAVCT_CCB* p_ccb;
181 
182   AVCT_TRACE_API("AVCT_RemoveConn");
183 
184   /* map handle to ccb */
185   p_ccb = avct_ccb_by_idx(handle);
186   if (p_ccb == NULL) {
187     result = AVCT_BAD_HANDLE;
188   }
189   /* if connection not bound to lcb, dealloc */
190   else if (p_ccb->p_lcb == NULL) {
191     avct_ccb_dealloc(p_ccb, AVCT_NO_EVT, 0, NULL);
192   }
193   /* send unbind event to lcb */
194   else {
195     tAVCT_LCB_EVT avct_lcb_evt;
196     avct_lcb_evt.p_ccb = p_ccb;
197     avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
198   }
199   return result;
200 }
201 
202 /*******************************************************************************
203  *
204  * Function         AVCT_CreateBrowse
205  *
206  * Description      Create an AVCTP Browse channel.  There are two types of
207  *                  connections, initiator and acceptor, as determined by
208  *                  the role parameter.  When this function is called to
209  *                  create an initiator connection, the Browse channel to
210  *                  the peer device is initiated if one does not already exist.
211  *                  If an acceptor connection is created, the connection waits
212  *                  passively for an incoming AVCTP connection from a peer
213  *                  device.
214  *
215  *
216  * Returns          AVCT_SUCCESS if successful, otherwise error.
217  *
218  ******************************************************************************/
AVCT_CreateBrowse(uint8_t handle,uint8_t role)219 uint16_t AVCT_CreateBrowse(uint8_t handle, uint8_t role) {
220   uint16_t result = AVCT_SUCCESS;
221   tAVCT_CCB* p_ccb;
222   tAVCT_BCB* p_bcb;
223   int index;
224 
225   AVCT_TRACE_API("AVCT_CreateBrowse: %d", role);
226 
227   /* map handle to ccb */
228   p_ccb = avct_ccb_by_idx(handle);
229   if (p_ccb == NULL) {
230     return AVCT_BAD_HANDLE;
231   } else {
232     /* mark this CCB as supporting browsing channel */
233     if ((p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
234       p_ccb->allocated |= AVCT_ALOC_BCB;
235     }
236   }
237 
238   /* if initiator connection */
239   if (role == AVCT_INT) {
240     /* the link control block must exist before this function is called as INT.
241      */
242     if ((p_ccb->p_lcb == NULL) || (p_ccb->p_lcb->allocated == 0)) {
243       result = AVCT_NOT_OPEN;
244     } else {
245       /* find link; if none allocate a new one */
246       index = p_ccb->p_lcb->allocated;
247       if (index > AVCT_NUM_LINKS) {
248         result = AVCT_BAD_HANDLE;
249       } else {
250         p_bcb = &avct_cb.bcb[index - 1];
251         p_bcb->allocated = index;
252       }
253     }
254 
255     if (result == AVCT_SUCCESS) {
256       /* bind bcb to ccb */
257       p_ccb->p_bcb = p_bcb;
258       p_bcb->peer_addr = p_ccb->p_lcb->peer_addr;
259       AVCT_TRACE_DEBUG("ch_state: %d", p_bcb->ch_state);
260       tAVCT_LCB_EVT avct_lcb_evt;
261       avct_lcb_evt.p_ccb = p_ccb;
262       avct_bcb_event(p_bcb, AVCT_LCB_UL_BIND_EVT, &avct_lcb_evt);
263     }
264   }
265 
266   return result;
267 }
268 
269 /*******************************************************************************
270  *
271  * Function         AVCT_RemoveBrowse
272  *
273  * Description      Remove an AVCTP Browse channel.  This function is called
274  *                  when the application is no longer using a connection.  If
275  *                  this is the last connection to a peer the L2CAP channel for
276  *                  AVCTP will be closed.
277  *
278  *
279  * Returns          AVCT_SUCCESS if successful, otherwise error.
280  *
281  ******************************************************************************/
AVCT_RemoveBrowse(uint8_t handle)282 uint16_t AVCT_RemoveBrowse(uint8_t handle) {
283   uint16_t result = AVCT_SUCCESS;
284   tAVCT_CCB* p_ccb;
285 
286   AVCT_TRACE_API("AVCT_RemoveBrowse");
287 
288   /* map handle to ccb */
289   p_ccb = avct_ccb_by_idx(handle);
290   if (p_ccb == NULL) {
291     result = AVCT_BAD_HANDLE;
292   } else if (p_ccb->p_bcb != NULL)
293   /* send unbind event to bcb */
294   {
295     tAVCT_LCB_EVT avct_lcb_evt;
296     avct_lcb_evt.p_ccb = p_ccb;
297     avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_UNBIND_EVT, &avct_lcb_evt);
298   }
299 
300   return result;
301 }
302 
303 /*******************************************************************************
304  *
305  * Function         AVCT_GetBrowseMtu
306  *
307  * Description      Get the peer_mtu for the AVCTP Browse channel of the given
308  *                  connection.
309  *
310  * Returns          the peer browsing channel MTU.
311  *
312  ******************************************************************************/
AVCT_GetBrowseMtu(uint8_t handle)313 uint16_t AVCT_GetBrowseMtu(uint8_t handle) {
314   uint16_t peer_mtu = AVCT_MIN_BROWSE_MTU;
315 
316   tAVCT_CCB* p_ccb = avct_ccb_by_idx(handle);
317 
318   if (p_ccb != NULL && p_ccb->p_bcb != NULL) {
319     peer_mtu = p_ccb->p_bcb->peer_mtu;
320   }
321 
322   return peer_mtu;
323 }
324 
325 /*******************************************************************************
326  *
327  * Function         AVCT_GetPeerMtu
328  *
329  * Description      Get the peer_mtu for the AVCTP channel of the given
330  *                  connection.
331  *
332  * Returns          the peer MTU size.
333  *
334  ******************************************************************************/
AVCT_GetPeerMtu(uint8_t handle)335 uint16_t AVCT_GetPeerMtu(uint8_t handle) {
336   uint16_t peer_mtu = L2CAP_DEFAULT_MTU;
337   tAVCT_CCB* p_ccb;
338 
339   /* map handle to ccb */
340   p_ccb = avct_ccb_by_idx(handle);
341   if (p_ccb != NULL) {
342     if (p_ccb->p_lcb) {
343       peer_mtu = p_ccb->p_lcb->peer_mtu;
344     }
345   }
346 
347   return peer_mtu;
348 }
349 
350 /*******************************************************************************
351  *
352  * Function         AVCT_MsgReq
353  *
354  * Description      Send an AVCTP message to a peer device.  In calling
355  *                  AVCT_MsgReq(), the application should keep track of the
356  *                  congestion state of AVCTP as communicated with events
357  *                  AVCT_CONG_IND_EVT and AVCT_UNCONG_IND_EVT.   If the
358  *                  application calls AVCT_MsgReq() when AVCTP is congested
359  *                  the message may be discarded.  The application may make its
360  *                  first call to AVCT_MsgReq() after it receives an
361  *                  AVCT_CONNECT_CFM_EVT or AVCT_CONNECT_IND_EVT on control
362  *                  channel or AVCT_BROWSE_CONN_CFM_EVT or
363  *                  AVCT_BROWSE_CONN_IND_EVT on browsing channel.
364  *
365  *                  p_msg->layer_specific must be set to
366  *                  AVCT_DATA_CTRL for control channel traffic;
367  *                  AVCT_DATA_BROWSE for for browse channel traffic.
368  *
369  * Returns          AVCT_SUCCESS if successful, otherwise error.
370  *
371  ******************************************************************************/
AVCT_MsgReq(uint8_t handle,uint8_t label,uint8_t cr,BT_HDR * p_msg)372 uint16_t AVCT_MsgReq(uint8_t handle, uint8_t label, uint8_t cr, BT_HDR* p_msg) {
373   uint16_t result = AVCT_SUCCESS;
374   tAVCT_CCB* p_ccb;
375   tAVCT_UL_MSG ul_msg;
376 
377   AVCT_TRACE_API("%s", __func__);
378 
379   /* verify p_msg parameter */
380   if (p_msg == NULL) {
381     return AVCT_NO_RESOURCES;
382   }
383   AVCT_TRACE_API("%s len: %d layer_specific: %d", __func__, p_msg->len,
384                  p_msg->layer_specific);
385 
386   /* map handle to ccb */
387   p_ccb = avct_ccb_by_idx(handle);
388   if (p_ccb == NULL) {
389     result = AVCT_BAD_HANDLE;
390     osi_free(p_msg);
391   }
392   /* verify channel is bound to link */
393   else if (p_ccb->p_lcb == NULL) {
394     result = AVCT_NOT_OPEN;
395     osi_free(p_msg);
396   }
397 
398   if (result == AVCT_SUCCESS) {
399     ul_msg.p_buf = p_msg;
400     ul_msg.p_ccb = p_ccb;
401     ul_msg.label = label;
402     ul_msg.cr = cr;
403 
404     /* send msg event to bcb */
405     if (p_msg->layer_specific == AVCT_DATA_BROWSE) {
406       if (p_ccb->p_bcb == NULL && (p_ccb->allocated & AVCT_ALOC_BCB) == 0) {
407         /* BCB channel is not open and not allocated */
408         result = AVCT_BAD_HANDLE;
409         osi_free(p_msg);
410       } else {
411         p_ccb->p_bcb = avct_bcb_by_lcb(p_ccb->p_lcb);
412         tAVCT_LCB_EVT avct_lcb_evt;
413         avct_lcb_evt.ul_msg = ul_msg;
414         avct_bcb_event(p_ccb->p_bcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
415       }
416     }
417     /* send msg event to lcb */
418     else {
419       tAVCT_LCB_EVT avct_lcb_evt;
420       avct_lcb_evt.ul_msg = ul_msg;
421       avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_MSG_EVT, &avct_lcb_evt);
422     }
423   }
424   return result;
425 }
426 
427 /******************************************************************************
428  *
429  * Function         AVCT_SetTraceLevel
430  *
431  * Description      Sets the trace level for AVCT. If 0xff is passed, the
432  *                  current trace level is returned.
433  *
434  *                  Input Parameters:
435  *                      new_level:  The level to set the AVCT tracing to:
436  *                      0xff-returns the current setting.
437  *                      0-turns off tracing.
438  *                      >= 1-Errors.
439  *                      >= 2-Warnings.
440  *                      >= 3-APIs.
441  *                      >= 4-Events.
442  *                      >= 5-Debug.
443  *
444  * Returns          The new trace level or current trace level if
445  *                  the input parameter is 0xff.
446  *
447  *****************************************************************************/
AVCT_SetTraceLevel(uint8_t new_level)448 uint8_t AVCT_SetTraceLevel(uint8_t new_level) {
449   if (new_level != 0xFF) {
450     avct_cb.trace_level = avct_trace_level = new_level;
451   }
452   return avct_trace_level;
453 }
454