1 /******************************************************************************
2 *
3 * Copyright 2003-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 the link control state machine and functions which
22 * operate on the link control block.
23 *
24 ******************************************************************************/
25
26 #define LOG_TAG "avctp"
27
28 #include <bluetooth/log.h>
29 #include <string.h>
30
31 #include "avct_api.h"
32 #include "avct_int.h"
33 #include "device/include/device_iot_config.h"
34 #include "internal_include/bt_target.h"
35 #include "os/log.h"
36 #include "osi/include/allocator.h"
37 #include "osi/include/osi.h"
38 #include "types/raw_address.h"
39
40 using namespace bluetooth;
41
42 /*****************************************************************************
43 * state machine constants and types
44 ****************************************************************************/
45
46 /* verbose state strings for trace */
47 const char* const avct_lcb_st_str[] = {"LCB_IDLE_ST", "LCB_OPENING_ST",
48 "LCB_OPEN_ST", "LCB_CLOSING_ST"};
49
50 /* verbose event strings for trace */
51 const char* const avct_lcb_evt_str[] = {
52 "UL_BIND_EVT", "UL_UNBIND_EVT", "UL_MSG_EVT", "INT_CLOSE_EVT",
53 "LL_OPEN_EVT", "LL_CLOSE_EVT", "LL_MSG_EVT", "LL_CONG_EVT"};
54
55 /* lcb state machine states */
56 enum {
57 AVCT_LCB_IDLE_ST,
58 AVCT_LCB_OPENING_ST,
59 AVCT_LCB_OPEN_ST,
60 AVCT_LCB_CLOSING_ST
61 };
62
63 /* state machine action enumeration list */
64 enum {
65 AVCT_LCB_CHNL_OPEN,
66 AVCT_LCB_CHNL_DISC,
67 AVCT_LCB_SEND_MSG,
68 AVCT_LCB_OPEN_IND,
69 AVCT_LCB_OPEN_FAIL,
70 AVCT_LCB_CLOSE_IND,
71 AVCT_LCB_CLOSE_CFM,
72 AVCT_LCB_MSG_IND,
73 AVCT_LCB_CONG_IND,
74 AVCT_LCB_BIND_CONN,
75 AVCT_LCB_BIND_FAIL,
76 AVCT_LCB_UNBIND_DISC,
77 AVCT_LCB_CHK_DISC,
78 AVCT_LCB_DISCARD_MSG,
79 AVCT_LCB_DEALLOC,
80 AVCT_LCB_FREE_MSG_IND,
81 AVCT_LCB_NUM_ACTIONS
82 };
83
84 #define AVCT_LCB_IGNORE AVCT_LCB_NUM_ACTIONS
85
86 /* type for action functions */
87 typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB* p_ccb, tAVCT_LCB_EVT* p_data);
88
89 /* action function list */
90 const tAVCT_LCB_ACTION avct_lcb_action[] = {
91 avct_lcb_chnl_open, avct_lcb_chnl_disc, avct_lcb_send_msg,
92 avct_lcb_open_ind, avct_lcb_open_fail, avct_lcb_close_ind,
93 avct_lcb_close_cfm, avct_lcb_msg_ind, avct_lcb_cong_ind,
94 avct_lcb_bind_conn, avct_lcb_bind_fail, avct_lcb_unbind_disc,
95 avct_lcb_chk_disc, avct_lcb_discard_msg, avct_lcb_dealloc,
96 avct_lcb_free_msg_ind};
97
98 /* state table information */
99 #define AVCT_LCB_ACTIONS 2 /* number of actions */
100 #define AVCT_LCB_NEXT_STATE 2 /* position of next state */
101 #define AVCT_LCB_NUM_COLS 3 /* number of columns in state tables */
102
103 /* state table for idle state */
104 const uint8_t avct_lcb_st_idle[][AVCT_LCB_NUM_COLS] = {
105 /* Event Action 1 Action 2 Next state */
106 /* UL_BIND */ {AVCT_LCB_CHNL_OPEN, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
107 /* UL_UNBIND */ {AVCT_LCB_UNBIND_DISC, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
108 /* UL_MSG */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
109 /* INT_CLOSE */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
110 /* LL_OPEN */ {AVCT_LCB_OPEN_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
111 /* LL_CLOSE */ {AVCT_LCB_CLOSE_IND, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
112 /* LL_MSG */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
113 /* LL_CONG */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST}};
114
115 /* state table for opening state */
116 const uint8_t avct_lcb_st_opening[][AVCT_LCB_NUM_COLS] = {
117 /* Event Action 1 Action 2 Next state */
118 /* UL_BIND */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
119 /* UL_UNBIND */ {AVCT_LCB_UNBIND_DISC, AVCT_LCB_IGNORE,
120 AVCT_LCB_OPENING_ST},
121 /* UL_MSG */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
122 /* INT_CLOSE */ {AVCT_LCB_CHNL_DISC, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
123 /* LL_OPEN */ {AVCT_LCB_OPEN_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
124 /* LL_CLOSE */ {AVCT_LCB_OPEN_FAIL, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
125 /* LL_MSG */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
126 /* LL_CONG */ {AVCT_LCB_CONG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST}};
127
128 /* state table for open state */
129 const uint8_t avct_lcb_st_open[][AVCT_LCB_NUM_COLS] = {
130 /* Event Action 1 Action 2 Next state */
131 /* UL_BIND */ {AVCT_LCB_BIND_CONN, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
132 /* UL_UNBIND */ {AVCT_LCB_CHK_DISC, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
133 /* UL_MSG */ {AVCT_LCB_SEND_MSG, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
134 /* INT_CLOSE */ {AVCT_LCB_CHNL_DISC, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
135 /* LL_OPEN */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
136 /* LL_CLOSE */ {AVCT_LCB_CLOSE_IND, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
137 /* LL_MSG */ {AVCT_LCB_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
138 /* LL_CONG */ {AVCT_LCB_CONG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST}};
139
140 /* state table for closing state */
141 const uint8_t avct_lcb_st_closing[][AVCT_LCB_NUM_COLS] = {
142 /* Event Action 1 Action 2 Next state */
143 /* UL_BIND */ {AVCT_LCB_BIND_FAIL, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
144 /* UL_UNBIND */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
145 /* UL_MSG */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
146 /* INT_CLOSE */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
147 /* LL_OPEN */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
148 /* LL_CLOSE */ {AVCT_LCB_CLOSE_CFM, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
149 /* LL_MSG */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
150 /* LL_CONG */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST}};
151
152 /* type for state table */
153 typedef const uint8_t (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
154
155 /* state table */
156 const tAVCT_LCB_ST_TBL avct_lcb_st_tbl[] = {
157 avct_lcb_st_idle, avct_lcb_st_opening, avct_lcb_st_open,
158 avct_lcb_st_closing};
159
160 /*******************************************************************************
161 *
162 * Function avct_lcb_event
163 *
164 * Description State machine event handling function for lcb
165 *
166 *
167 * Returns Nothing.
168 *
169 ******************************************************************************/
avct_lcb_event(tAVCT_LCB * p_lcb,uint8_t event,tAVCT_LCB_EVT * p_data)170 void avct_lcb_event(tAVCT_LCB* p_lcb, uint8_t event, tAVCT_LCB_EVT* p_data) {
171 tAVCT_LCB_ST_TBL state_table;
172 uint8_t action;
173 int i;
174
175 log::verbose("LCB lcb={} event={} state={}", p_lcb->allocated,
176 avct_lcb_evt_str[event], avct_lcb_st_str[p_lcb->state]);
177
178 /* look up the state table for the current state */
179 state_table = avct_lcb_st_tbl[p_lcb->state];
180
181 if (p_lcb->state == AVCT_LCB_IDLE_ST && event == AVCT_LCB_LL_OPEN_EVT)
182 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(p_lcb->peer_addr,
183 IOT_CONF_KEY_AVRCP_CONN_COUNT);
184
185 /* set next state */
186 p_lcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
187
188 /* execute action functions */
189 for (i = 0; i < AVCT_LCB_ACTIONS; i++) {
190 action = state_table[event][i];
191 if (action != AVCT_LCB_IGNORE) {
192 (*avct_lcb_action[action])(p_lcb, p_data);
193 } else {
194 break;
195 }
196 }
197 }
198
199 /*******************************************************************************
200 *
201 * Function avct_bcb_event
202 *
203 * Description State machine event handling function for lcb
204 *
205 *
206 * Returns Nothing.
207 *
208 ******************************************************************************/
avct_bcb_event(tAVCT_BCB * p_bcb,uint8_t event,tAVCT_LCB_EVT * p_data)209 void avct_bcb_event(tAVCT_BCB* p_bcb, uint8_t event, tAVCT_LCB_EVT* p_data) {
210 tAVCT_LCB_ST_TBL state_table;
211 uint8_t action;
212 int i;
213
214 log::verbose("BCB lcb={} event={} state={}", p_bcb->allocated,
215 avct_lcb_evt_str[event], avct_lcb_st_str[p_bcb->state]);
216
217 /* look up the state table for the current state */
218 state_table = avct_lcb_st_tbl[p_bcb->state];
219
220 /* set next state */
221 p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
222
223 /* execute action functions */
224 for (i = 0; i < AVCT_LCB_ACTIONS; i++) {
225 action = state_table[event][i];
226 if (action != AVCT_LCB_IGNORE) {
227 (*avct_bcb_action[action])(p_bcb, p_data);
228 } else {
229 break;
230 }
231 }
232 }
233
234 /*******************************************************************************
235 *
236 * Function avct_lcb_by_bd
237 *
238 * Description This lookup function finds the lcb for a BD address.
239 *
240 *
241 * Returns pointer to the lcb, or NULL if none found.
242 *
243 ******************************************************************************/
avct_lcb_by_bd(const RawAddress & bd_addr)244 tAVCT_LCB* avct_lcb_by_bd(const RawAddress& bd_addr) {
245 tAVCT_LCB* p_lcb = &avct_cb.lcb[0];
246 int i;
247
248 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
249 /* if allocated lcb has matching lcb */
250 if (p_lcb->allocated && p_lcb->peer_addr == bd_addr) {
251 break;
252 }
253 }
254
255 if (i == AVCT_NUM_LINKS) {
256 /* if no lcb found */
257 p_lcb = NULL;
258
259 log::verbose("No lcb for addr {}", bd_addr);
260 }
261 return p_lcb;
262 }
263
264 /*******************************************************************************
265 *
266 * Function avct_lcb_alloc
267 *
268 * Description Allocate a link control block.
269 *
270 *
271 * Returns pointer to the lcb, or NULL if none could be allocated.
272 *
273 ******************************************************************************/
avct_lcb_alloc(const RawAddress & bd_addr)274 tAVCT_LCB* avct_lcb_alloc(const RawAddress& bd_addr) {
275 tAVCT_LCB* p_lcb = &avct_cb.lcb[0];
276 int i;
277
278 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
279 if (!p_lcb->allocated) {
280 p_lcb->allocated = (uint8_t)(i + 1);
281 p_lcb->peer_addr = bd_addr;
282 log::verbose("avct_lcb_alloc {}", p_lcb->allocated);
283 p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
284 p_lcb->peer_mtu = L2CAP_LE_MIN_MTU;
285 break;
286 }
287 }
288
289 if (i == AVCT_NUM_LINKS) {
290 /* out of lcbs */
291 p_lcb = NULL;
292 log::warn("Out of lcbs");
293 }
294 return p_lcb;
295 }
296
297 /*******************************************************************************
298 *
299 * Function avct_lcb_dealloc
300 *
301 * Description Deallocate a link control block.
302 *
303 *
304 * Returns void.
305 *
306 ******************************************************************************/
avct_lcb_dealloc(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT *)307 void avct_lcb_dealloc(tAVCT_LCB* p_lcb, tAVCT_LCB_EVT* /* p_data */) {
308 log::verbose("allocated: {}", p_lcb->allocated);
309
310 // Check if the LCB is still referenced
311
312 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
313 for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
314 if (p_ccb->allocated && p_ccb->p_lcb == p_lcb) {
315 log::verbose("LCB in use; lcb index: {}", i);
316 return;
317 }
318 }
319
320 // If not, de-allocate now...
321
322 log::verbose("Freeing LCB");
323 osi_free(p_lcb->p_rx_msg);
324 fixed_queue_free(p_lcb->tx_q, NULL);
325 memset(p_lcb, 0, sizeof(tAVCT_LCB));
326 }
327
328 /*******************************************************************************
329 *
330 * Function avct_lcb_by_lcid
331 *
332 * Description Find the LCB associated with the L2CAP LCID
333 *
334 *
335 * Returns pointer to the lcb, or NULL if none found.
336 *
337 ******************************************************************************/
avct_lcb_by_lcid(uint16_t lcid)338 tAVCT_LCB* avct_lcb_by_lcid(uint16_t lcid) {
339 tAVCT_LCB* p_lcb = &avct_cb.lcb[0];
340 int i;
341
342 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
343 if (p_lcb->allocated &&
344 ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid))) {
345 break;
346 }
347 }
348
349 if (i == AVCT_NUM_LINKS) {
350 /* out of lcbs */
351 p_lcb = NULL;
352 log::warn("No lcb for lcid {:x}", lcid);
353 }
354
355 return p_lcb;
356 }
357
358 /*******************************************************************************
359 *
360 * Function avct_lcb_has_pid
361 *
362 * Description See if any ccbs on this lcb have a particular pid.
363 *
364 *
365 * Returns Pointer to CCB if PID found, NULL otherwise.
366 *
367 ******************************************************************************/
avct_lcb_has_pid(tAVCT_LCB * p_lcb,uint16_t pid)368 tAVCT_CCB* avct_lcb_has_pid(tAVCT_LCB* p_lcb, uint16_t pid) {
369 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
370 int i;
371
372 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
373 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid)) {
374 return p_ccb;
375 }
376 }
377 return NULL;
378 }
379
380 /*******************************************************************************
381 *
382 * Function avct_lcb_last_ccb
383 *
384 * Description See if given ccb is only one on the lcb.
385 *
386 *
387 * Returns true if ccb is last, false otherwise.
388 *
389 ******************************************************************************/
avct_lcb_last_ccb(tAVCT_LCB * p_lcb,tAVCT_CCB * p_ccb_last)390 bool avct_lcb_last_ccb(tAVCT_LCB* p_lcb, tAVCT_CCB* p_ccb_last) {
391 tAVCT_CCB* p_ccb = &avct_cb.ccb[0];
392 int i;
393
394 log::warn("avct_lcb_last_ccb");
395 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
396 log::warn("{:x}: aloc:{}, lcb:0x{}/0x{}, ccb:0x{}/0x{}", i,
397 p_ccb->allocated, fmt::ptr(p_ccb->p_lcb), fmt::ptr(p_lcb),
398 fmt::ptr(p_ccb), fmt::ptr(p_ccb_last));
399 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) {
400 return false;
401 }
402 }
403 return true;
404 }
405