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