From 8a1508699619f12a0847faa4e98e51601b283a73 Mon Sep 17 00:00:00 2001 From: Chris Elliott Date: Wed, 2 Dec 2015 13:48:50 -0800 Subject: DO NOT MERGE Final Revert "A2DP Offload BRCM vendor specific implementation" This reverts commit d51ab12cc1e7b02279b45f91c2f2f9a9b4a1404e. --- src/bt_vendor_brcm_a2dp.c | 744 ---------------------------------------------- 1 file changed, 744 deletions(-) delete mode 100644 src/bt_vendor_brcm_a2dp.c (limited to 'src') diff --git a/src/bt_vendor_brcm_a2dp.c b/src/bt_vendor_brcm_a2dp.c deleted file mode 100644 index 45d4295..0000000 --- a/src/bt_vendor_brcm_a2dp.c +++ /dev/null @@ -1,744 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 Motorola Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ******************************************************************************/ - -/****************************************************************************** - * - * This is the stream state machine for the BRCM offloaded advanced audio. - * - ******************************************************************************/ - -#define LOG_TAG "bt_vnd_a2dp" -#define LOG_NDEBUG 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "bt_hci_bdroid.h" -#include "bt_vendor_brcm_a2dp.h" -#include "a2d_api.h" -#include "a2d_sbc.h" - -#if (BTA2DP_DEBUG == TRUE) -#define BTA2DPDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} -#else -#define BTA2DPDBG(param, ...) {} -#endif - -/***************************************************************************** -** Constants and types -*****************************************************************************/ - -typedef void (*hci_cback)(void *); - -typedef enum -{ - BRCM_VND_A2DP_OFFLOAD_INIT_REQ, - BRCM_VND_A2DP_OFFLOAD_START_REQ, - BRCM_VND_A2DP_OFFLOAD_STOP_REQ, - BRCM_VND_UIPC_OPEN_RSP, - BRCM_VND_L2C_SYNC_TO_LITE_RSP, - BRCM_VND_SYNC_TO_BTC_LITE_RSP, - BRCM_VND_AUDIO_CODEC_CONFIG_RSP, - BRCM_VND_AUDIO_ROUTE_CONFIG_RSP, - BRCM_VND_UIPC_CLOSE_RSP, - BRCM_VND_L2C_REMOVE_TO_LITE_RSP, - BRCM_VND_A2DP_START_RSP, - BRCM_VND_A2DP_SUSPEND_RSP, - BRCM_VND_STREAM_STOP_RSP, - BRCM_VND_A2DP_CLEANUP_RSP, - BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT, -} tBRCM_VND_A2DP_EVENT; - -/* state machine states */ -typedef enum -{ - BRCM_VND_A2DP_INVALID_SST = -1, - BRCM_VND_A2DP_IDLE_SST, - BRCM_VND_A2DP_STARTING_SST, - BRCM_VND_A2DP_STREAM_SST, -} -tBRCM_VND_A2DP_SST_STATES; - -static uint8_t brcm_vnd_a2dp_offload_cleanup(); -static uint8_t brcm_vnd_a2dp_offload_suspend(); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_enter(tBRCM_VND_A2DP_EVENT event); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_enter(tBRCM_VND_A2DP_EVENT event); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_enter(tBRCM_VND_A2DP_EVENT event); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data); -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data); -static void brcm_vnd_a2dp_hci_uipc_cback(void *pmem); - -typedef struct { - uint8_t fcn; - uint32_t pad_conf; -} -tBRCM_VND_PCM_CONF; - -typedef struct { - tBRCM_VND_A2DP_SST_STATES state; - tCODEC_INFO_SBC codec_info; - tBRCM_VND_PCM_CONF pcmi2s_pinmux; - bt_vendor_op_a2dp_offload_t offload_params; -} -tBRCM_VND_A2DP_PDATA; - -typedef struct { - tBRCM_VND_A2DP_SST_STATES (*enter)(tBRCM_VND_A2DP_EVENT event); - tBRCM_VND_A2DP_SST_STATES (*process_event)(tBRCM_VND_A2DP_EVENT event, void *ev_data); -} -tBRCM_VND_A2DP_SST_STATE; - -/* state table */ -static tBRCM_VND_A2DP_SST_STATE brcm_vnd_a2dp_sst_tbl[] = -{ - {brcm_vnd_a2dp_sm_idle_enter, brcm_vnd_a2dp_sm_idle_process_ev}, - {brcm_vnd_a2dp_sm_starting_enter, brcm_vnd_a2dp_sm_starting_process_ev}, - {brcm_vnd_a2dp_sm_stream_enter, brcm_vnd_a2dp_sm_stream_process_ev}, -}; - -static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; -static tBRCM_VND_A2DP_PDATA brcm_vnd_a2dp_pdata = { .state = BRCM_VND_A2DP_INVALID_SST }; - - -/******************************************************************************* -** Local Utility Functions -*******************************************************************************/ - -static void log_bin_to_hexstr(uint8_t *bin, uint8_t binsz, const char *log_tag) -{ -#if (BTA2DP_DEBUG == TRUE) - char *str, hex_str[]= "0123456789abcdef"; - uint8_t i; - - str = (char *)malloc(binsz * 3); - if (!binsz) { - ALOGE("%s alloc failed", __FUNCTION__); - return; - } - - for (i = 0; i < binsz; i++) { - str[(i * 3) + 0] = hex_str[(bin[i] >> 4) & 0x0F]; - str[(i * 3) + 1] = hex_str[(bin[i] ) & 0x0F]; - str[(i * 3) + 2] = ' '; - } - str[(binsz * 3) - 1] = 0x00; - BTA2DPDBG("%s %s", log_tag, str); -#endif -} - -static uint8_t brcm_vnd_a2dp_send_hci_vsc(uint16_t cmd, uint8_t *payload, uint8_t len, hci_cback cback) -{ - HC_BT_HDR *p_buf; - uint8_t *p, status; - uint16_t opcode; - - // Perform Opening configure cmds. // - if (bt_vendor_cbacks) { - p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc( - BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + len); - if (p_buf) - { - p_buf->event = MSG_STACK_TO_HC_HCI_CMD; - p_buf->offset = 0; - p_buf->layer_specific = 0; - p_buf->len = HCI_CMD_PREAMBLE_SIZE + len; - p = (uint8_t *)(p_buf + 1); - - UINT16_TO_STREAM(p, cmd); - *p++ = len; - memcpy(p, payload, len); - - //BTA2DPDBG("%s Cmd %04x UIPC Event %02x%02x UIPC Op %02x Len %d", __FUNCTION__, cmd, event, payload[1], payload[0], payload[2], len); - log_bin_to_hexstr((uint8_t *)(p_buf + 1), HCI_CMD_PREAMBLE_SIZE + len, __FUNCTION__); - - if (bt_vendor_cbacks->xmit_cb(cmd, p_buf, cback)) - { - return BT_VND_OP_RESULT_SUCCESS; - } - bt_vendor_cbacks->dealloc(p_buf); - } - } - return BT_VND_OP_RESULT_FAIL; -} - -static void brcm_vnd_map_a2d_uipc_codec_info(tCODEC_INFO_SBC *codec_info) -{ - switch(codec_info->sampling_freq) { - case A2D_SBC_IE_SAMP_FREQ_16: - codec_info->sampling_freq = CODEC_INFO_SBC_SF_16K; break; - case A2D_SBC_IE_SAMP_FREQ_32: - codec_info->sampling_freq = CODEC_INFO_SBC_SF_32K; break; - case A2D_SBC_IE_SAMP_FREQ_44: - codec_info->sampling_freq = CODEC_INFO_SBC_SF_44K; break; - case A2D_SBC_IE_SAMP_FREQ_48: - codec_info->sampling_freq = CODEC_INFO_SBC_SF_48K; break; - - } - switch(codec_info->channel_mode) { - case A2D_SBC_IE_CH_MD_MONO: - codec_info->channel_mode = CODEC_INFO_SBC_CH_MONO; break; - case A2D_SBC_IE_CH_MD_DUAL: - codec_info->channel_mode = CODEC_INFO_SBC_CH_DUAL; break; - case A2D_SBC_IE_CH_MD_STEREO: - codec_info->channel_mode = CODEC_INFO_SBC_CH_STEREO; break; - case A2D_SBC_IE_CH_MD_JOINT: - codec_info->channel_mode = CODEC_INFO_SBC_CH_JS; break; - } - switch(codec_info->block_length) { - case A2D_SBC_IE_BLOCKS_4: - codec_info->block_length = CODEC_INFO_SBC_BLOCK_4; break; - case A2D_SBC_IE_BLOCKS_8: - codec_info->block_length = CODEC_INFO_SBC_BLOCK_8; break; - case A2D_SBC_IE_BLOCKS_12: - codec_info->block_length = CODEC_INFO_SBC_BLOCK_12; break; - case A2D_SBC_IE_BLOCKS_16: - codec_info->block_length = CODEC_INFO_SBC_BLOCK_16; break; - } - switch(codec_info->alloc_method) { - case A2D_SBC_IE_ALLOC_MD_S: - codec_info->alloc_method = CODEC_INFO_SBC_ALLOC_SNR; break; - case A2D_SBC_IE_ALLOC_MD_L: - codec_info->alloc_method = CODEC_INFO_SBC_ALLOC_LOUDNESS; break; - } - switch(codec_info->num_subbands) { - case A2D_SBC_IE_SUBBAND_4: - codec_info->num_subbands = CODEC_INFO_SBC_SUBBAND_4; break; - case A2D_SBC_IE_SUBBAND_8: - codec_info->num_subbands = CODEC_INFO_SBC_SUBBAND_8; break; - } -} - -static tA2D_STATUS bcrm_vnd_a2dp_parse_codec_info(tCODEC_INFO_SBC *parsed_info, uint8_t *codec_info) -{ - tA2D_STATUS status = A2D_SUCCESS; - UINT8 losc; - UINT8 mt; - - BTA2DPDBG("%s", __FUNCTION__); - - if( parsed_info == NULL || codec_info == NULL) - status = A2D_FAIL; - else - { - losc = *codec_info++; - mt = *codec_info++; - /* If the function is called for the wrong Media Type or Media Codec Type */ - if(losc != A2D_SBC_INFO_LEN || *codec_info != A2D_MEDIA_CT_SBC) - status = A2D_WRONG_CODEC; - else - { - codec_info++; - parsed_info->sampling_freq = *codec_info & A2D_SBC_IE_SAMP_FREQ_MSK; - parsed_info->channel_mode = *codec_info & A2D_SBC_IE_CH_MD_MSK; - codec_info++; - parsed_info->block_length = *codec_info & A2D_SBC_IE_BLOCKS_MSK; - parsed_info->num_subbands = *codec_info & A2D_SBC_IE_SUBBAND_MSK; - parsed_info->alloc_method = *codec_info & A2D_SBC_IE_ALLOC_MD_MSK; - codec_info += 2; - parsed_info->bitpool_size = *codec_info; // MAX BITPOOL // - - if(MULTI_BIT_SET(parsed_info->sampling_freq)) - status = A2D_BAD_SAMP_FREQ; - if(MULTI_BIT_SET(parsed_info->channel_mode)) - status = A2D_BAD_CH_MODE; - if(MULTI_BIT_SET(parsed_info->block_length)) - status = A2D_BAD_BLOCK_LEN; - if(MULTI_BIT_SET(parsed_info->num_subbands)) - status = A2D_BAD_SUBBANDS; - if(MULTI_BIT_SET(parsed_info->alloc_method)) - status = A2D_BAD_ALLOC_MTHD; - if(parsed_info->bitpool_size < A2D_SBC_IE_MIN_BITPOOL || parsed_info->bitpool_size > A2D_SBC_IE_MAX_BITPOOL ) - status = A2D_BAD_MIN_BITPOOL; - - if(status == A2D_SUCCESS) - brcm_vnd_map_a2d_uipc_codec_info(parsed_info); - - BTA2DPDBG("%s STATUS %d parsed info : SampF %02x, ChnMode %02x, BlockL %02x, NSubB %02x, alloc %02x, bitpool %02x", - __FUNCTION__, status, parsed_info->sampling_freq, parsed_info->channel_mode, parsed_info->block_length, - parsed_info->num_subbands, parsed_info->alloc_method, parsed_info->bitpool_size); - - } - } - return status; -} - -/******************************************************************************* -** State Machine Functions -*******************************************************************************/ - -/******************************************************************************* -** -** Function brcm_vnd_a2dp_ssm_execute -** -** Description Stream state machine event handling function for AV -** -** -** Returns void -** -*******************************************************************************/ -int brcm_vnd_a2dp_ssm_execute(tBRCM_VND_A2DP_EVENT event, void *ev_data) -{ - tBRCM_VND_A2DP_SST_STATE *state_table; - tBRCM_VND_A2DP_SST_STATES next_state; - - BTA2DPDBG("%s ev %d state %d", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state); - - pthread_mutex_lock(&g_mutex); - - if (brcm_vnd_a2dp_pdata.state != BRCM_VND_A2DP_INVALID_SST) { - state_table = &brcm_vnd_a2dp_sst_tbl[brcm_vnd_a2dp_pdata.state]; - /* process event */ - next_state = state_table->process_event(event, ev_data); - } else if (BRCM_VND_A2DP_OFFLOAD_INIT_REQ == event) { - next_state = BRCM_VND_A2DP_IDLE_SST; - } - else { - pthread_mutex_unlock(&g_mutex); - return BT_VND_OP_RESULT_FAIL; - } - - /* transition stae */ - while (next_state != brcm_vnd_a2dp_pdata.state) { - brcm_vnd_a2dp_pdata.state = next_state; - state_table = &brcm_vnd_a2dp_sst_tbl[next_state]; - if (state_table->enter) - next_state = state_table->enter(event); - } - - pthread_mutex_unlock(&g_mutex); - return BT_VND_OP_RESULT_SUCCESS; -} - -/* state machine actions */ - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_enter(tBRCM_VND_A2DP_EVENT event) -{ - UNUSED(event); - BTA2DPDBG("%s", __FUNCTION__); - brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn = PCM_PIN_FCN_INVALID; - return brcm_vnd_a2dp_pdata.state; -} - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_enter(tBRCM_VND_A2DP_EVENT event) -{ - UNUSED(event); - uint8_t *p, msg_req[HCI_CMD_MAX_LEN]; - BTA2DPDBG("%s", __FUNCTION__); - - p = msg_req; - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_READ_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_PCM_PIN_FCN); - UINT32_TO_STREAM(p, BRCM_A2DP_OFFLOAD_PCM_PIN_PADCNF); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_WRITE_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_MGMT_EVT); - UINT8_TO_STREAM(p, UIPC_OPEN_REQ); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_L2C_EVT); - UINT8_TO_STREAM(p, L2C_SYNC_TO_LITE_REQ); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.acl_data_size); - UINT16_TO_STREAM(p, !(brcm_vnd_a2dp_pdata.offload_params.is_flushable)); - UINT8_TO_STREAM(p, 0x02); //multi_av_data_cong_start - UINT8_TO_STREAM(p, 0x00); //multi_av_data_cong_end - UINT8_TO_STREAM(p, 0x04); //multi_av_data_cong_discard - UINT8_TO_STREAM(p, 1); //num_stream - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.remote_cid); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.lm_handle); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.is_flushable); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_AVDT_EVT); - UINT8_TO_STREAM(p, AVDT_SYNC_TO_BTC_LITE_REQ); - UINT8_TO_STREAM(p, 1); //num_stream - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - UINT32_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_source); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT); - UINT8_TO_STREAM(p, AUDIO_ROUTE_CONFIG_REQ); - UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC); - UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC_SF); - UINT8_TO_STREAM(p, AUDIO_ROUTE_OUT_BTA2DP); - UINT8_TO_STREAM(p, BRCM_A2DP_OFFLOAD_SRC_SF); - UINT8_TO_STREAM(p, AUDIO_ROUTE_SF_NA); - UINT8_TO_STREAM(p, AUDIO_ROUTE_EQ_BYPASS); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT); - UINT8_TO_STREAM(p, AUDIO_CODEC_CONFIG_REQ); - UINT16_TO_STREAM(p, AUDIO_CODEC_SBC_ENC); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.sampling_freq); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.channel_mode); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.block_length); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.num_subbands); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.alloc_method); - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.codec_info.bitpool_size); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT); - UINT8_TO_STREAM(p, A2DP_START_REQ); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - return brcm_vnd_a2dp_pdata.state; -} - - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_enter(tBRCM_VND_A2DP_EVENT event) -{ - UNUSED(event); - ALOGV("%s", __FUNCTION__); - - return brcm_vnd_a2dp_pdata.state; -} - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_idle_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data) -{ - tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state; - - switch (event) { - case BRCM_VND_A2DP_OFFLOAD_START_REQ: - brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data; - if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info( &brcm_vnd_a2dp_pdata.codec_info, - (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) { - ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__); - } - - next_state = BRCM_VND_A2DP_STARTING_SST; - break; - - default: - ALOGV("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state); - break; - } - return next_state; -} - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_starting_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data) -{ - tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state; - uint8_t status, *p; - switch (event) { - case BRCM_VND_A2DP_OFFLOAD_START_REQ: - brcm_vnd_a2dp_offload_cleanup(); - brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data; - if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info( - &brcm_vnd_a2dp_pdata.codec_info, (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) { - ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__); - } - - next_state = BRCM_VND_A2DP_STARTING_SST; - break; - - - case BRCM_VND_A2DP_OFFLOAD_STOP_REQ: - brcm_vnd_a2dp_offload_cleanup(); - next_state = BRCM_VND_A2DP_IDLE_SST; - break; - - case BRCM_VND_UIPC_OPEN_RSP: { - uint8_t num_streams; - uint16_t maj_ver, min_ver; - p = (uint8_t*)ev_data + offsetof(tUIPC_OPEN_RSP, status); - STREAM_TO_UINT8(status,p); - STREAM_TO_UINT16(maj_ver,p); - STREAM_TO_UINT16(min_ver,p); - STREAM_TO_UINT8(num_streams,p); - // TODO Verify Params // - if (status) { - ALOGE("%s BRCM_VND_UIPC_OPEN_RSP %02x FAILED", __FUNCTION__, status); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - } - } - break; - - case BRCM_VND_L2C_SYNC_TO_LITE_RSP: - status = *((uint8_t*)ev_data + offsetof(tL2C_SYNC_TO_LITE_RESP, stream.status)); - if (status) { - ALOGE("%s L2C_SYNC_TO_LITE_RESP %02x FAILED", __FUNCTION__, status); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - } - break; - - case BRCM_VND_SYNC_TO_BTC_LITE_RSP: - status = *((uint8_t*)ev_data + offsetof(tAVDT_SYNC_TO_BTC_LITE_RESP, status)); - if (status) { - ALOGE("%s AVDT_SYNC_TO_BTC_LITE_RESP %02x FAILED", __FUNCTION__, status); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - } - break; - - case BRCM_VND_AUDIO_ROUTE_CONFIG_RSP: - status = *((uint8_t*)ev_data + offsetof(tAUDIO_ROUTE_CONFIG_RESP, status)); - if (status) { - ALOGE("%s AUDIO_ROUTE_CONFIG_RESP %02x FAILED", __FUNCTION__, status); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - } - break; - - case BRCM_VND_AUDIO_CODEC_CONFIG_RSP: - status = *((uint8_t*)ev_data + offsetof(tAUDIO_CODEC_CONFIG_RESP, status)); - if (status) { - ALOGE("%s BRCM_VND_AUDIO_CODEC_CONFIG_RSP %02x FAILED", __FUNCTION__, status); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - } - break; - - case BRCM_VND_A2DP_START_RSP: - /* status = *((uint8_t*)ev_data + offsetof(tA2DP_GENERIC_RESP, status)); */ - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_SUCCESS, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_STREAM_SST; - break; - - case BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT: - ALOGE("%s BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT", __FUNCTION__); - brcm_vnd_a2dp_offload_cleanup(); - bt_vendor_cbacks->a2dp_offload_cb(BT_VND_OP_RESULT_FAIL, BT_VND_OP_A2DP_OFFLOAD_START, - brcm_vnd_a2dp_pdata.offload_params.bta_av_handle); - next_state = BRCM_VND_A2DP_IDLE_SST; - break; - - default: - ALOGE("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state); - break; - } - return next_state; -} - -static tBRCM_VND_A2DP_SST_STATES brcm_vnd_a2dp_sm_stream_process_ev(tBRCM_VND_A2DP_EVENT event, void *ev_data) -{ - tBRCM_VND_A2DP_SST_STATES next_state = brcm_vnd_a2dp_pdata.state; - switch (event) { - case BRCM_VND_A2DP_OFFLOAD_START_REQ: - brcm_vnd_a2dp_offload_cleanup(); - brcm_vnd_a2dp_pdata.offload_params = *(bt_vendor_op_a2dp_offload_t*)ev_data; - if (A2D_SUCCESS != bcrm_vnd_a2dp_parse_codec_info( - &brcm_vnd_a2dp_pdata.codec_info, (uint8_t *)brcm_vnd_a2dp_pdata.offload_params.codec_info)) { - ALOGE("%s CodecConfig BT_VND_OP_A2DP_OFFLOAD_START FAILED", __FUNCTION__); - } - next_state = BRCM_VND_A2DP_STARTING_SST; - break; - - case BRCM_VND_A2DP_OFFLOAD_STOP_REQ: - case BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT: - ALOGE("%s BRCM_VND_A2DP_OFFLOAD_STOP ABORT %d.", __FUNCTION__, - (event == BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT)); - brcm_vnd_a2dp_offload_cleanup(); - next_state = BRCM_VND_A2DP_IDLE_SST; - break; - - default: - ALOGE("%s Unexpected Event %d in State %d, IGNORE", __FUNCTION__, event, brcm_vnd_a2dp_pdata.state); - break; - } - return next_state; -} - -static uint8_t brcm_vnd_a2dp_offload_cleanup() -{ - uint8_t *p, msg_req[HCI_CMD_MAX_LEN]; - - BTA2DPDBG("%s", __FUNCTION__); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT); - UINT8_TO_STREAM(p, A2DP_CLEANUP_REQ); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.stream_mtu); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_L2C_EVT); - UINT8_TO_STREAM(p, L2C_REMOVE_TO_LITE_REQ); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.xmit_quota); - UINT8_TO_STREAM(p, 1); //num_stream - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_MGMT_EVT); - UINT8_TO_STREAM(p, UIPC_CLOSE_REQ); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - if (PCM_PIN_FCN_INVALID != brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn) { - p = msg_req; - UINT8_TO_STREAM(p, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn); - UINT32_TO_STREAM(p, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_WRITE_PCM_PINS, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - } - - return 0; -} - -static uint8_t brcm_vnd_a2dp_offload_suspend() -{ - uint8_t *p, msg_req[HCI_CMD_MAX_LEN]; - - BTA2DPDBG("%s", __FUNCTION__); - - p = msg_req; - UINT16_TO_STREAM(p, BT_EVT_BTU_IPC_BTM_EVT); - UINT8_TO_STREAM(p, A2DP_SUSPEND_REQ); - UINT16_TO_STREAM(p, brcm_vnd_a2dp_pdata.offload_params.local_cid); - brcm_vnd_a2dp_send_hci_vsc(HCI_VSC_UIPC_OVER_HCI, msg_req, (uint8_t)(p - msg_req), brcm_vnd_a2dp_hci_uipc_cback); - - return 0; -} - -void brcm_vnd_a2dp_hci_uipc_cback(void *pmem) -{ - HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)pmem; - uint8_t *p, len, vsc_result, uipc_opcode; - uint16_t vsc_opcode, uipc_event; - HC_BT_HDR *p_buf = NULL; - bt_vendor_op_result_t status = BT_VND_OP_RESULT_SUCCESS; - tBRCM_VND_A2DP_EVENT ssm_event; - - p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_LEN; - len = *p; - p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_VSC; - STREAM_TO_UINT16(vsc_opcode,p); - vsc_result = *p++; - - log_bin_to_hexstr(((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_VSC), len-1, __FUNCTION__); - - if (vsc_result != 0) { - ALOGE("%s Failed VSC Op %04x", __FUNCTION__, vsc_opcode); - status = BT_VND_OP_RESULT_FAIL; - } - else if (vsc_opcode == HCI_VSC_UIPC_OVER_HCI) { - STREAM_TO_UINT16(uipc_event,p); - uipc_opcode = *p; - BTA2DPDBG("%s UIPC Event %04x UIPC Op %02x", __FUNCTION__, uipc_event, uipc_opcode); - - switch (uipc_event) { - case BT_EVT_BTU_IPC_MGMT_EVT : - switch (uipc_opcode) { - case UIPC_OPEN_RSP : ssm_event = BRCM_VND_UIPC_OPEN_RSP; break; - case UIPC_CLOSE_RSP : ssm_event = BRCM_VND_UIPC_CLOSE_RSP; break; - default: status = BT_VND_OP_RESULT_FAIL; - } - break; - - case BT_EVT_BTU_IPC_BTM_EVT : - switch (uipc_opcode) { - case A2DP_START_RESP: ssm_event = BRCM_VND_A2DP_START_RSP; break; - case A2DP_SUSPEND_RESP: ssm_event = BRCM_VND_A2DP_SUSPEND_RSP; break; - case A2DP_CLEANUP_RESP: ssm_event = BRCM_VND_A2DP_CLEANUP_RSP; break; - case AUDIO_CODEC_CONFIG_RESP: ssm_event = BRCM_VND_AUDIO_CODEC_CONFIG_RSP; break; - case AUDIO_ROUTE_CONFIG_RESP: ssm_event = BRCM_VND_AUDIO_ROUTE_CONFIG_RSP; break; - default: status = BT_VND_OP_RESULT_FAIL; - } - break; - - case BT_EVT_BTU_IPC_L2C_EVT : - switch (uipc_opcode) { - case L2C_REMOVE_TO_LITE_RESP: ssm_event = BRCM_VND_L2C_REMOVE_TO_LITE_RSP; break; - case L2C_SYNC_TO_LITE_RESP: ssm_event = BRCM_VND_L2C_SYNC_TO_LITE_RSP; break; - default: status = BT_VND_OP_RESULT_FAIL; - } - break; - - case BT_EVT_BTU_IPC_AVDT_EVT : - if (uipc_opcode == AVDT_SYNC_TO_BTC_LITE_RESP) { - ssm_event = BRCM_VND_SYNC_TO_BTC_LITE_RSP; - break; - } - - default: - status = BT_VND_OP_RESULT_FAIL; - break; - } - if (status == BT_VND_OP_RESULT_SUCCESS) - brcm_vnd_a2dp_ssm_execute(ssm_event, p); - } - else if (vsc_opcode == HCI_VSC_READ_PCM_PINS) { - STREAM_TO_UINT8(brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn, p); - STREAM_TO_UINT32(brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf, p); - BTA2DPDBG("%s HCI_VSC_READ_PCM_PINS %02x %08x", __FUNCTION__, - brcm_vnd_a2dp_pdata.pcmi2s_pinmux.fcn, brcm_vnd_a2dp_pdata.pcmi2s_pinmux.pad_conf); - } - - if (status != BT_VND_OP_RESULT_SUCCESS) - brcm_vnd_a2dp_ssm_execute(BRCM_VND_A2DP_OFFLOAD_FAILED_ABORT, NULL); - - /* Free the RX event buffer */ - bt_vendor_cbacks->dealloc(p_evt_buf); -} - -void brcm_vnd_a2dp_init() -{ - if (!bt_vendor_cbacks) - return; - - ALOGD("%s ", __FUNCTION__); - brcm_vnd_a2dp_ssm_execute(BRCM_VND_A2DP_OFFLOAD_INIT_REQ, NULL); -} - -int brcm_vnd_a2dp_execute(bt_vendor_opcode_t opcode, void *ev_data) -{ - tBRCM_VND_A2DP_EVENT ssm_event = (opcode == BT_VND_OP_A2DP_OFFLOAD_START)? - BRCM_VND_A2DP_OFFLOAD_START_REQ:BRCM_VND_A2DP_OFFLOAD_STOP_REQ; - - ALOGD("%s opcode %d ", __FUNCTION__, opcode); - - return brcm_vnd_a2dp_ssm_execute(ssm_event, ev_data); -} - - -- cgit v1.2.3