Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2015 Motorola 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 is the stream state machine for the BRCM offloaded advanced audio.
     22  *
     23  ******************************************************************************/
     24 
     25 #define LOG_TAG "bt_vnd_a2dp"
     26 #define LOG_NDEBUG 0
     27 
     28 #include <string.h>
     29 #include <pthread.h>
     30 #include <utils/Log.h>
     31 #include <sys/types.h>
     32 #include <sys/stat.h>
     33 #include <signal.h>
     34 #include <time.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <dirent.h>
     38 #include <ctype.h>
     39 #include <cutils/properties.h>
     40 #include <stdlib.h>
     41 #include "bt_hci_bdroid.h"
     42 #include "bt_vendor_brcm_a2dp.h"
     43 #include "a2d_api.h"
     44 #include "a2d_sbc.h"
     45 
     46 #if (BTA2DP_DEBUG == TRUE)
     47 #define BTA2DPDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
     48 #else
     49 #define BTA2DPDBG(param, ...) {}
     50 #endif
     51 
     52 /*****************************************************************************
     53 ** Constants and types
     54 *****************************************************************************/
     55 
     56 typedef void (*hci_cback)(void *);
     57 
     58 typedef enum
     59 {
     60     BRCM_VND_A2DP_OFFLOAD_INIT_REQ,
     61     BRCM_VND_A2DP_OFFLOAD_START_REQ,
     62     BRCM_VND_A2DP_OFFLOAD_STOP_REQ,
     63     BRCM_VND_UIPC_OPEN_RSP,
     64     BRCM_VND_L2C_SYNC_TO_LITE_RSP,
     65     BRCM_VND_SYNC_TO_BTC_LITE_RSP,
     66     BRCM_VND_AUDIO_CODEC_CONFIG_RSP,
     67     BRCM_VND_AUDIO_ROUTE_CONFIG_RSP,
     68     BRCM_VND_UIPC_CLOSE_RSP,
     69     BRCM_VND_L2C_REMOVE_TO_LITE_RSP,
     70     BRCM_VND_A2DP_START_RSP,
     71     BRCM_VND_A2DP_SUSPEND_RSP,
     72     BRCM_VND_STREAM_STOP_RSP,
     73     BRCM_VND_A2DP_CLEANUP_RSP,
     74     BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT,
     75 } tBRCM_VND_A2DP_EVENT;
     76 
     77 /* state machine states */
     78 typedef enum
     79 {
     80     BRCM_VND_A2DP_INVALID_SST = -1,
     81     BRCM_VND_A2DP_IDLE_SST,
     82     BRCM_VND_A2DP_STARTING_SST,
     83     BRCM_VND_A2DP_STREAM_SST,
     84 }
     85 tBRCM_VND_A2DP_SST_STATES;
     86 
     87 static uint8_t brcm_vnd_a2dp_offload_configure();
     88 static uint8_t brcm_vnd_a2dp_offload_cleanup();
     89 static uint8_t brcm_vnd_a2dp_offload_suspend();
     90 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data);
     91 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data);
     92 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data);
     93 static void brcm_vnd_a2dp_hci_uipc_cback(void *pmem);
     94 
     95 typedef struct {
     96     uint8_t     fcn;
     97     uint32_t    pad_conf;
     98 }
     99 tBRCM_VND_PCM_CONF;
    100 
    101 typedef struct {
    102     tBRCM_VND_A2DP_SST_STATES state;
    103     tCODEC_INFO_SBC codec_info;
    104     tBRCM_VND_PCM_CONF pcmi2s_pinmux;
    105     bt_vendor_op_a2dp_offload_t offload_params;
    106 }
    107 tBRCM_VND_A2DP_PDATA;
    108 
    109 typedef struct {
    110     tBRCM_VND_A2DP_SST_STATES (*enter)(tBRCM_VND_A2DP_EVENT event);
    111     tBRCM_VND_A2DP_SST_STATES (*process_event)(tBRCM_VND_A2DP_EVENT event, void *ev_data);
    112 }
    113 tBRCM_VND_A2DP_SST_STATE;
    114 
    115 /* state table */
    116 static tBRCM_VND_A2DP_SST_STATE brcm_vnd_a2dp_sst_tbl[] =
    117 {
    118     {NULL, brcm_vnd_a2dp_sm_idle_process_ev},
    119     {NULL, brcm_vnd_a2dp_sm_starting_process_ev},
    120     {NULL, brcm_vnd_a2dp_sm_stream_process_ev},
    121 };
    122 
    123 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
    124 static tBRCM_VND_A2DP_PDATA brcm_vnd_a2dp_pdata = { .state = BRCM_VND_A2DP_INVALID_SST };
    125 
    126 
    127 /*******************************************************************************
    128 ** Local Utility Functions
    129 *******************************************************************************/
    130 
    131 static void log_bin_to_hexstr(uint8_t *bin, uint8_t binsz, const char *log_tag)
    132 {
    133 #if (BTA2DP_DEBUG == TRUE)
    134   char     *str, hex_str[]= "0123456789abcdef";
    135   uint8_t  i;
    136 
    137   str = (char *)malloc(binsz * 3);
    138   if (!binsz) {
    139     ALOGE("%s alloc failed", __FUNCTION__);
    140     return;
    141   }
    142 
    143   for (i = 0; i < binsz; i++) {
    144       str[(i * 3) + 0] = hex_str[(bin[i] >> 4) & 0x0F];
    145       str[(i * 3) + 1] = hex_str[(bin[i]     ) & 0x0F];
    146       str[(i * 3) + 2] = ' ';
    147   }
    148   str[(binsz * 3) - 1] = 0x00;
    149   BTA2DPDBG("%s %s", log_tag, str);
    150 #endif
    151 }
    152 
    153 static uint8_t brcm_vnd_a2dp_send_hci_vsc(uint16_t cmd, uint8_t *payload, uint8_t len, hci_cback cback)
    154 {
    155     HC_BT_HDR   *p_buf;
    156     uint8_t     *p, status;
    157     uint16_t    opcode;
    158 
    159     // Perform Opening configure cmds. //
    160     if (bt_vendor_cbacks) {
    161         p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(
    162             BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + len);
    163         if (p_buf)
    164         {
    165             p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
    166             p_buf->offset = 0;
    167             p_buf->layer_specific = 0;
    168             p_buf->len = HCI_CMD_PREAMBLE_SIZE + len;
    169             p = (uint8_t *)(p_buf + 1);
    170 
    171             UINT16_TO_STREAM(p, cmd);
    172             *p++ = len;
    173             memcpy(p, payload, len);
    174 
    175             //BTA2DPDBG("%s Cmd %04x UIPC Event %02x%02x UIPC Op %02x Len %d", __FUNCTION__, cmd, event, payload[1], payload[0], payload[2], len);
    176             log_bin_to_hexstr((uint8_t *)(p_buf + 1), HCI_CMD_PREAMBLE_SIZE + len, __FUNCTION__);
    177 
    178             if (bt_vendor_cbacks->xmit_cb(cmd, p_buf, cback))
    179             {
    180                 return BT_VND_OP_RESULT_SUCCESS;
    181             }
    182             bt_vendor_cbacks->dealloc(p_buf);
    183         }
    184     }
    185     return BT_VND_OP_RESULT_FAIL;
    186 }
    187 
    188 static void brcm_vnd_map_a2d_uipc_codec_info(tCODEC_INFO_SBC *codec_info)
    189 {
    190     switch(codec_info->sampling_freq) {
    191         case A2D_SBC_IE_SAMP_FREQ_16:
    192             codec_info->sampling_freq = CODEC_INFO_SBC_SF_16K; break;
    193         case A2D_SBC_IE_SAMP_FREQ_32:
    194             codec_info->sampling_freq = CODEC_INFO_SBC_SF_32K; break;
    195         case A2D_SBC_IE_SAMP_FREQ_44:
    196             codec_info->sampling_freq = CODEC_INFO_SBC_SF_44K; break;
    197         case A2D_SBC_IE_SAMP_FREQ_48:
    198             codec_info->sampling_freq = CODEC_INFO_SBC_SF_48K; break;
    199 
    200     }
    201     switch(codec_info->channel_mode) {
    202         case A2D_SBC_IE_CH_MD_MONO:
    203             codec_info->channel_mode = CODEC_INFO_SBC_CH_MONO; break;
    204         case A2D_SBC_IE_CH_MD_DUAL:
    205             codec_info->channel_mode = CODEC_INFO_SBC_CH_DUAL; break;
    206         case A2D_SBC_IE_CH_MD_STEREO:
    207             codec_info->channel_mode = CODEC_INFO_SBC_CH_STEREO; break;
    208         case A2D_SBC_IE_CH_MD_JOINT:
    209             codec_info->channel_mode = CODEC_INFO_SBC_CH_JS; break;
    210     }
    211     switch(codec_info->block_length) {
    212         case A2D_SBC_IE_BLOCKS_4:
    213             codec_info->block_length = CODEC_INFO_SBC_BLOCK_4; break;
    214         case A2D_SBC_IE_BLOCKS_8:
    215             codec_info->block_length = CODEC_INFO_SBC_BLOCK_8; break;
    216         case A2D_SBC_IE_BLOCKS_12:
    217             codec_info->block_length = CODEC_INFO_SBC_BLOCK_12; break;
    218         case A2D_SBC_IE_BLOCKS_16:
    219             codec_info->block_length = CODEC_INFO_SBC_BLOCK_16; break;
    220     }
    221     switch(codec_info->alloc_method) {
    222         case A2D_SBC_IE_ALLOC_MD_S:
    223             codec_info->alloc_method = CODEC_INFO_SBC_ALLOC_SNR; break;
    224         case A2D_SBC_IE_ALLOC_MD_L:
    225             codec_info->alloc_method = CODEC_INFO_SBC_ALLOC_LOUDNESS; break;
    226     }
    227     switch(codec_info->num_subbands) {
    228         case A2D_SBC_IE_SUBBAND_4:
    229             codec_info->num_subbands = CODEC_INFO_SBC_SUBBAND_4; break;
    230         case A2D_SBC_IE_SUBBAND_8:
    231             codec_info->num_subbands = CODEC_INFO_SBC_SUBBAND_8; break;
    232     }
    233 }
    234 
    235 static tA2D_STATUS bcrm_vnd_a2dp_parse_codec_info(tCODEC_INFO_SBC *parsed_info, uint8_t *codec_info)
    236 {
    237     tA2D_STATUS status = A2D_SUCCESS;
    238     UINT8   losc;
    239     UINT8   mt;
    240 
    241     BTA2DPDBG("%s", __FUNCTION__);
    242 
    243     if( parsed_info == NULL || codec_info == NULL)
    244         status = A2D_FAIL;
    245     else
    246     {
    247         losc    = *codec_info++;
    248         mt      = *codec_info++;
    249         /* If the function is called for the wrong Media Type or Media Codec Type */
    250         if(losc != A2D_SBC_INFO_LEN || *codec_info != A2D_MEDIA_CT_SBC)
    251             status = A2D_WRONG_CODEC;
    252         else
    253         {
    254             codec_info++;
    255             parsed_info->sampling_freq = *codec_info & A2D_SBC_IE_SAMP_FREQ_MSK;
    256             parsed_info->channel_mode  = *codec_info & A2D_SBC_IE_CH_MD_MSK;
    257             codec_info++;
    258             parsed_info->block_length  = *codec_info & A2D_SBC_IE_BLOCKS_MSK;
    259             parsed_info->num_subbands  = *codec_info & A2D_SBC_IE_SUBBAND_MSK;
    260             parsed_info->alloc_method  = *codec_info & A2D_SBC_IE_ALLOC_MD_MSK;
    261             codec_info += 2; /* MAX Bitpool */
    262             parsed_info->bitpool_size  = (*codec_info > BRCM_A2DP_OFFLOAD_MAX_BITPOOL) ?
    263                                          BRCM_A2DP_OFFLOAD_MAX_BITPOOL : (*codec_info);
    264 
    265             if(MULTI_BIT_SET(parsed_info->sampling_freq))
    266                 status = A2D_BAD_SAMP_FREQ;
    267             if(MULTI_BIT_SET(parsed_info->channel_mode))
    268                 status = A2D_BAD_CH_MODE;
    269             if(MULTI_BIT_SET(parsed_info->block_length))
    270                 status = A2D_BAD_BLOCK_LEN;
    271             if(MULTI_BIT_SET(parsed_info->num_subbands))
    272                 status = A2D_BAD_SUBBANDS;
    273             if(MULTI_BIT_SET(parsed_info->alloc_method))
    274                 status = A2D_BAD_ALLOC_MTHD;
    275             if(parsed_info->bitpool_size < A2D_SBC_IE_MIN_BITPOOL || parsed_info->bitpool_size > A2D_SBC_IE_MAX_BITPOOL )
    276                 status = A2D_BAD_MIN_BITPOOL;
    277 
    278             if(status == A2D_SUCCESS)
    279                 brcm_vnd_map_a2d_uipc_codec_info(parsed_info);
    280 
    281             BTA2DPDBG("%s STATUS %d parsed info : SampF %02x, ChnMode %02x, BlockL %02x, NSubB %02x, alloc %02x, bitpool %02x",
    282                 __FUNCTION__, status, parsed_info->sampling_freq, parsed_info->channel_mode, parsed_info->block_length,
    283                 parsed_info->num_subbands, parsed_info->alloc_method, parsed_info->bitpool_size);
    284 
    285         }
    286     }
    287     return status;
    288 }
    289 
    290 /*******************************************************************************
    291 ** State Machine Functions
    292 *******************************************************************************/
    293 
    294 /*******************************************************************************
    295 **
    296 ** Function         brcm_vnd_a2dp_ssm_execute
    297 **
    298 ** Description      Stream state machine event handling function for AV
    299 **
    300 **
    301 ** Returns          void
    302 **
    303 *******************************************************************************/
    304 int brcm_vnd_a2dp_ssm_execute(tBRCM_VND_A2DP_EVENT event, void *ev_data)
    305 {
    306     tBRCM_VND_A2DP_SST_STATE *state_table;
    307     tBRCM_VND_A2DP_SST_STATES next_state;
    308 
    309     pthread_mutex_lock(&g_mutex);
    310 
    311     BTA2DPDBG("%s ev %d state %d", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state);
    312 
    313     if (brcm_vnd_a2dp_pdata.state != BRCM_VND_A2DP_INVALID_SST) {
    314         state_table = &brcm_vnd_a2dp_sst_tbl[brcm_vnd_a2dp_pdata.state];
    315         /* process event */
    316         next_state = state_table->process_event(event, ev_data);
    317     } else if (BRCM_VND_A2DP_OFFLOAD_INIT_REQ == event) {
    318         next_state = BRCM_VND_A2DP_IDLE_SST;
    319     }
    320     else {
    321         pthread_mutex_unlock(&g_mutex);
    322         return BT_VND_OP_RESULT_FAIL;
    323     }
    324 
    325     /* transition stae */
    326     while (next_state != brcm_vnd_a2dp_pdata.state) {
    327         brcm_vnd_a2dp_pdata.state = next_state;
    328         state_table = &brcm_vnd_a2dp_sst_tbl[next_state];
    329         if (state_table->enter)
    330             next_state = state_table->enter(event);
    331     }
    332 
    333     pthread_mutex_unlock(&g_mutex);
    334     return BT_VND_OP_RESULT_SUCCESS;
    335 }
    336 
    337 /* state machine actions */
    338 
    339 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data)
    340 {
    341     tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state;
    342 
    343     switch (event) {
    344         case BRCM_VND_A2DP_OFFLOAD_START_REQ:
    345             brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data;
    346             if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info( &brcm_vnd_a2dp_pdata.codec_info,
    347                     (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) {
    348                 ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__);
    349                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    350                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    351             } else {
    352                 brcm_vnd_a2dp_offload_configure();
    353                 next_state = BRCM_VND_A2DP_STARTING_SST;
    354             }
    355             break;
    356 
    357         default:
    358             ALOGV("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state);
    359             break;
    360     }
    361     return next_state;
    362 }
    363 
    364 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data)
    365 {
    366     tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state;
    367     uint8_t status, *p;
    368 
    369     switch (event) {
    370         case BRCM_VND_A2DP_OFFLOAD_START_REQ:
    371             brcm_vnd_a2dp_offload_cleanup();
    372             brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data;
    373             if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info(
    374                     &brcm_vnd_a2dp_pdata.codec_info, (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) {
    375                 ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__);
    376                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    377                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    378                 next_state = BRCM_VND_A2DP_IDLE_SST;
    379             } else {
    380                 brcm_vnd_a2dp_offload_configure();
    381             }
    382             break;
    383 
    384         case BRCM_VND_A2DP_OFFLOAD_STOP_REQ:
    385             brcm_vnd_a2dp_offload_cleanup();
    386             next_state = BRCM_VND_A2DP_IDLE_SST;
    387             break;
    388 
    389         case BRCM_VND_UIPC_OPEN_RSP: {
    390                 uint8_t num_streams;
    391                 uint16_t maj_ver, min_ver;
    392                 p = (uint8_t*)ev_data + offsetof(tUIPC_OPEN_RSP, status);
    393                 STREAM_TO_UINT8(status,p);
    394                 STREAM_TO_UINT16(maj_ver,p);
    395                 STREAM_TO_UINT16(min_ver,p);
    396                 STREAM_TO_UINT8(num_streams,p);
    397                 // TODO Verify Params //
    398                 if (status) {
    399                     ALOGE("%s BRCM_VND_UIPC_OPEN_RSP %02x FAILED", __FUNCTION__, status);
    400                     brcm_vnd_a2dp_offload_cleanup();
    401                     bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    402                                                       brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    403                     next_state = BRCM_VND_A2DP_IDLE_SST;
    404                 }
    405             }
    406             break;
    407 
    408         case BRCM_VND_L2C_SYNC_TO_LITE_RSP:
    409             status = *((uint8_t*)ev_data + offsetof(tL2C_SYNC_TO_LITE_RESP, stream.status));
    410             if (status) {
    411                 ALOGE("%s L2C_SYNC_TO_LITE_RESP %02x FAILED", __FUNCTION__, status);
    412                 brcm_vnd_a2dp_offload_cleanup();
    413                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    414                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    415                 next_state = BRCM_VND_A2DP_IDLE_SST;
    416             }
    417             break;
    418 
    419         case BRCM_VND_SYNC_TO_BTC_LITE_RSP:
    420             status = *((uint8_t*)ev_data + offsetof(tAVDT_SYNC_TO_BTC_LITE_RESP, status));
    421             if (status) {
    422                 ALOGE("%s AVDT_SYNC_TO_BTC_LITE_RESP %02x FAILED", __FUNCTION__, status);
    423                 brcm_vnd_a2dp_offload_cleanup();
    424                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    425                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    426                 next_state = BRCM_VND_A2DP_IDLE_SST;
    427             }
    428             break;
    429 
    430         case BRCM_VND_AUDIO_ROUTE_CONFIG_RSP:
    431             status = *((uint8_t*)ev_data + offsetof(tAUDIO_ROUTE_CONFIG_RESP, status));
    432             if (status) {
    433                 ALOGE("%s AUDIO_ROUTE_CONFIG_RESP %02x FAILED", __FUNCTION__, status);
    434                 brcm_vnd_a2dp_offload_cleanup();
    435                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    436                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    437                 next_state = BRCM_VND_A2DP_IDLE_SST;
    438             }
    439             break;
    440 
    441         case BRCM_VND_AUDIO_CODEC_CONFIG_RSP:
    442             status = *((uint8_t*)ev_data + offsetof(tAUDIO_CODEC_CONFIG_RESP, status));
    443             if (status) {
    444                 ALOGE("%s BRCM_VND_AUDIO_CODEC_CONFIG_RSP %02x FAILED", __FUNCTION__, status);
    445                 brcm_vnd_a2dp_offload_cleanup();
    446                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    447                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    448                 next_state = BRCM_VND_A2DP_IDLE_SST;
    449             }
    450             break;
    451 
    452         case BRCM_VND_A2DP_START_RSP:
    453             /* status = *((uint8_t*)ev_data + offsetof(tA2DP_GENERIC_RESP, status)); */
    454             bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_SUCCESS, BT_VND_OP_A2DP_OFFLOAD_START,
    455                                               brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    456             next_state = BRCM_VND_A2DP_STREAM_SST;
    457             break;
    458 
    459         case BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT:
    460             ALOGE("%s BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT", __FUNCTION__);
    461             brcm_vnd_a2dp_offload_cleanup();
    462             bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    463                                               brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    464             next_state = BRCM_VND_A2DP_IDLE_SST;
    465             break;
    466 
    467         default:
    468             ALOGE("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state);
    469             break;
    470     }
    471     return next_state;
    472 }
    473 
    474 static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data)
    475 {
    476     tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state;
    477     switch (event) {
    478         case BRCM_VND_A2DP_OFFLOAD_START_REQ:
    479             brcm_vnd_a2dp_offload_cleanup();
    480             brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data;
    481             if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info(
    482                     &brcm_vnd_a2dp_pdata.codec_info, (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) {
    483                 ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__);
    484                 bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START,
    485                                                   brcm_vnd_a2dp_pdata.offload_params.bta_av_handle);
    486                 next_state = BRCM_VND_A2DP_IDLE_SST;
    487             } else {
    488                 brcm_vnd_a2dp_offload_configure();
    489                 next_state = BRCM_VND_A2DP_STARTING_SST;
    490             }
    491             break;
    492 
    493         case BRCM_VND_A2DP_OFFLOAD_STOP_REQ:
    494         case BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT:
    495             ALOGE("%s BRCM_VND_A2DP_OFFLOAD_STOP ABORT %d.", __FUNCTION__,
    496                   (event == BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT));
    497             brcm_vnd_a2dp_offload_cleanup();
    498             next_state = BRCM_VND_A2DP_IDLE_SST;
    499             break;
    500 
    501         default:
    502             ALOGE("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state);
    503             break;
    504     }
    505     return next_state;
    506 }
    507 
    508 static uint8_t brcm_vnd_a2dp_offload_configure()
    509 {
    510     uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
    511 
    512     BTA2DPDBG("%s", __FUNCTION__);
    513 
    514     p = msg_req;
    515     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_READ_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    516 
    517     p = msg_req;
    518     UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_PCM_PIN_FCN);
    519     UINT32_TO_STREAM(p, BRCM_A2DP_OFFLOAD_PCM_PIN_PADCNF);
    520     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_WRITE_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    521 
    522     p = msg_req;
    523     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_MGMT_EVT);
    524     UINT8_TO_STREAM(p, UIPC_OPEN_REQ);
    525     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    526 
    527     p = msg_req;
    528     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_L2C_EVT);
    529     UINT8_TO_STREAM(p, L2C_SYNC_TO_LITE_REQ);
    530     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota);
    531     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.acl_data_size);
    532     UINT16_TO_STREAM(p, !(brcm_vnd_a2dp_pdata.offload_params.is_flushable));
    533     UINT8_TO_STREAM(p, 0x02); //multi_av_data_cong_start
    534     UINT8_TO_STREAM(p, 0x00); //multi_av_data_cong_end
    535     UINT8_TO_STREAM(p, 0x04); //multi_av_data_cong_discard
    536     UINT8_TO_STREAM(p, 1); //num_stream
    537     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    538     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.remote_cid);
    539     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu);
    540     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.lm_handle);
    541     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota);
    542     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.is_flushable);
    543     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    544 
    545     p = msg_req;
    546     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_AVDT_EVT);
    547     UINT8_TO_STREAM(p, AVDT_SYNC_TO_BTC_LITE_REQ);
    548     UINT8_TO_STREAM(p, 1); //num_stream
    549     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    550     UINT32_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_source);
    551     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    552 
    553     p = msg_req;
    554     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT);
    555     UINT8_TO_STREAM(p, AUDIO_ROUTE_CONFIG_REQ);
    556     UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC);
    557     UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC_SF);
    558     UINT8_TO_STREAM(p, AUDIO_ROUTE_OUT_BTA2DP);
    559     UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC_SF);
    560     UINT8_TO_STREAM(p, AUDIO_ROUTE_SF_NA);
    561     UINT8_TO_STREAM(p, AUDIO_ROUTE_EQ_BYPASS);
    562     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    563 
    564     p = msg_req;
    565     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT);
    566     UINT8_TO_STREAM(p, AUDIO_CODEC_CONFIG_REQ);
    567     UINT16_TO_STREAM(p, AUDIO_CODEC_SBC_ENC);
    568     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.sampling_freq);
    569     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.channel_mode);
    570     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.block_length);
    571     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.num_subbands);
    572     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.alloc_method);
    573     UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.bitpool_size);
    574     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    575 
    576     p = msg_req;
    577     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT);
    578     UINT8_TO_STREAM(p, A2DP_START_REQ);
    579     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    580     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu);
    581     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    582 
    583     return 0;
    584 }
    585 
    586 static uint8_t brcm_vnd_a2dp_offload_cleanup()
    587 {
    588     uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
    589 
    590     BTA2DPDBG("%s", __FUNCTION__);
    591 
    592     p = msg_req;
    593     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT);
    594     UINT8_TO_STREAM(p, A2DP_CLEANUP_REQ);
    595     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    596     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu);
    597     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    598 
    599     p = msg_req;
    600     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_L2C_EVT);
    601     UINT8_TO_STREAM(p, L2C_REMOVE_TO_LITE_REQ);
    602     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota);
    603     UINT8_TO_STREAM(p, 1); //num_stream
    604     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    605     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    606 
    607     p = msg_req;
    608     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_MGMT_EVT);
    609     UINT8_TO_STREAM(p, UIPC_CLOSE_REQ);
    610     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    611 
    612     if (PCM_PIN_FCN_INVALID != brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn) {
    613         p = msg_req;
    614         UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn);
    615         UINT32_TO_STREAM(p, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf);
    616         brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_WRITE_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    617         brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn = PCM_PIN_FCN_INVALID;
    618     }
    619 
    620     return 0;
    621 }
    622 
    623 static uint8_t brcm_vnd_a2dp_offload_suspend()
    624 {
    625     uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
    626 
    627     BTA2DPDBG("%s", __FUNCTION__);
    628 
    629     p = msg_req;
    630     UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT);
    631     UINT8_TO_STREAM(p, A2DP_SUSPEND_REQ);
    632     UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid);
    633     brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback);
    634 
    635     return 0;
    636 }
    637 
    638 void brcm_vnd_a2dp_hci_uipc_cback(void *pmem)
    639 {
    640     HC_BT_HDR    *p_evt_buf = (HC_BT_HDR *)pmem;
    641     uint8_t     *p, len, vsc_result, uipc_opcode;
    642     uint16_t    vsc_opcode, uipc_event;
    643     HC_BT_HDR    *p_buf = NULL;
    644     bt_vendor_op_result_t status = BT_VND_OP_RESULT_SUCCESS;
    645     tBRCM_VND_A2DP_EVENT   ssm_event;
    646 
    647     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_LEN;
    648     len = *p;
    649     p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_VSC;
    650     STREAM_TO_UINT16(vsc_opcode,p);
    651     vsc_result = *p++;
    652 
    653     log_bin_to_hexstr(((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_VSC), len-1, __FUNCTION__);
    654 
    655     if (vsc_result != 0) {
    656         ALOGE("%s Failed VSC Op %04x", __FUNCTION__, vsc_opcode);
    657         status = BT_VND_OP_RESULT_FAIL;
    658     }
    659     else if (vsc_opcode == HCI_VSC_UIPC_OVER_HCI) {
    660         STREAM_TO_UINT16(uipc_event,p);
    661         uipc_opcode = *p;
    662         BTA2DPDBG("%s UIPC Event %04x UIPC Op %02x", __FUNCTION__, uipc_event, uipc_opcode);
    663 
    664         switch (uipc_event) {
    665             case BT_EVT_BTU_IPC_MGMT_EVT :
    666                 switch (uipc_opcode) {
    667                     case UIPC_OPEN_RSP    : ssm_event = BRCM_VND_UIPC_OPEN_RSP; break;
    668                     case UIPC_CLOSE_RSP    : ssm_event = BRCM_VND_UIPC_CLOSE_RSP; break;
    669                     default: status = BT_VND_OP_RESULT_FAIL;
    670                 }
    671                 break;
    672 
    673             case BT_EVT_BTU_IPC_BTM_EVT     :
    674                 switch (uipc_opcode) {
    675                     case A2DP_START_RESP:   ssm_event = BRCM_VND_A2DP_START_RSP; break;
    676                     case A2DP_SUSPEND_RESP: ssm_event = BRCM_VND_A2DP_SUSPEND_RSP; break;
    677                     case A2DP_CLEANUP_RESP: ssm_event = BRCM_VND_A2DP_CLEANUP_RSP; break;
    678                     case AUDIO_CODEC_CONFIG_RESP: ssm_event = BRCM_VND_AUDIO_CODEC_CONFIG_RSP; break;
    679                     case AUDIO_ROUTE_CONFIG_RESP: ssm_event = BRCM_VND_AUDIO_ROUTE_CONFIG_RSP; break;
    680                     default: status = BT_VND_OP_RESULT_FAIL;
    681                 }
    682                 break;
    683 
    684             case BT_EVT_BTU_IPC_L2C_EVT  :
    685                 switch (uipc_opcode) {
    686                     case L2C_REMOVE_TO_LITE_RESP: ssm_event = BRCM_VND_L2C_REMOVE_TO_LITE_RSP; break;
    687                     case L2C_SYNC_TO_LITE_RESP:   ssm_event = BRCM_VND_L2C_SYNC_TO_LITE_RSP; break;
    688                     default: status = BT_VND_OP_RESULT_FAIL;
    689                 }
    690                 break;
    691 
    692             case BT_EVT_BTU_IPC_AVDT_EVT :
    693                 if (uipc_opcode == AVDT_SYNC_TO_BTC_LITE_RESP) {
    694                     ssm_event = BRCM_VND_SYNC_TO_BTC_LITE_RSP;
    695                     break;
    696                 }
    697 
    698             default:
    699                 status = BT_VND_OP_RESULT_FAIL;
    700                 break;
    701         }
    702         if (status == BT_VND_OP_RESULT_SUCCESS)
    703             brcm_vnd_a2dp_ssm_execute(ssm_event, p);
    704     }
    705     else if (vsc_opcode == HCI_VSC_READ_PCM_PINS) {
    706         STREAM_TO_UINT8(brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn, p);
    707         STREAM_TO_UINT32(brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf, p);
    708         BTA2DPDBG("%s HCI_VSC_READ_PCM_PINS %02x %08x", __FUNCTION__,
    709                   brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf);
    710     }
    711 
    712     if (status != BT_VND_OP_RESULT_SUCCESS)
    713         brcm_vnd_a2dp_ssm_execute(BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT, NULL);
    714 
    715     /* Free the RX event buffer */
    716     bt_vendor_cbacks->dealloc(p_evt_buf);
    717 }
    718 
    719 void brcm_vnd_a2dp_init()
    720 {
    721     if (!bt_vendor_cbacks)
    722         return;
    723 
    724     ALOGD("%s ", __FUNCTION__);
    725     brcm_vnd_a2dp_ssm_execute(BRCM_VND_A2DP_OFFLOAD_INIT_REQ, NULL);
    726 }
    727 
    728 int brcm_vnd_a2dp_execute(bt_vendor_opcode_t opcode, void *ev_data)
    729 {
    730     tBRCM_VND_A2DP_EVENT ssm_event = (opcode == BT_VND_OP_A2DP_OFFLOAD_START)?
    731         BRCM_VND_A2DP_OFFLOAD_START_REQ:BRCM_VND_A2DP_OFFLOAD_STOP_REQ;
    732 
    733     ALOGD("%s opcode %d , state %d", __FUNCTION__, opcode, brcm_vnd_a2dp_pdata.state);
    734 
    735     return brcm_vnd_a2dp_ssm_execute(ssm_event, ev_data);
    736 }
    737 
    738 
    739