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