Merge fc852cd9fdcdc2fbac6da7eba4cadbc9615fd653 on remote branch
Change-Id: Ib5cb67b5dbf4463b425f8aa3d20455a42080d47a
diff --git a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
index 9b2d1d0..49860a0 100644
--- a/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_client/src/agm_client_wrapper.cpp
@@ -314,6 +314,16 @@
return -EINVAL;
}
+int agm_sessionid_flush(uint32_t session_id)
+{
+ ALOGV("%s called with session id = %d", __func__, session_id);
+ if (!agm_server_died) {
+ android::sp<IAGM> agm_client = get_agm_server();
+ return agm_client->ipc_agm_sessionid_flush(session_id);
+ }
+ return -EINVAL;
+}
+
int agm_session_resume(uint64_t handle){
ALOGV("%s called with handle = %llx \n", __func__, (unsigned long long) handle);
if (!agm_server_died) {
diff --git a/ipc/HwBinders/agm_ipc_service/inc/agm_server_wrapper.h b/ipc/HwBinders/agm_ipc_service/inc/agm_server_wrapper.h
index 9ad0a2d..4c31633 100644
--- a/ipc/HwBinders/agm_ipc_service/inc/agm_server_wrapper.h
+++ b/ipc/HwBinders/agm_ipc_service/inc/agm_server_wrapper.h
@@ -200,6 +200,7 @@
Return<int32_t> ipc_agm_session_stop(uint64_t hndl) override;
Return<int32_t> ipc_agm_session_pause(uint64_t hndl) override;
Return<int32_t> ipc_agm_session_flush(uint64_t hndl) override;
+ Return<int32_t> ipc_agm_sessionid_flush(uint32_t session_id) override;
Return<int32_t> ipc_agm_session_resume(uint64_t hndl) override;
Return<int32_t> ipc_agm_session_suspend(uint64_t hndl) override;
Return<void> ipc_agm_session_read(uint64_t hndl, uint32_t count,
diff --git a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
index b8dd8c7..ccf047e 100644
--- a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
@@ -541,6 +541,10 @@
ALOGV("%s called with aif_id = %d, size = %d\n", __func__, aif_id, size);
uint8_t * metadata_l = NULL;
int32_t ret = 0;
+
+ if (metadata.size() < size) {
+ return -EINVAL;
+ }
metadata_l = (uint8_t *) calloc(1,size);
if (metadata_l == NULL) {
ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -558,6 +562,11 @@
ALOGV("%s : session_id = %d, size = %d\n", __func__, session_id, size);
uint8_t * metadata_l = NULL;
int32_t ret = 0;
+
+ if (metadata.size() < size) {
+ return -EINVAL;
+ }
+
metadata_l = (uint8_t *) calloc(1,size);
if (metadata_l == NULL) {
ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -581,6 +590,11 @@
session_id, aif_id, size);
uint8_t * metadata_l = NULL;
int32_t ret = 0;
+
+ if (metadata.size() < size) {
+ return -EINVAL;
+ }
+
metadata_l = (uint8_t *) calloc(1,size);
if (metadata_l == NULL) {
ALOGE("%s: Cannot allocate memory for metadata_l\n", __func__);
@@ -652,6 +666,11 @@
int32_t ret = 0;
hidl_vec<uint8_t> payload_hidl;
+ if (buff.size() < size) {
+ _hidl_cb(-EINVAL, size);
+ return Void();
+ }
+
payload_local = (uint8_t *) calloc (1, size);
if (payload_local == NULL) {
ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -707,6 +726,11 @@
int32_t ret = 0;
ALOGV("%s : aif_id =%d, size = %d\n", __func__, aif_id, size);
+
+ if (payload.size() < size) {
+ return -EINVAL;
+ }
+
payload_local = (void*) calloc (1,size);
if (payload_local == NULL) {
ALOGE("%s: calloc failed for payload_local\n", __func__);
@@ -727,6 +751,11 @@
size_t size_local = (size_t) size;
void * payload_local = NULL;
int32_t ret = 0;
+
+ if (payload.size() < size) {
+ return -EINVAL;
+ }
+
payload_local = (void*) calloc (1,size);
if (payload_local == NULL) {
ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -778,6 +807,11 @@
size_t size_local = (size_t) size;
void * payload_local = NULL;
int32_t ret = 0;
+
+ if (payload.size() < size) {
+ return -EINVAL;
+ }
+
payload_local = (void*) calloc (1,size);
if (payload_local == NULL) {
ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -826,6 +860,10 @@
size_t size_local = (size_t) size;
void * payload_local = NULL;
int32_t ret = 0;
+
+ if (payload.size() < size) {
+ return -EINVAL;
+ }
payload_local = (void*) calloc(1,size);
if (payload_local == NULL) {
ALOGE("%s: Cannot allocate memory for payload_local\n", __func__);
@@ -1032,6 +1070,12 @@
return agm_session_flush(hndl);
}
+Return<int32_t> AGM::ipc_agm_sessionid_flush(uint32_t session_id) {
+ ALOGV("%s called with session id = %d", __func__, session_id);
+
+ return agm_sessionid_flush(session_id);
+}
+
Return<int32_t> AGM::ipc_agm_session_resume(uint64_t hndl) {
ALOGV("%s called with handle = %llx \n", __func__, (unsigned long long) hndl);
@@ -1070,6 +1114,12 @@
ipc_agm_session_write_cb _hidl_cb) {
ALOGV("%s called with handle = %llx \n", __func__, (unsigned long long) hndl);
void* buffer = NULL;
+
+ if (buff.size() < count) {
+ _hidl_cb(-EINVAL, count);
+ return Void();
+ }
+
buffer = (void*) calloc(1,count);
if (buffer == NULL) {
ALOGE("%s: Cannot allocate memory for buffer\n", __func__);
@@ -1419,6 +1469,10 @@
buf.addr = nullptr;
buf.metadata = nullptr;
+ if (buff_hidl.data()->metadata.size() < buff_hidl.data()->metadata_size) {
+ _hidl_cb(-EINVAL, buff_hidl.data()->metadata_size);
+ return Void();
+ }
bufSize = buff_hidl.data()->size;
buf.addr = (uint8_t *)calloc(1, bufSize);
if (!buf.addr) {
diff --git a/ipc/HwBinders/interfaces/AGMIPC/1.0/IAGM.hal b/ipc/HwBinders/interfaces/AGMIPC/1.0/IAGM.hal
index 0e797a4..280cc5d 100644
--- a/ipc/HwBinders/interfaces/AGMIPC/1.0/IAGM.hal
+++ b/ipc/HwBinders/interfaces/AGMIPC/1.0/IAGM.hal
@@ -125,6 +125,7 @@
ipc_agm_session_stop(uint64_t hndl) generates (int32_t ret);
ipc_agm_session_pause(uint64_t hndl) generates (int32_t ret);
ipc_agm_session_flush(uint64_t hndl) generates (int32_t ret);
+ ipc_agm_sessionid_flush(uint32_t session_id) generates (int32_t ret);
ipc_agm_session_resume(uint64_t hndl) generates (int32_t ret);
ipc_agm_session_suspend(uint64_t hndl) generates (int32_t ret);
ipc_agm_session_read(uint64_t hndl, uint32_t count)
diff --git a/ipc/HwBinders/interfaces/AGMIPC/current.txt b/ipc/HwBinders/interfaces/AGMIPC/current.txt
index ae21480..8eae287 100644
--- a/ipc/HwBinders/interfaces/AGMIPC/current.txt
+++ b/ipc/HwBinders/interfaces/AGMIPC/current.txt
@@ -1,4 +1,4 @@
# Hash for vendor.qti.hardware.AGMIPC@1.0 package
1846dac975898187405fcd011ea43c98415334e187a74a2e4fcaea123e0064b7 vendor.qti.hardware.AGMIPC@1.0::types
-c75ed15965f38d53fe69c0a641fb7c9ae043560cb5dcd4e73ea31499251a8dc5 vendor.qti.hardware.AGMIPC@1.0::IAGM
+a1545123ef5e6f4536cd2f2902c74a202b39bac323bcbc0ed703ab1437056d4c vendor.qti.hardware.AGMIPC@1.0::IAGM
e8d1ca223a57cfacc7373f6418555330bb545c43a1e9d2c3a1fdd984fcec4a14 vendor.qti.hardware.AGMIPC@1.0::IAGMCallback
diff --git a/plugins/tinyalsa/src/agm_mixer_plugin.c b/plugins/tinyalsa/src/agm_mixer_plugin.c
index 819ed25..cb85c9d 100644
--- a/plugins/tinyalsa/src/agm_mixer_plugin.c
+++ b/plugins/tinyalsa/src/agm_mixer_plugin.c
@@ -144,17 +144,19 @@
"loopback",
"echoReference",
"bufTimestamp",
- /* Add new ones here, be sue to update enum as well */
+ /* Add new ones here, be sure to update enum as well */
};
enum {
PCM_RX_CTL_NAME_SIDETONE = 0,
PCM_RX_CTL_NAME_DATAPATH_PARAMS,
+ PCM_RX_CTL_NAME_FLUSH,
};
/* strings should be at the index as per the enum */
static char *amp_pcm_rx_ctl_names[] = {
"sidetone",
"datapathParams",
+ "flush",
};
struct amp_get_param_info {
@@ -1678,6 +1680,26 @@
return ret;
}
+/* Dummy implementation for flush_get */
+static int amp_pcm_flush_get(struct mixer_plugin *plugin __unused,
+ struct snd_control *ctl __unused, struct snd_ctl_elem_value *ev __unused)
+{
+ return 0;
+}
+
+static int amp_pcm_flush_put(struct mixer_plugin *plugin,
+ struct snd_control *ctl, struct snd_ctl_elem_value *ev)
+{
+ uint32_t pcm_idx = ctl->private_value;
+ bool flush = !!(ev->value.integer.value[0]);
+ int ret = 0;
+
+ if (flush)
+ ret = agm_sessionid_flush(pcm_idx);
+
+ return ret;
+}
+
/* 512 max bytes for non-tlv controls, reserving 16 for future use */
static struct snd_value_bytes pcm_calibration_bytes =
SND_VALUE_BYTES(512 - 16);
@@ -1714,6 +1736,9 @@
static struct snd_value_int group_media_fmt_int =
SND_VALUE_INTEGER(5, 0, 384000, 1);
+static struct snd_value_int flush_param_int =
+ SND_VALUE_INTEGER(1, 0, 1, 1);
+
static struct snd_value_tlv_bytes be_setparam_bytes =
SND_VALUE_TLV_BYTES(64 * 1024, amp_be_set_param_get, amp_be_set_param_put);
@@ -1957,6 +1982,18 @@
pcm_getacdbtunnel_bytes, pval, pdata);
}
+static void amp_create_pcm_flush_ctl(struct amp_priv *amp_priv,
+ char *name, int ctl_idx, int pval, void *pdata)
+{
+ struct snd_control *ctl = AMP_PRIV_GET_CTL_PTR(amp_priv, ctl_idx);
+ char *ctl_name = AMP_PRIV_GET_CTL_NAME_PTR(amp_priv, ctl_idx);
+
+ snprintf(ctl_name, AIF_NAME_MAX_LEN + 16, "%s %s",
+ name, amp_pcm_rx_ctl_names[PCM_RX_CTL_NAME_FLUSH]);
+
+ INIT_SND_CONTROL_INTEGER(ctl, ctl_name, amp_pcm_flush_get,
+ amp_pcm_flush_put, flush_param_int, pval, pdata);
+}
/* BE related mixer control creations here */
static void amp_create_metadata_ctl(struct amp_priv *amp_priv,
@@ -2140,6 +2177,8 @@
&be_tx_adi->dev_enum, idx, rx_adi);
amp_create_pcm_write_with_metadata_ctl(amp_priv, name, (*ctl_idx)++,
idx, rx_adi);
+ amp_create_pcm_flush_ctl(amp_priv, name, (*ctl_idx)++,
+ idx, rx_adi);
}
return 0;
diff --git a/plugins/tinyalsa/src/agm_pcm_plugin.c b/plugins/tinyalsa/src/agm_pcm_plugin.c
index 176a218..92561fc 100644
--- a/plugins/tinyalsa/src/agm_pcm_plugin.c
+++ b/plugins/tinyalsa/src/agm_pcm_plugin.c
@@ -59,7 +59,8 @@
#define AGM_PULL_PUSH_IDX_RETRY_COUNT 2
#define AGM_PULL_PUSH_FRAME_CNT_RETRY_COUNT 5
-#define SNDCARD_PATH "/sys/kernel/snd_card/card_state"
+/* multiplier of timeout for wating for mmap buffers */
+#define MMAP_TOUT_MULTI 4
struct agm_shared_pos_buffer {
volatile uint32_t frame_counter;
@@ -100,7 +101,7 @@
/* idx: 0: out port, 1: in port */
struct agm_mmap_buffer_port mmap_buffer_port[2];
bool mmap_status;
- int fd;
+ uint32_t mmap_buf_tout;
};
struct pcm_plugin_hw_constraints agm_pcm_constrs = {
@@ -310,28 +311,6 @@
return -EAGAIN;
}
-static int agm_pcm_plugin_get_card_status(struct agm_pcm_priv *priv)
-{
- char buf[10];
- int card_status = -1;
-
- if (priv->fd < 0) {
- if ((priv->fd = open(SNDCARD_PATH, O_RDWR)) < 0) {
- AGM_LOGE(LOG_TAG, "Open failed snd sysfs node");
- errno = ENETRESET;
- return -ENETRESET;
- }
- AGM_LOGD(LOG_TAG, "Snd sysfs node open successful");
- }
-
- memset(buf, 0, sizeof(buf));
- read(priv->fd, buf, 1);
- lseek(priv->fd, 0L, SEEK_SET);
- sscanf(buf, "%d", &card_status);
-
- return card_status;
-}
-
static int agm_pcm_plugin_update_hw_ptr(struct agm_pcm_priv *priv)
{
int retries = 10;
@@ -344,15 +323,8 @@
int ret = 0;
uint32_t period_size = priv->period_size; /** in frames */
uint32_t crossed_boundary = 0;
- int card_status = -1;
uint32_t old_frame_counter = priv->pos_buf->frame_counter;
- card_status = agm_pcm_plugin_get_card_status(priv);
- if (card_status != 1) { // 1 assume to be snd card status online
- AGM_LOGE("%s: Snd card is Offline\n", __func__);
- errno = ENETRESET;
- return -ENETRESET;
- }
do {
ret = agm_pcm_plugin_get_shared_pos(priv->pos_buf,
&read_index, &wall_clk_msw, &wall_clk_lsw);
@@ -727,10 +699,6 @@
close(priv->buf_info->data_buf_fd);
free(priv->buf_info);
}
- if (priv->fd >= 0) {
- close(priv->fd);
- priv->fd = -1;
- }
free(plugin->priv);
free(plugin);
@@ -767,6 +735,7 @@
uint32_t period_size = priv->period_size;
snd_pcm_sframes_t avail;
int ret = 0;
+ uint32_t period_to_msec = period_size / (priv->media_config->rate / 1000);
avail = agm_pcm_get_avail(plugin);
@@ -777,8 +746,6 @@
ret = agm_pcm_plugin_update_hw_ptr(priv);
if (ret == 0)
avail = agm_pcm_get_avail(plugin);
- else if (ret == -ENETRESET)
- return ret;
}
if (avail >= period_size) {
@@ -789,8 +756,16 @@
pfd->revents = POLLOUT;
ret = POLLOUT;
}
+ priv->mmap_buf_tout = 0;
} else {
ret = 0; /* TIMEOUT */
+ priv->mmap_buf_tout += timeout;
+ if (priv->mmap_buf_tout > (period_to_msec * MMAP_TOUT_MULTI)) {
+ AGM_LOGE("timeout in waiting for mmap buffer");
+ priv->mmap_buf_tout = 0;
+ errno = ETIMEDOUT;
+ return -ETIMEDOUT;
+ }
}
return ret;
@@ -967,13 +942,6 @@
goto err_buf_free;
}
- priv->fd = -1;
- if ((priv->fd = open(SNDCARD_PATH, O_RDWR)) < 0) {
- AGM_LOGE(LOG_TAG, "Open failed snd sysfs node");
- ret = -EINVAL;
- goto err_session_free;
- }
-
card_node = snd_card_def_get_card(card);
if (!card_node) {
ret = -EINVAL;
@@ -1021,10 +989,6 @@
err_card_put:
snd_card_def_put_card(card_node);
err_session_free:
- if (priv->fd >= 0) {
- close(priv->fd);
- priv->fd = -1;
- }
free(session_config);
err_buf_free:
free(buffer_config);
diff --git a/service/inc/private/agm/device.h b/service/inc/private/agm/device.h
index 7fda4a3..9bd6a08 100644
--- a/service/inc/private/agm/device.h
+++ b/service/inc/private/agm/device.h
@@ -89,6 +89,7 @@
#define PCM_RT_PROXY 0x7
#define AUDIOSS_DMA 0x8
#define PCM_DUMMY 0x9
+#define BTFM_PROXY 0xa
#define AUDIO_OUTPUT 0x1 /**< playback usecases*/
#define AUDIO_INPUT 0x2 /**< capture/voice activation usecases*/
diff --git a/service/inc/private/agm/session_obj.h b/service/inc/private/agm/session_obj.h
index 4679117..b6969d0 100644
--- a/service/inc/private/agm/session_obj.h
+++ b/service/inc/private/agm/session_obj.h
@@ -111,6 +111,7 @@
int session_obj_deinit();
int session_obj_valid_check(uint64_t hndl);
int session_obj_get(int session_id, struct session_obj **sess_obj);
+struct session_obj *session_obj_retrieve_from_pool(uint32_t session_id);
int session_obj_open(uint32_t session_id,
enum agm_session_mode sess_mode,
struct session_obj **sess_obj);
diff --git a/service/inc/public/agm/agm_api.h b/service/inc/public/agm/agm_api.h
index 8680fa1..3ff08f7 100644
--- a/service/inc/public/agm/agm_api.h
+++ b/service/inc/public/agm/agm_api.h
@@ -960,6 +960,16 @@
int agm_session_flush(uint64_t hndl);
/**
+ * \brief flush the session. session must be in pause state
+ * before flushing.
+ *
+ * \param[in] session_id - Valid audio session id
+ *
+ * \return 0 on success, error code otherwise
+ */
+int agm_sessionid_flush(uint32_t session_id);
+
+/**
* \brief Resume the session. session must be in paused state
* before resuming.
*
diff --git a/service/src/agm.c b/service/src/agm.c
index f56e7a4..f718369 100644
--- a/service/src/agm.c
+++ b/service/src/agm.c
@@ -795,6 +795,20 @@
return session_obj_flush(handle);
}
+int agm_sessionid_flush(uint32_t session_id)
+{
+ struct session_obj *handle = NULL;
+ int ret = 0;
+
+ handle = session_obj_retrieve_from_pool(session_id);
+ if (!handle) {
+ AGM_LOGE("Incorrect session_id:%d, doesn't match sess_obj from pool",
+ session_id);
+ return -EINVAL;
+ }
+ return session_obj_flush(handle);
+}
+
int agm_session_resume(uint64_t hndl)
{
struct session_obj *handle = (struct session_obj *) hndl;
diff --git a/service/src/device_hw_ep.c b/service/src/device_hw_ep.c
index 155f0a0..bee6bce 100644
--- a/service/src/device_hw_ep.c
+++ b/service/src/device_hw_ep.c
@@ -178,6 +178,8 @@
hw_ep_info->intf = AUDIOSS_DMA;
else if (!strcmp(intf, "PCM_DUMMY"))
hw_ep_info->intf = PCM_DUMMY;
+ else if (!strcmp(intf, "BTFM_PROXY"))
+ hw_ep_info->intf = BTFM_PROXY;
else {
AGM_LOGE("No matching intf found\n");
return -EINVAL;
@@ -232,7 +234,7 @@
}
-static int populate_pcm_rt_proxy_ep_info(hw_ep_info_t *hw_ep_info, char *value)
+static int populate_btfm_rt_proxy_ep_info(hw_ep_info_t *hw_ep_info, char *value)
{
char arg[DEV_ARG_SIZE] = {0};
struct hw_ep_pcm_rt_proxy_config *pcm_rt_proxy_config;
@@ -410,7 +412,8 @@
case USB_AUDIO:
return populate_slim_dp_usb_ep_info(&dev_obj->hw_ep_info, value);
case PCM_RT_PROXY:
- return populate_pcm_rt_proxy_ep_info(&dev_obj->hw_ep_info, value);
+ case BTFM_PROXY:
+ return populate_btfm_rt_proxy_ep_info(&dev_obj->hw_ep_info, value);
case AUDIOSS_DMA:
return populate_audioss_dma_ep_info(&dev_obj->hw_ep_info, value);
case PCM_DUMMY:
diff --git a/service/src/graph_module.c b/service/src/graph_module.c
index f77aa0f..1a0cb70 100644
--- a/service/src/graph_module.c
+++ b/service/src/graph_module.c
@@ -744,10 +744,11 @@
int ret = 0;
struct device_obj *dev_obj = mod->dev_obj;
- if(dev_obj->hw_ep_info.intf == PCM_RT_PROXY || dev_obj->hw_ep_info.intf == PCM_DUMMY) {
+ if ((dev_obj->hw_ep_info.intf == PCM_RT_PROXY) ||
+ (dev_obj->hw_ep_info.intf == PCM_DUMMY) ||
+ (dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
AGM_LOGD("no ep media config for %d\n", dev_obj->hw_ep_info.intf);
- }
- else {
+ } else {
ret = configure_hw_ep_media_config(mod, graph_obj);
if (ret) {
AGM_LOGE("hw_ep_media_config failed %d", ret);
@@ -772,19 +773,15 @@
break;
case DISPLAY_PORT:
case USB_AUDIO:
- AGM_LOGD("no ep configuration for %d\n", dev_obj->hw_ep_info.intf);
- break;
case PCM_RT_PROXY:
- AGM_LOGD("no ep configuration for %d\n", dev_obj->hw_ep_info.intf);
- break;
case AUDIOSS_DMA:
- AGM_LOGD("no ep configuration for %d\n", dev_obj->hw_ep_info.intf);
- break;
case PCM_DUMMY:
+ case BTFM_PROXY:
AGM_LOGD("no ep configuration for %d\n", dev_obj->hw_ep_info.intf);
break;
default:
AGM_LOGE("hw intf %d not enabled yet", dev_obj->hw_ep_info.intf);
+ ret = -EINVAL;
break;
}
return ret;
diff --git a/service/src/metadata.c b/service/src/metadata.c
index c94f856..047f5e0 100644
--- a/service/src/metadata.c
+++ b/service/src/metadata.c
@@ -270,17 +270,17 @@
return merged;
}
-int metadata_copy(struct agm_meta_data_gsl *dest, uint32_t size __unused,
+int metadata_copy(struct agm_meta_data_gsl *dest, uint32_t size,
uint8_t *metadata)
{
int ret = 0;
+ int min_req_len = 0;
if (!metadata) {
AGM_LOGI("NULL metadata passed, ignoring\n");
- return ret;
+ goto done;
}
-
if ((NUM_GKV(metadata) > MAX_KVPAIR) || (NUM_CKV(metadata) > MAX_KVPAIR)) {
AGM_LOGE("Num GKVs %d Num CKVs %d more than expected: %d", NUM_GKV(metadata),
NUM_CKV(metadata), MAX_KVPAIR);
@@ -288,39 +288,84 @@
return ret;
}
+ min_req_len += sizeof(uint32_t);
+ if (size < min_req_len) {
+ AGM_LOGE("size should be atleast %d size for GKV\n", sizeof(uint32_t));
+ ret = -EINVAL;
+ goto done;
+
+ }
+
dest->gkv.num_kvs = NUM_GKV(metadata);
dest->gkv.kv = calloc(dest->gkv.num_kvs, sizeof(struct agm_key_value));
if (!dest->gkv.kv) {
AGM_LOGE("Memory allocation failed to copy GKV\n");
ret = -ENOMEM;
- return ret;
+ goto free_metadata;
+ }
+
+ min_req_len += (dest->gkv.num_kvs * sizeof(struct agm_key_value));
+ if (size < min_req_len) {
+ AGM_LOGE("Invalid GKV passed\n");
+ ret = -EINVAL;
+ goto free_metadata;
}
memcpy(dest->gkv.kv, PTR_TO_GKV(metadata), dest->gkv.num_kvs *
sizeof(struct agm_key_value));
+ min_req_len += sizeof(uint32_t);
+ if (size < min_req_len) {
+ goto done;
+ }
dest->ckv.num_kvs = NUM_CKV(metadata);
dest->ckv.kv = calloc(dest->ckv.num_kvs, sizeof(struct agm_key_value));
if (!dest->ckv.kv) {
AGM_LOGE("Memory allocation failed to copy CKV\n");
- metadata_free(dest);
ret = -ENOMEM;
- return ret;
+ goto free_metadata;
+ }
+ min_req_len += (dest->ckv.num_kvs * sizeof(struct agm_key_value));
+ if (size < min_req_len) {
+ AGM_LOGE("Invalid CKV passed\n");
+ ret = -EINVAL;
+ goto free_metadata;
}
memcpy(dest->ckv.kv, PTR_TO_CKV(metadata), dest->ckv.num_kvs *
sizeof(struct agm_key_value));
+ min_req_len += sizeof(uint32_t);
+ if (size < min_req_len) {
+ goto done;
+ }
dest->sg_props.prop_id = PROP_ID(metadata);
+
+ min_req_len += sizeof(uint32_t);
+ if (size < min_req_len) {
+ AGM_LOGE("Invalid properties passed\n");
+ ret = -EINVAL;
+ goto free_metadata;
+ }
dest->sg_props.num_values = NUM_PROPS(metadata);
dest->sg_props.values = calloc(dest->sg_props.num_values, sizeof(uint32_t));
if (!dest->sg_props.values) {
AGM_LOGE("Memory allocation failed to copy properties\n");
- metadata_free(dest);
ret = -ENOMEM;
- return ret;
+ goto free_metadata;
+ }
+ min_req_len += (dest->sg_props.num_values * sizeof(uint32_t));
+ if (size < min_req_len) {
+ AGM_LOGE("Invalid properties passed\n");
+ ret = -EINVAL;
+ goto free_metadata;
}
memcpy(dest->sg_props.values, PTR_TO_PROPS(metadata),
dest->sg_props.num_values * sizeof(uint32_t));
+ goto done;
+free_metadata:
+ metadata_free(dest);
+
+done:
return ret;
}
diff --git a/service/src/session_obj.c b/service/src/session_obj.c
index f3295b0..7809de4 100644
--- a/service/src/session_obj.c
+++ b/service/src/session_obj.c
@@ -1081,7 +1081,7 @@
pthread_mutex_lock(&hwep_lock);
- //For Slimbus EP - First configure the slave ports via device_prepare/start
+ //For Slimbus/CP EP - First configure the slave ports via device_prepare/start
//and then start the master side via graph_start.
list_for_each(node, &sess_obj->aif_pool) {
aif_obj = node_to_item(node, struct aif, node);
@@ -1090,8 +1090,9 @@
goto device_stop;
}
- if (aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) {
- AGM_LOGD("configuring device early - for SLIMBUS EPs\n");
+ if ((aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) ||
+ (aif_obj->dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
+ AGM_LOGD("configuring device early - for SLIMBUS/Connectivity Proxy EPs\n");
if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
ret = device_prepare(aif_obj->dev_obj);
if (ret) {
@@ -1128,9 +1129,11 @@
goto unwind;
}
- //Continue/SKIP for SLIMBUS EP as they are started early.
- if (aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS)
+ //Continue/SKIP for SLIMBUS/Connectivity Proxy EP as they are started early.
+ if ((aif_obj->dev_obj->hw_ep_info.intf == SLIMBUS) ||
+ (aif_obj->dev_obj->hw_ep_info.intf == BTFM_PROXY)) {
continue;
+ }
if (aif_obj->state == AIF_OPENED || aif_obj->state == AIF_STOPPED) {
ret = device_prepare(aif_obj->dev_obj);
diff --git a/snd_parser/src/snd-card-parser.c b/snd_parser/src/snd-card-parser.c
index 525028d..37824e6 100644
--- a/snd_parser/src/snd-card-parser.c
+++ b/snd_parser/src/snd-card-parser.c
@@ -491,6 +491,7 @@
}
}
+ card_def = NULL;
/* read XML */
file = fopen(CARD_DEF_FILE, "r");
if (!file) {