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