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