avdt_ccb.cc revision f33b6f434f086b20fabe5913016bc423ac975057
1/****************************************************************************** 2 * 3 * Copyright (C) 2002-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * This module contains the channel control block state machine and 22 * functions which operate on the channel control block. 23 * 24 ******************************************************************************/ 25 26#include <string.h> 27#include "bt_types.h" 28#include "bt_target.h" 29#include "bt_utils.h" 30#include "avdt_api.h" 31#include "avdtc_api.h" 32#include "avdt_int.h" 33#include "bt_common.h" 34#include "btu.h" 35#include "osi/include/osi.h" 36 37/***************************************************************************** 38** state machine constants and types 39*****************************************************************************/ 40#if (AVDT_DEBUG == TRUE) 41 42/* verbose state strings for trace */ 43const char * const avdt_ccb_st_str[] = { 44 "CCB_IDLE_ST", 45 "CCB_OPENING_ST", 46 "CCB_OPEN_ST", 47 "CCB_CLOSING_ST" 48}; 49 50/* verbose event strings for trace */ 51const char * const avdt_ccb_evt_str[] = { 52 "API_DISCOVER_REQ_EVT", 53 "API_GETCAP_REQ_EVT", 54 "API_START_REQ_EVT", 55 "API_SUSPEND_REQ_EVT", 56 "API_DISCOVER_RSP_EVT", 57 "API_GETCAP_RSP_EVT", 58 "API_START_RSP_EVT", 59 "API_SUSPEND_RSP_EVT", 60 "API_CONNECT_REQ_EVT", 61 "API_DISCONNECT_REQ_EVT", 62 "MSG_DISCOVER_CMD_EVT", 63 "MSG_GETCAP_CMD_EVT", 64 "MSG_START_CMD_EVT", 65 "MSG_SUSPEND_CMD_EVT", 66 "MSG_DISCOVER_RSP_EVT", 67 "MSG_GETCAP_RSP_EVT", 68 "MSG_START_RSP_EVT", 69 "MSG_SUSPEND_RSP_EVT", 70 "RCVRSP_EVT", 71 "SENDMSG_EVT", 72 "RET_TOUT_EVT", 73 "RSP_TOUT_EVT", 74 "IDLE_TOUT_EVT", 75 "UL_OPEN_EVT", 76 "UL_CLOSE_EVT", 77 "LL_OPEN_EVT", 78 "LL_CLOSE_EVT", 79 "LL_CONG_EVT" 80}; 81 82#endif 83 84 85/* action function list */ 86const tAVDT_CCB_ACTION avdt_ccb_action[] = { 87 avdt_ccb_chan_open, 88 avdt_ccb_chan_close, 89 avdt_ccb_chk_close, 90 avdt_ccb_hdl_discover_cmd, 91 avdt_ccb_hdl_discover_rsp, 92 avdt_ccb_hdl_getcap_cmd, 93 avdt_ccb_hdl_getcap_rsp, 94 avdt_ccb_hdl_start_cmd, 95 avdt_ccb_hdl_start_rsp, 96 avdt_ccb_hdl_suspend_cmd, 97 avdt_ccb_hdl_suspend_rsp, 98 avdt_ccb_snd_discover_cmd, 99 avdt_ccb_snd_discover_rsp, 100 avdt_ccb_snd_getcap_cmd, 101 avdt_ccb_snd_getcap_rsp, 102 avdt_ccb_snd_start_cmd, 103 avdt_ccb_snd_start_rsp, 104 avdt_ccb_snd_suspend_cmd, 105 avdt_ccb_snd_suspend_rsp, 106 avdt_ccb_clear_cmds, 107 avdt_ccb_cmd_fail, 108 avdt_ccb_free_cmd, 109 avdt_ccb_cong_state, 110 avdt_ccb_ret_cmd, 111 avdt_ccb_snd_cmd, 112 avdt_ccb_snd_msg, 113 avdt_ccb_set_reconn, 114 avdt_ccb_clr_reconn, 115 avdt_ccb_chk_reconn, 116 avdt_ccb_chk_timer, 117 avdt_ccb_set_conn, 118 avdt_ccb_set_disconn, 119 avdt_ccb_do_disconn, 120 avdt_ccb_ll_closed, 121 avdt_ccb_ll_opened, 122 avdt_ccb_dealloc 123}; 124 125/* state table information */ 126#define AVDT_CCB_ACTIONS 2 /* number of actions */ 127#define AVDT_CCB_NEXT_STATE 2 /* position of next state */ 128#define AVDT_CCB_NUM_COLS 3 /* number of columns in state tables */ 129 130/* state table for idle state */ 131const uint8_t avdt_ccb_st_idle[][AVDT_CCB_NUM_COLS] = { 132/* Event Action 1 Action 2 Next state */ 133/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST}, 134/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST}, 135/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 136/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 137/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 138/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 139/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 140/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 141/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_CHAN_OPEN, AVDT_CCB_OPENING_ST}, 142/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 143/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 144/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 145/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 146/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 147/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 148/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 149/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 150/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 151/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 152/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 153/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 154/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 155/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 156/* UL_OPEN_EVT */ {AVDT_CCB_CHAN_OPEN, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 157/* UL_CLOSE_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 158/* LL_OPEN_EVT */ {AVDT_CCB_LL_OPENED, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 159/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 160/* LL_CONG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST} 161}; 162 163/* state table for opening state */ 164const uint8_t avdt_ccb_st_opening[][AVDT_CCB_NUM_COLS] = { 165/* Event Action 1 Action 2 Next state */ 166/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 167/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 168/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 169/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 170/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 171/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 172/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 173/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 174/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 175/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN, AVDT_CCB_DO_DISCONN, AVDT_CCB_CLOSING_ST}, 176/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 177/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 178/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 179/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 180/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 181/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 182/* MSG_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 183/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 184/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 185/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 186/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 187/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 188/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 189/* UL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST}, 190/* UL_CLOSE_EVT */ {AVDT_CCB_CLEAR_CMDS, AVDT_CCB_CHAN_CLOSE, AVDT_CCB_CLOSING_ST}, 191/* LL_OPEN_EVT */ {AVDT_CCB_SND_CMD, AVDT_CCB_LL_OPENED, AVDT_CCB_OPEN_ST}, 192/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 193/* LL_CONG_EVT */ {AVDT_CCB_CONG_STATE, AVDT_CCB_IGNORE, AVDT_CCB_OPENING_ST} 194}; 195 196/* state table for open state */ 197const uint8_t avdt_ccb_st_open[][AVDT_CCB_NUM_COLS] = { 198/* Event Action 1 Action 2 Next state */ 199/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 200/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 201/* API_START_REQ_EVT */ {AVDT_CCB_SND_START_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 202/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_SND_SUSPEND_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 203/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_SND_DISCOVER_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 204/* API_GETCAP_RSP_EVT */ {AVDT_CCB_SND_GETCAP_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 205/* API_START_RSP_EVT */ {AVDT_CCB_SND_START_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 206/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_SND_SUSPEND_RSP, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 207/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_CONN, AVDT_CCB_LL_OPENED, AVDT_CCB_OPEN_ST}, 208/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_SET_DISCONN, AVDT_CCB_DO_DISCONN, AVDT_CCB_CLOSING_ST}, 209/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_HDL_DISCOVER_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 210/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_HDL_GETCAP_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 211/* MSG_START_CMD_EVT */ {AVDT_CCB_HDL_START_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 212/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_HDL_SUSPEND_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 213/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_OPEN_ST}, 214/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_OPEN_ST}, 215/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 216/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 217/* RCVRSP_EVT */ {AVDT_CCB_FREE_CMD, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 218/* SENDMSG_EVT */ {AVDT_CCB_SND_MSG, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 219/* RET_TOUT_EVT */ {AVDT_CCB_RET_CMD, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 220/* RSP_TOUT_EVT */ {AVDT_CCB_CMD_FAIL, AVDT_CCB_SND_CMD, AVDT_CCB_OPEN_ST}, 221/* IDLE_TOUT_EVT */ {AVDT_CCB_CLEAR_CMDS, AVDT_CCB_CHAN_CLOSE, AVDT_CCB_CLOSING_ST}, 222/* UL_OPEN_EVT */ {AVDT_CCB_CHK_TIMER, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 223/* UL_CLOSE_EVT */ {AVDT_CCB_CHK_CLOSE, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 224/* LL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_OPEN_ST}, 225/* LL_CLOSE_EVT */ {AVDT_CCB_LL_CLOSED, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 226/* LL_CONG_EVT */ {AVDT_CCB_CONG_STATE, AVDT_CCB_SND_MSG, AVDT_CCB_OPEN_ST} 227}; 228 229/* state table for closing state */ 230const uint8_t avdt_ccb_st_closing[][AVDT_CCB_NUM_COLS] = { 231/* Event Action 1 Action 2 Next state */ 232/* API_DISCOVER_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SND_DISCOVER_CMD, AVDT_CCB_CLOSING_ST}, 233/* API_GETCAP_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SND_GETCAP_CMD, AVDT_CCB_CLOSING_ST}, 234/* API_START_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 235/* API_SUSPEND_REQ_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 236/* API_DISCOVER_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 237/* API_GETCAP_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 238/* API_START_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 239/* API_SUSPEND_RSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 240/* API_CONNECT_REQ_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_SET_CONN, AVDT_CCB_CLOSING_ST}, 241/* API_DISCONNECT_REQ_EVT */ {AVDT_CCB_CLR_RECONN, AVDT_CCB_SET_DISCONN, AVDT_CCB_CLOSING_ST}, 242/* MSG_DISCOVER_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 243/* MSG_GETCAP_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 244/* MSG_START_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 245/* MSG_SUSPEND_CMD_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 246/* MSG_DISCOVER_RSP_EVT */ {AVDT_CCB_HDL_DISCOVER_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 247/* MSG_GETCAP_RSP_EVT */ {AVDT_CCB_HDL_GETCAP_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 248/* MSG_START_RSP_EVT */ {AVDT_CCB_HDL_START_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 249/* MSG_SUSPEND_RSP_EVT */ {AVDT_CCB_HDL_SUSPEND_RSP, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 250/* RCVRSP_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 251/* SENDMSG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 252/* RET_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 253/* RSP_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 254/* IDLE_TOUT_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 255/* UL_OPEN_EVT */ {AVDT_CCB_SET_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 256/* UL_CLOSE_EVT */ {AVDT_CCB_CLR_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 257/* LL_OPEN_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST}, 258/* LL_CLOSE_EVT */ {AVDT_CCB_CHK_RECONN, AVDT_CCB_IGNORE, AVDT_CCB_IDLE_ST}, 259/* LL_CONG_EVT */ {AVDT_CCB_IGNORE, AVDT_CCB_IGNORE, AVDT_CCB_CLOSING_ST} 260}; 261 262/* type for state table */ 263typedef const uint8_t (*tAVDT_CCB_ST_TBL)[AVDT_CCB_NUM_COLS]; 264 265/* state table */ 266const tAVDT_CCB_ST_TBL avdt_ccb_st_tbl[] = { 267 avdt_ccb_st_idle, 268 avdt_ccb_st_opening, 269 avdt_ccb_st_open, 270 avdt_ccb_st_closing 271}; 272 273/******************************************************************************* 274** 275** Function avdt_ccb_init 276** 277** Description Initialize channel control block module. 278** 279** 280** Returns Nothing. 281** 282*******************************************************************************/ 283void avdt_ccb_init(void) 284{ 285 memset(&avdt_cb.ccb[0], 0, sizeof(tAVDT_CCB) * AVDT_NUM_LINKS); 286 avdt_cb.p_ccb_act = (tAVDT_CCB_ACTION *) avdt_ccb_action; 287} 288 289/******************************************************************************* 290** 291** Function avdt_ccb_event 292** 293** Description State machine event handling function for ccb 294** 295** 296** Returns Nothing. 297** 298*******************************************************************************/ 299void avdt_ccb_event(tAVDT_CCB *p_ccb, uint8_t event, tAVDT_CCB_EVT *p_data) 300{ 301 tAVDT_CCB_ST_TBL state_table; 302 uint8_t action; 303 int i; 304 305#if (AVDT_DEBUG == TRUE) 306 AVDT_TRACE_EVENT("CCB ccb=%d event=%s state=%s", avdt_ccb_to_idx(p_ccb), avdt_ccb_evt_str[event], avdt_ccb_st_str[p_ccb->state]); 307#endif 308 309 /* look up the state table for the current state */ 310 state_table = avdt_ccb_st_tbl[p_ccb->state]; 311 312 /* set next state */ 313 if (p_ccb->state != state_table[event][AVDT_CCB_NEXT_STATE]) { 314 p_ccb->state = state_table[event][AVDT_CCB_NEXT_STATE]; 315 } 316 317 /* execute action functions */ 318 for (i = 0; i < AVDT_CCB_ACTIONS; i++) 319 { 320 action = state_table[event][i]; 321 if (action != AVDT_CCB_IGNORE) 322 { 323 (*avdt_cb.p_ccb_act[action])(p_ccb, p_data); 324 } 325 else 326 { 327 break; 328 } 329 } 330} 331 332 333/******************************************************************************* 334** 335** Function avdt_ccb_by_bd 336** 337** Description This lookup function finds the ccb for a BD address. 338** 339** 340** Returns pointer to the ccb, or NULL if none found. 341** 342*******************************************************************************/ 343tAVDT_CCB *avdt_ccb_by_bd(BD_ADDR bd_addr) 344{ 345 tAVDT_CCB *p_ccb = &avdt_cb.ccb[0]; 346 int i; 347 348 for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) 349 { 350 /* if allocated ccb has matching ccb */ 351 if (p_ccb->allocated && (!memcmp(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN))) 352 { 353 break; 354 } 355 } 356 357 if (i == AVDT_NUM_LINKS) 358 { 359 /* if no ccb found */ 360 p_ccb = NULL; 361 362 AVDT_TRACE_DEBUG("No ccb for addr %02x-%02x-%02x-%02x-%02x-%02x", 363 bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); 364 } 365 return p_ccb; 366} 367 368/******************************************************************************* 369** 370** Function avdt_ccb_alloc 371** 372** Description Allocate a channel control block. 373** 374** 375** Returns pointer to the ccb, or NULL if none could be allocated. 376** 377*******************************************************************************/ 378tAVDT_CCB *avdt_ccb_alloc(BD_ADDR bd_addr) 379{ 380 tAVDT_CCB *p_ccb = &avdt_cb.ccb[0]; 381 int i; 382 383 for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) 384 { 385 if (!p_ccb->allocated) 386 { 387 p_ccb->allocated = true; 388 memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN); 389 p_ccb->cmd_q = fixed_queue_new(SIZE_MAX); 390 p_ccb->rsp_q = fixed_queue_new(SIZE_MAX); 391 p_ccb->idle_ccb_timer = alarm_new("avdt_ccb.idle_ccb_timer"); 392 p_ccb->ret_ccb_timer = alarm_new("avdt_ccb.ret_ccb_timer"); 393 p_ccb->rsp_ccb_timer = alarm_new("avdt_ccb.rsp_ccb_timer"); 394 AVDT_TRACE_DEBUG("avdt_ccb_alloc %d", i); 395 break; 396 } 397 } 398 399 if (i == AVDT_NUM_LINKS) 400 { 401 /* out of ccbs */ 402 p_ccb = NULL; 403 AVDT_TRACE_WARNING("Out of ccbs"); 404 } 405 return p_ccb; 406} 407 408/******************************************************************************* 409** 410** Function avdt_ccb_dealloc 411** 412** Description Deallocate a stream control block. 413** 414** 415** Returns void. 416** 417*******************************************************************************/ 418void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, 419 UNUSED_ATTR tAVDT_CCB_EVT *p_data) 420{ 421 AVDT_TRACE_DEBUG("avdt_ccb_dealloc %d", avdt_ccb_to_idx(p_ccb)); 422 alarm_free(p_ccb->idle_ccb_timer); 423 alarm_free(p_ccb->ret_ccb_timer); 424 alarm_free(p_ccb->rsp_ccb_timer); 425 fixed_queue_free(p_ccb->cmd_q, NULL); 426 fixed_queue_free(p_ccb->rsp_q, NULL); 427 memset(p_ccb, 0, sizeof(tAVDT_CCB)); 428} 429 430/******************************************************************************* 431** 432** Function avdt_ccb_to_idx 433** 434** Description Given a pointer to an ccb, return its index. 435** 436** 437** Returns Index of ccb. 438** 439*******************************************************************************/ 440uint8_t avdt_ccb_to_idx(tAVDT_CCB *p_ccb) 441{ 442 /* use array arithmetic to determine index */ 443 return (uint8_t) (p_ccb - avdt_cb.ccb); 444} 445 446/******************************************************************************* 447** 448** Function avdt_ccb_by_idx 449** 450** Description Return ccb pointer based on ccb index. 451** 452** 453** Returns pointer to the ccb, or NULL if none found. 454** 455*******************************************************************************/ 456tAVDT_CCB *avdt_ccb_by_idx(uint8_t idx) 457{ 458 tAVDT_CCB *p_ccb; 459 460 /* verify index */ 461 if (idx < AVDT_NUM_LINKS) 462 { 463 p_ccb = &avdt_cb.ccb[idx]; 464 } 465 else 466 { 467 p_ccb = NULL; 468 AVDT_TRACE_WARNING("No ccb for idx %d", idx); 469 } 470 return p_ccb; 471} 472 473