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 
log_bin_to_hexstr(uint8_t * bin,uint8_t binsz,const char * log_tag)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 
brcm_vnd_a2dp_send_hci_vsc(uint16_t cmd,uint8_t * payload,uint8_t len,hci_cback cback)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 
brcm_vnd_map_a2d_uipc_codec_info(tCODEC_INFO_SBC * codec_info)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 
bcrm_vnd_a2dp_parse_codec_info(tCODEC_INFO_SBC * parsed_info,uint8_t * codec_info)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 *******************************************************************************/
brcm_vnd_a2dp_ssm_execute(tBRCM_VND_A2DP_EVENT event,void * ev_data)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 
brcm_vnd_a2dp_sm_idle_process_ev(tBRCM_VND_A2DP_EVENT event,void * ev_data)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 
brcm_vnd_a2dp_sm_starting_process_ev(tBRCM_VND_A2DP_EVENT event,void * ev_data)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 
brcm_vnd_a2dp_sm_stream_process_ev(tBRCM_VND_A2DP_EVENT event,void * ev_data)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 
brcm_vnd_a2dp_offload_configure()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 
brcm_vnd_a2dp_offload_cleanup()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 
brcm_vnd_a2dp_offload_suspend()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 
brcm_vnd_a2dp_hci_uipc_cback(void * pmem)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 
brcm_vnd_a2dp_init()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 
brcm_vnd_a2dp_execute(bt_vendor_opcode_t opcode,void * ev_data)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