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 "avdt_api.h"
     28 #include "avdt_int.h"
     29 #include "avdtc_api.h"
     30 #include "bt_common.h"
     31 #include "bt_target.h"
     32 #include "bt_types.h"
     33 #include "bt_utils.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 */
     43 const char* const avdt_ccb_st_str[] = {"CCB_IDLE_ST", "CCB_OPENING_ST",
     44                                        "CCB_OPEN_ST", "CCB_CLOSING_ST"};
     45 
     46 /* verbose event strings for trace */
     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"};
     62 
     63 #endif
     64 
     65 /* action function list */
     66 const tAVDT_CCB_ACTION avdt_ccb_action[] = {
     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};
     85 
     86 /* state table information */
     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 */
     90 
     91 /* state table for idle state */
     92 const uint8_t avdt_ccb_st_idle[][AVDT_CCB_NUM_COLS] = {
     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}};
    151 
    152 /* state table for opening state */
    153 const uint8_t avdt_ccb_st_opening[][AVDT_CCB_NUM_COLS] = {
    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}};
    212 
    213 /* state table for open state */
    214 const uint8_t avdt_ccb_st_open[][AVDT_CCB_NUM_COLS] = {
    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}};
    273 
    274 /* state table for closing state */
    275 const uint8_t avdt_ccb_st_closing[][AVDT_CCB_NUM_COLS] = {
    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}};
    334 
    335 /* type for state table */
    336 typedef const uint8_t (*tAVDT_CCB_ST_TBL)[AVDT_CCB_NUM_COLS];
    337 
    338 /* state table */
    339 const tAVDT_CCB_ST_TBL avdt_ccb_st_tbl[] = {
    340     avdt_ccb_st_idle, avdt_ccb_st_opening, avdt_ccb_st_open,
    341     avdt_ccb_st_closing};
    342 
    343 /*******************************************************************************
    344  *
    345  * Function         avdt_ccb_init
    346  *
    347  * Description      Initialize channel control block module.
    348  *
    349  *
    350  * Returns          Nothing.
    351  *
    352  ******************************************************************************/
    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;
    356 }
    357 
    358 /*******************************************************************************
    359  *
    360  * Function         avdt_ccb_event
    361  *
    362  * Description      State machine event handling function for ccb
    363  *
    364  *
    365  * Returns          Nothing.
    366  *
    367  ******************************************************************************/
    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;
    372 
    373 #if (AVDT_DEBUG == TRUE)
    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]);
    377 #endif
    378 
    379   /* look up the state table for the current state */
    380   state_table = avdt_ccb_st_tbl[p_ccb->state];
    381 
    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   }
    386 
    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;
    394     }
    395   }
    396 }
    397 
    398 /*******************************************************************************
    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  ******************************************************************************/
    408 tAVDT_CCB* avdt_ccb_by_bd(BD_ADDR bd_addr) {
    409   tAVDT_CCB* p_ccb = &avdt_cb.ccb[0];
    410   int i;
    411 
    412   for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
    413     /* if allocated ccb has matching ccb */
    414     if (p_ccb->allocated && (!memcmp(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN))) {
    415       break;
    416     }
    417   }
    418 
    419   if (i == AVDT_NUM_LINKS) {
    420     /* if no ccb found */
    421     p_ccb = NULL;
    422 
    423     AVDT_TRACE_DEBUG("No ccb for addr %02x-%02x-%02x-%02x-%02x-%02x",
    424                      bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
    425                      bd_addr[5]);
    426   }
    427   return p_ccb;
    428 }
    429 
    430 /*******************************************************************************
    431  *
    432  * Function         avdt_ccb_alloc
    433  *
    434  * Description      Allocate a channel control block.
    435  *
    436  *
    437  * Returns          pointer to the ccb, or NULL if none could be allocated.
    438  *
    439  ******************************************************************************/
    440 tAVDT_CCB* avdt_ccb_alloc(BD_ADDR bd_addr) {
    441   tAVDT_CCB* p_ccb = &avdt_cb.ccb[0];
    442   int i;
    443 
    444   for (i = 0; i < AVDT_NUM_LINKS; i++, p_ccb++) {
    445     if (!p_ccb->allocated) {
    446       p_ccb->allocated = true;
    447       memcpy(p_ccb->peer_addr, bd_addr, BD_ADDR_LEN);
    448       p_ccb->cmd_q = fixed_queue_new(SIZE_MAX);
    449       p_ccb->rsp_q = fixed_queue_new(SIZE_MAX);
    450       p_ccb->idle_ccb_timer = alarm_new("avdt_ccb.idle_ccb_timer");
    451       p_ccb->ret_ccb_timer = alarm_new("avdt_ccb.ret_ccb_timer");
    452       p_ccb->rsp_ccb_timer = alarm_new("avdt_ccb.rsp_ccb_timer");
    453       AVDT_TRACE_DEBUG("avdt_ccb_alloc %d", i);
    454       break;
    455     }
    456   }
    457 
    458   if (i == AVDT_NUM_LINKS) {
    459     /* out of ccbs */
    460     p_ccb = NULL;
    461     AVDT_TRACE_WARNING("Out of ccbs");
    462   }
    463   return p_ccb;
    464 }
    465 
    466 /*******************************************************************************
    467  *
    468  * Function         avdt_ccb_dealloc
    469  *
    470  * Description      Deallocate a stream control block.
    471  *
    472  *
    473  * Returns          void.
    474  *
    475  ******************************************************************************/
    476 void avdt_ccb_dealloc(tAVDT_CCB* p_ccb, UNUSED_ATTR tAVDT_CCB_EVT* p_data) {
    477   AVDT_TRACE_DEBUG("avdt_ccb_dealloc %d", avdt_ccb_to_idx(p_ccb));
    478   alarm_free(p_ccb->idle_ccb_timer);
    479   alarm_free(p_ccb->ret_ccb_timer);
    480   alarm_free(p_ccb->rsp_ccb_timer);
    481   fixed_queue_free(p_ccb->cmd_q, NULL);
    482   fixed_queue_free(p_ccb->rsp_q, NULL);
    483   memset(p_ccb, 0, sizeof(tAVDT_CCB));
    484 }
    485 
    486 /*******************************************************************************
    487  *
    488  * Function         avdt_ccb_to_idx
    489  *
    490  * Description      Given a pointer to an ccb, return its index.
    491  *
    492  *
    493  * Returns          Index of ccb.
    494  *
    495  ******************************************************************************/
    496 uint8_t avdt_ccb_to_idx(tAVDT_CCB* p_ccb) {
    497   /* use array arithmetic to determine index */
    498   return (uint8_t)(p_ccb - avdt_cb.ccb);
    499 }
    500 
    501 /*******************************************************************************
    502  *
    503  * Function         avdt_ccb_by_idx
    504  *
    505  * Description      Return ccb pointer based on ccb index.
    506  *
    507  *
    508  * Returns          pointer to the ccb, or NULL if none found.
    509  *
    510  ******************************************************************************/
    511 tAVDT_CCB* avdt_ccb_by_idx(uint8_t idx) {
    512   tAVDT_CCB* p_ccb;
    513 
    514   /* verify index */
    515   if (idx < AVDT_NUM_LINKS) {
    516     p_ccb = &avdt_cb.ccb[idx];
    517   } else {
    518     p_ccb = NULL;
    519     AVDT_TRACE_WARNING("No ccb for idx %d", idx);
    520   }
    521   return p_ccb;
    522 }
    523