summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Johnson <zachoverflow@google.com>2016-02-04 23:43:33 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2016-02-04 23:43:33 +0000
commit47aab49512c74389d1e46629d2f858f319495204 (patch)
tree508254bbd37be5a6f5b1e0e8ff1500873b2cd4c3
parent776dd81667c379113706d82aef24aaab7b5e04f7 (diff)
parentcea4ce624550664140119b71f75c3f33ec39fe83 (diff)
downloadlibbt-brillo-m10-dev.tar.gz
Merge "Fix undefined behavior configuring SCO for I2S only devices."android-n-preview-1brillo-m10-releasebrillo-m10-dev
-rwxr-xr-xsrc/hardware.c136
1 files changed, 60 insertions, 76 deletions
diff --git a/src/hardware.c b/src/hardware.c
index bf59896..9b636be 100755
--- a/src/hardware.c
+++ b/src/hardware.c
@@ -30,6 +30,7 @@
#include <utils/Log.h>
#include <sys/types.h>
+#include <stdbool.h>
#include <sys/stat.h>
#include <signal.h>
#include <time.h>
@@ -257,7 +258,8 @@ static uint8_t sco_bus_wbs_clock_rate = INVALID_SCO_CLOCK_RATE;
/******************************************************************************
** Static functions
******************************************************************************/
-static void hw_sco_i2spcm_config(void *p_mem, uint16_t codec);
+static void hw_sco_i2spcm_config(uint16_t codec);
+static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec);
/******************************************************************************
** Controller Initialization Static Functions
@@ -1070,7 +1072,7 @@ static void hw_set_MSBC_codec_cback(void *p_mem)
{
/* whenever update the codec enable/disable, need to update I2SPCM */
ALOGI("SCO I2S interface change the sample rate to 16K");
- hw_sco_i2spcm_config(p_mem, SCO_CODEC_MSBC);
+ hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_MSBC);
}
/*******************************************************************************
@@ -1086,7 +1088,7 @@ static void hw_set_CVSD_codec_cback(void *p_mem)
{
/* whenever update the codec enable/disable, need to update I2SPCM */
ALOGI("SCO I2S interface change the sample rate to 8K");
- hw_sco_i2spcm_config(p_mem, SCO_CODEC_CVSD);
+ hw_sco_i2spcm_config_from_command(p_mem, SCO_CODEC_CVSD);
}
#endif // SCO_CFG_INCLUDED
@@ -1297,21 +1299,7 @@ void hw_sco_config(void)
*/
if (SCO_INTERFACE_I2S == sco_bus_interface) {
- HC_BT_HDR *p_buf = NULL;
- uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
-
- if (bt_vendor_cbacks)
- p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
-
- if (p_buf) {
- p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
- p_buf->offset = 0;
- p_buf->layer_specific = 0;
- p_buf->len = cmd_u16;
- hw_sco_i2spcm_config(p_buf, SCO_CODEC_CVSD);
- } else {
- ALOGE("Cannot allocate memory for p_buf in hw_sco_config sco config");
- }
+ hw_sco_i2spcm_config(SCO_CODEC_CVSD);
}
if (bt_vendor_cbacks)
@@ -1320,6 +1308,21 @@ void hw_sco_config(void)
}
}
+static void hw_sco_i2spcm_config_from_command(void *p_mem, uint16_t codec) {
+ HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
+ bool command_success = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0;
+
+ /* Free the RX event buffer */
+ if (bt_vendor_cbacks)
+ bt_vendor_cbacks->dealloc(p_evt_buf);
+
+ if (command_success)
+ hw_sco_i2spcm_config(codec);
+ else if (bt_vendor_cbacks)
+ bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
+}
+
+
/*******************************************************************************
**
** Function hw_sco_i2spcm_config
@@ -1329,76 +1332,57 @@ void hw_sco_config(void)
** Returns None
**
*******************************************************************************/
-static void hw_sco_i2spcm_config(void *p_mem, uint16_t codec)
+static void hw_sco_i2spcm_config(uint16_t codec)
{
- HC_BT_HDR *p_evt_buf = (HC_BT_HDR *)p_mem;
- bt_vendor_op_result_t status = BT_VND_OP_RESULT_FAIL;
+ HC_BT_HDR *p_buf = NULL;
+ uint8_t *p, ret;
+ uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
- if (*((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE) == 0)
- {
- status = BT_VND_OP_RESULT_SUCCESS;
- }
-
- /* Free the RX event buffer */
if (bt_vendor_cbacks)
- bt_vendor_cbacks->dealloc(p_evt_buf);
+ p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
- if (status == BT_VND_OP_RESULT_SUCCESS)
+ if (p_buf)
{
- HC_BT_HDR *p_buf = NULL;
- uint8_t *p, ret;
- uint16_t cmd_u16 = HCI_CMD_PREAMBLE_SIZE + SCO_I2SPCM_PARAM_SIZE;
+ p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
+ p_buf->offset = 0;
+ p_buf->layer_specific = 0;
+ p_buf->len = cmd_u16;
- if (bt_vendor_cbacks)
- p_buf = (HC_BT_HDR *)bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + cmd_u16);
+ p = (uint8_t *)(p_buf + 1);
- if (p_buf)
+ UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
+ *p++ = SCO_I2SPCM_PARAM_SIZE;
+ if (codec == SCO_CODEC_CVSD)
{
- p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
- p_buf->offset = 0;
- p_buf->layer_specific = 0;
- p_buf->len = cmd_u16;
-
- p = (uint8_t *)(p_buf + 1);
-
- UINT16_TO_STREAM(p, HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM);
- *p++ = SCO_I2SPCM_PARAM_SIZE;
- if (codec == SCO_CODEC_CVSD)
- {
- bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
- bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
- }
- else if (codec == SCO_CODEC_MSBC)
- {
- bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
- bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
- }
- else
- {
- bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
- bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
- ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
- }
- memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
- cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
- ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
- bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
- bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
+ bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
+ }
+ else if (codec == SCO_CODEC_MSBC)
+ {
+ bt_sco_i2spcm_param[2] = wbs_sample_rate; /* SCO_I2SPCM_IF_SAMPLE_RATE 16K */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_wbs_clock_rate;
+ }
+ else
+ {
+ bt_sco_i2spcm_param[2] = 0; /* SCO_I2SPCM_IF_SAMPLE_RATE 8k */
+ bt_sco_i2spcm_param[3] = bt_sco_param[1] = sco_bus_clock_rate;
+ ALOGE("wrong codec is use in hw_sco_i2spcm_config, goes default NBS");
+ }
+ memcpy(p, &bt_sco_i2spcm_param, SCO_I2SPCM_PARAM_SIZE);
+ cmd_u16 = HCI_VSC_WRITE_I2SPCM_INTERFACE_PARAM;
+ ALOGI("I2SPCM config {0x%x, 0x%x, 0x%x, 0x%x}",
+ bt_sco_i2spcm_param[0], bt_sco_i2spcm_param[1],
+ bt_sco_i2spcm_param[2], bt_sco_i2spcm_param[3]);
- if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
- {
- bt_vendor_cbacks->dealloc(p_buf);
- }
- else
- return;
+ if ((ret = bt_vendor_cbacks->xmit_cb(cmd_u16, p_buf, hw_sco_i2spcm_cfg_cback)) == FALSE)
+ {
+ bt_vendor_cbacks->dealloc(p_buf);
}
- status = BT_VND_OP_RESULT_FAIL;
+ else
+ return;
}
- if (bt_vendor_cbacks)
- {
- bt_vendor_cbacks->audio_state_cb(status);
- }
+ bt_vendor_cbacks->audio_state_cb(BT_VND_OP_RESULT_FAIL);
}
/*******************************************************************************