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