Merge "agm: session: Add check for invalid session handle"
diff --git a/ipc/DBus/agm_server/src/agm-dbus-utils.cpp b/ipc/DBus/agm_server/src/agm-dbus-utils.cpp
index d5616be..e16baaf 100644
--- a/ipc/DBus/agm_server/src/agm-dbus-utils.cpp
+++ b/ipc/DBus/agm_server/src/agm-dbus-utils.cpp
@@ -496,6 +496,10 @@
     if ((object = (agm_dbus_object *)
                    g_hash_table_lookup(conn->objects, dbus_obj_path)) == NULL) {
         object = (agm_dbus_object *)malloc(sizeof(agm_dbus_object));
+        if (object == NULL) {
+            AGM_LOGE("object is NULL\n");
+            goto object_malloc_failed;
+        }
         object->obj_path = dbus_obj_path;
         object->interfaces = g_hash_table_new_full(g_str_hash,
                                                    g_str_equal,
@@ -503,6 +507,10 @@
                                                    agm_free_interface);
 
         interface = (agm_dbus_interface *)malloc(sizeof(agm_dbus_interface));
+        if (interface == NULL) {
+            AGM_LOGE("interface is NULL\n");
+            goto interface_malloc_failed;
+        }
         interface->name = interface_info->name;
         interface->methods = g_hash_table_new_full(g_str_hash,
                                                    g_str_equal,
@@ -511,6 +519,10 @@
 
         for (i = 0; i < interface_info->method_count; i++) {
              method = (agm_dbus_method *)malloc(sizeof(agm_dbus_method));
+             if (method == NULL) {
+                AGM_LOGE("method is NULL\n");
+                goto method_malloc_failed;
+             }
              method->method_name = interface_info->methods[i].method_name;
              method->method_signature =
                                     interface_info->methods[i].method_signature;
@@ -526,6 +538,10 @@
                                                    agm_free_signal);
         for (i = 0; i < interface_info->signal_count; i++) {
              signal = (agm_dbus_signal *)malloc(sizeof(agm_dbus_signal));
+             if (signal == NULL) {
+                AGM_LOGE("signal is NULL\n");
+                goto signal_malloc_failed;
+             }
              signal->method_name = interface_info->signals[i].method_name;
              signal->method_signature =
                                     interface_info->signals[i].method_signature;
@@ -555,6 +571,10 @@
                                                interface_info->name)) == NULL) {
             interface = (agm_dbus_interface *)
                                     malloc(sizeof(agm_dbus_interface));
+            if (interface == NULL) {
+                AGM_LOGE("interface is NULL\n");
+                goto interface_malloc_failed;
+            }
             interface->name = interface_info->name;
             interface->signals = NULL;
             interface->methods = NULL;
@@ -566,6 +586,10 @@
 
                 for (i = 0; i < interface_info->method_count; i++) {
                     method = (agm_dbus_method *)malloc(sizeof(agm_dbus_method));
+                    if (method == NULL) {
+                        AGM_LOGE("method is NULL\n");
+                        goto method_malloc_failed;
+                    }
                     method->method_name =
                                     interface_info->methods[i].method_name;
                     method->method_signature =
@@ -584,6 +608,10 @@
                                                            agm_free_signal);
                 for (i = 0; i < interface_info->signal_count; i++) {
                     signal = (agm_dbus_signal *)malloc(sizeof(agm_dbus_signal));
+                    if (signal == NULL) {
+                        AGM_LOGE("signal is NULL\n");
+                        goto signal_malloc_failed;
+                    }
                     signal->method_name =
                                     interface_info->signals[i].method_name;
                     signal->method_signature =
@@ -603,6 +631,21 @@
 
     dbus_error_free(&err);
     return 0;
+
+signal_malloc_failed:
+    free(method);
+    method = NULL;
+method_malloc_failed:
+    free(interface);
+    interface = NULL;
+interface_malloc_failed:
+    if (object) {
+        free(object);
+        object = NULL;
+    }
+object_malloc_failed:
+    dbus_error_free(&err);
+    return -EINVAL;
 }
 
 void agm_dbus_connection_free(agm_dbus_connection *conn) {
@@ -624,6 +667,10 @@
     agm_dbus_connection *conn = NULL;
 
     conn = (agm_dbus_connection *)malloc(sizeof(agm_dbus_connection));
+    if (conn == NULL) {
+        AGM_LOGE("conn is NULL\n");
+        return NULL;
+    }
     conn->objects = NULL;
 
     dbus_error_init(&err);
diff --git a/ipc/DBus/agm_server/src/agm_server_wrapper_dbus.cpp b/ipc/DBus/agm_server/src/agm_server_wrapper_dbus.cpp
index d8951e1..054f354 100644
--- a/ipc/DBus/agm_server/src/agm_server_wrapper_dbus.cpp
+++ b/ipc/DBus/agm_server/src/agm_server_wrapper_dbus.cpp
@@ -387,12 +387,22 @@
                         g_hash_table_lookup(mdata->sessions,
                                        GUINT_TO_POINTER(session_id))) == NULL) {
         ses_data = (agm_session_data *)malloc(sizeof(agm_session_data));
+        if (ses_data == NULL) {
+            AGM_LOGE("ses_data is NULL\n");
+            return NULL;
+        }
         ses_data->session_id = session_id;
         ss << ses_data->session_id;
         obj_length = sizeof(char)*(strlen(AGM_OBJECT_PATH)) +
                      strlen("/session_") +
                      ss.str().length() + 1;
         ses_data->dbus_obj_path = (char *)malloc(obj_length);
+        if (ses_data->dbus_obj_path == NULL) {
+            AGM_LOGE("dbus_obj_path is NULL\n");
+            free(ses_data);
+            ses_data = NULL;
+            return NULL;
+        }
         snprintf(ses_data->dbus_obj_path,
                  obj_length,
                  "%s%s%d",
@@ -432,6 +442,10 @@
     AGM_LOGE("%s: Received event for session %d", __func__, session_id);
 
     buf = malloc(event_params->event_payload_size);
+    if (buf == NULL) {
+        AGM_LOGE("buf is NULL");
+        return;
+    }
     memcpy(buf, event_params->event_payload, event_params->event_payload_size);
 
     message = dbus_message_new_signal(ses_data->dbus_obj_path,
@@ -516,6 +530,13 @@
     }
 
     cb_data = (agm_callback_data *)malloc(sizeof(agm_callback_data));
+    if (cb_data == NULL) {
+        AGM_LOGE("cb_data is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                             "cb_data is NULL");
+        agm_free_session(ses_data);
+        return;
+    }
     cb_data->session_id = session_id;
     cb_data->event_type = evt_type;
     cb_data->client_data = client_data;
@@ -590,6 +611,13 @@
     }
 
     cb_data = (agm_callback_data *)malloc(sizeof(agm_callback_data));
+    if (cb_data == NULL) {
+        AGM_LOGE("cb_data is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                             "cb_data is NULL");
+        agm_free_session(ses_data);
+        return;
+    }
     cb_data->session_id = session_id;
     cb_data->event_type = evt_type;
     cb_data->client_data = client_data;
@@ -661,6 +689,12 @@
     evt_reg_cfg = (struct agm_event_reg_cfg *)
                     calloc (1,(sizeof(struct agm_event_reg_cfg) +
                             (event_config_payload_size)*sizeof(uint8_t)));
+    if (evt_reg_cfg == NULL) {
+        AGM_LOGE("alloc memory failed, evt_reg_cfg is NULL.");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                             "alloc memory failed, evt_reg_cfg is NULL.");
+        return;
+    }
     evt_reg_cfg->module_instance_id = module_instance_id;
     evt_reg_cfg->event_id = event_id;
     evt_reg_cfg->event_config_payload_size = event_config_payload_size;
@@ -722,6 +756,12 @@
     dbus_message_iter_recurse(&arg_i, &array_i);
     dbus_message_iter_get_fixed_array(&array_i, addr_value, &n_elements);
     payload = (void *)malloc(n_elements*sizeof(char));
+    if (payload == NULL) {
+        AGM_LOGE("payload is NULL.");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                              "Ipayload is NULL.");
+        return;
+    }
     memcpy(payload, value, n_elements);
 
     if (agm_session_get_params(session_id, (void *)payload, size) != 0) {
@@ -791,6 +831,12 @@
     cal_config = (struct agm_cal_config *)
                         calloc (1, sizeof(struct agm_cal_config) +
                                 num_ckv * sizeof(struct agm_key_value));
+    if (cal_config == NULL) {
+        AGM_LOGE("alloc memory failed, cal_config is NULL.");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                             "alloc memory failed, cal_config is NULL.");
+        return;
+    }
     cal_config->num_ckvs = num_ckv;
     memcpy(cal_config->kv, value,
                              cal_config->num_ckvs*sizeof(struct agm_key_value));
@@ -854,6 +900,11 @@
     dbus_message_iter_recurse(&arg_i, &array_i);
     dbus_message_iter_get_fixed_array(&array_i, addr_value, &n_elements);
     buf = (void *)malloc(n_elements*sizeof(char));
+    if (buf == NULL) {
+        AGM_LOGE("buf is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED, "buf is NULL");
+        return;
+    }
     memcpy(buf, value, n_elements);
 
     if (agm_session_aif_set_params(session_id, aif_id, buf, size) != 0) {
@@ -1285,6 +1336,12 @@
     size_local = (sizeof(struct agm_tag_config) +
                         (num_tkvs) * sizeof(agm_key_value));
     tag_config = (struct agm_tag_config *) calloc(1,size_local);
+    if (tag_config == NULL) {
+        AGM_LOGE("tag_config is NULL.");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED,
+                             "tag_config is NULL.");
+        return;
+    }
     tag_config->tag = tag;
     tag_config->num_tkvs = num_tkvs;
     dbus_message_iter_recurse(&struct_i, &array_i);
@@ -1407,6 +1464,11 @@
     dbus_message_iter_recurse(&arg_i, &array_i);
     dbus_message_iter_get_fixed_array(&array_i, addr_value, &n_elements);
     metadata = (void *)malloc(n_elements*sizeof(char));
+    if (metadata == NULL) {
+        AGM_LOGE("metadata is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED, "metadata is NULL");
+        return;
+    }
     memcpy(metadata, value, n_elements);
 
     if (agm_session_set_metadata(session_id, size, (uint8_t *)metadata) != 0) {
@@ -1467,6 +1529,11 @@
     dbus_message_iter_recurse(&arg_i, &array_i);
     dbus_message_iter_get_fixed_array(&array_i, addr_value, &n_elements);
     metadata = (void *)malloc(n_elements*sizeof(char));
+    if (metadata == NULL) {
+        AGM_LOGE("metadata is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED, "metadata is NULL");
+        return;
+    }
     memcpy(metadata, value, n_elements);
 
     if (agm_session_aif_set_metadata(session_id,
@@ -1529,6 +1596,11 @@
     dbus_message_iter_recurse(&arg_i, &array_i);
     dbus_message_iter_get_fixed_array(&array_i, addr_value, &n_elements);
     metadata = (void *)malloc(n_elements*sizeof(char));
+    if (metadata == NULL) {
+        AGM_LOGE("metadata is NULL");
+        agm_dbus_send_error(mdata->conn, msg, DBUS_ERROR_FAILED, "metadata is NULL");
+        return;
+    }
     memcpy(metadata, value, n_elements);
 
     if (agm_aif_set_metadata(aif_id, size, (uint8_t *)metadata) != 0) {
@@ -2188,8 +2260,21 @@
     AGM_LOGV("%s : ", __func__);
 
     mdata = (agm_module_dbus_data *)malloc(sizeof(agm_module_dbus_data));
+    if (mdata == NULL) {
+        AGM_LOGE("mdata is NULL");
+        rc = -EINVAL;
+        return rc;
+    }
+
     mdata->dbus_obj_path =
                     (char *)malloc(sizeof(char)*(strlen(AGM_OBJECT_PATH) + 1));
+    if (mdata->dbus_obj_path == NULL) {
+        AGM_LOGE("dbus_obj_path is NULL");
+        free(mdata)
+        mata = NULL;
+        rc = -EINVAL;
+        return rc;
+    }
     memcpy(mdata->dbus_obj_path, AGM_OBJECT_PATH, strlen(AGM_OBJECT_PATH)+1);
 
     mdata->conn = agm_dbus_new_connection();
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 62480d4..b8dd8c7 100644
--- a/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
+++ b/ipc/HwBinders/agm_ipc_service/src/agm_server_wrapper.cpp
@@ -79,6 +79,9 @@
 #ifndef __SIGRTMIN
 #define __SIGRTMIN 32
 #endif
+
+#define MAX_KVPAIR 48
+
 static const constexpr int DEBUGGER_SIGNAL = (__SIGRTMIN + 3);
 
 using AgmCallbackData = ::vendor::qti::hardware::AGMIPC::V1_0::implementation::clbk_data;
@@ -745,13 +748,18 @@
     struct agm_cal_config *cal_config_local = NULL;
     int32_t ret = 0;
 
+    if (cal_config.data()->num_ckvs > MAX_KVPAIR ) {
+        ALOGE("Num KVs %d more than expected: %d", cal_config.data()->num_ckvs, MAX_KVPAIR);
+        return -ENOMEM;
+    }
+
     cal_config_local =
-              (struct agm_cal_config*) calloc(1, sizeof(struct agm_cal_config) +
-               cal_config.data()->num_ckvs * sizeof(struct agm_key_value));
+               (struct agm_cal_config*) calloc(1, sizeof(struct agm_cal_config) +
+                cal_config.data()->num_ckvs * sizeof(struct agm_key_value));
 
     if (cal_config_local == NULL) {
-            ALOGE("%s: Cannot allocate memory for cal_config_local\n", __func__);
-            return -ENOMEM;
+        ALOGE("%s: Cannot allocate memory for cal_config_local\n", __func__);
+        return -ENOMEM;
     }
     cal_config_local->num_ckvs = cal_config.data()->num_ckvs;
     for (int i=0 ; i < cal_config.data()->num_ckvs ; i++ ) {
@@ -786,6 +794,11 @@
                                      const hidl_vec<AgmTagConfig>& tag_config) {
     ALOGV("%s : session_id = %d, aif_id = %d\n", __func__, session_id, aif_id);
     struct agm_tag_config *tag_config_local;
+
+    if (tag_config.data()->num_tkvs > MAX_KVPAIR) {
+        ALOGE("Num KVs %d more than expected: %d", tag_config.data()->num_tkvs, MAX_KVPAIR);
+        return -ENOMEM;
+    }
     size_t size_local = (sizeof(struct agm_tag_config) +
                         (tag_config.data()->num_tkvs) * sizeof(agm_key_value));
     int32_t ret = 0;
diff --git a/plugins/tinyalsa/Android.mk b/plugins/tinyalsa/Android.mk
index f987792..7c422fd 100644
--- a/plugins/tinyalsa/Android.mk
+++ b/plugins/tinyalsa/Android.mk
@@ -103,9 +103,9 @@
     libcutils \
     liblog
 
-#if android version is R, refer to qtitinyxx otherwise use upstream ones
-#This assumes we would be using AR code only for Android R and subsequent versions.
-ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+# Use flag based selection to use QTI vs open source tinycompress project
+
+ifeq ($(TARGET_USES_QTI_TINYCOMPRESS),true)
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinycompress/include
 LOCAL_SHARED_LIBRARIES += libqti-tinyalsa\
diff --git a/plugins/tinyalsa/src/agm_mixer_plugin.c b/plugins/tinyalsa/src/agm_mixer_plugin.c
index ec89577..819ed25 100644
--- a/plugins/tinyalsa/src/agm_mixer_plugin.c
+++ b/plugins/tinyalsa/src/agm_mixer_plugin.c
@@ -214,6 +214,7 @@
     struct snd_value_enum rx_be_enum;
 
     event_callback event_cb;
+    pthread_mutex_t lock;
 };
 
 struct event_params_node {
@@ -412,22 +413,28 @@
     if (!stream)
         return;
 found:
+    pthread_mutex_lock(&amp_priv->lock);
     amp_add_event_params(amp_priv, session_id, event_params);
     event.type = SNDRV_CTL_EVENT_ELEM;
     ctl_len = (int)(strlen(stream) + 1 + strlen(ctl_name) + 1);
     mixer_str = calloc(1, ctl_len);
-    if (!mixer_str)
+    if (!mixer_str) {
+        pthread_mutex_unlock(&amp_priv->lock);
         return;
+    }
 
     snprintf(mixer_str, ctl_len, "%s %s", stream, ctl_name);
     strlcpy((char*)event.data.elem.id.name, mixer_str, sizeof(event.data.elem.id.name));
 
     data = calloc(1, sizeof(struct mixer_plugin_event_data));
-    if (!data)
+    if (!data) {
+        pthread_mutex_unlock(&amp_priv->lock);
         goto done;
+    }
 
     data->ev = event;
     list_add_tail(&amp_priv->events_list, &data->node);
+    pthread_mutex_unlock(&amp_priv->lock);
 
     if (amp_priv->event_cb)
         amp_priv->event_cb(plugin);
@@ -528,6 +535,8 @@
     return 0;
 
 err_backends_get:
+    if (aif_list)
+        free(aif_list);
     amp_free_be_dev_info(amp_priv);
     return ret;
 }
@@ -568,6 +577,8 @@
     return 0;
 
 err_backends_get:
+    if (aif_list)
+        free(aif_list);
     amp_free_group_be_dev_info(amp_priv);
     return ret;
 }
@@ -1099,6 +1110,7 @@
     int session_id = ctl->private_value;
     uint32_t tlv_size, event_payload_size;
     void *payload;
+    int ret = 0;
 
     AGM_LOGV("%s: enter\n", __func__);
     payload = &tlv->tlv[0];
@@ -1110,6 +1122,7 @@
         AGM_LOGE("%s: invalid array size %d\n", __func__, tlv_size);
         return -EINVAL;
     }
+    pthread_mutex_lock(&amp_priv->lock);
     list_for_each_safe(eparams_node, temp, &amp_priv->events_paramlist) {
         event_node = node_to_item(eparams_node, struct event_params_node, node);
         if (event_node->session_id == session_id) {
@@ -1117,18 +1130,21 @@
             event_payload_size = sizeof(struct agm_event_cb_params) + eparams->event_payload_size;
             if (tlv_size < event_payload_size) {
                 AGM_LOGE("Expected %d size, received %d\n", event_payload_size, tlv_size);
-                return -EINVAL;
+                ret = -EINVAL;
+                goto done;
             }
             memcpy(payload, eparams,
                    sizeof(struct agm_event_cb_params)
                    + eparams->event_payload_size);
             list_remove(&event_node->node);
             free(event_node);
-            return 0;
+            goto done;
         }
     }
 
-    return 0;
+done:
+    pthread_mutex_unlock(&amp_priv->lock);
+    return ret;
 }
 
 static int amp_pcm_event_put(struct mixer_plugin *plugin __unused,
@@ -2187,8 +2203,11 @@
     while (size >= sizeof(struct ctl_event)) {
         struct mixer_plugin_event_data *data;
 
-        if (list_empty(&amp_priv->events_list))
+        pthread_mutex_lock(&amp_priv->lock);
+        if (list_empty(&amp_priv->events_list)) {
+            pthread_mutex_unlock(&amp_priv->lock);
             return result;
+        }
 
         data = node_to_item(amp_priv->events_list.next,
                             struct mixer_plugin_event_data, node);
@@ -2196,6 +2215,8 @@
 
         list_remove(&data->node);
         free(data);
+        pthread_mutex_unlock(&amp_priv->lock);
+
         ev += sizeof(struct ctl_event);
         size -= sizeof(struct ctl_event);
         result += sizeof(struct ctl_event);
@@ -2248,6 +2269,7 @@
     amp_free_group_be_dev_info(amp_priv);
     amp_free_be_dev_info(amp_priv);
     amp_free_ctls(amp_priv);
+    pthread_mutex_destroy(&amp_priv->lock);
     free(amp_priv);
     free(*plugin);
     plugin = NULL;
@@ -2364,6 +2386,7 @@
     amp_register_event_callback(amp, 1);
     list_init(&amp_priv->events_paramlist);
     list_init(&amp_priv->events_list);
+    pthread_mutex_init(&amp_priv->lock, (const pthread_mutexattr_t *) NULL);
     AGM_LOGV("%s: total_ctl_cnt = %d\n", __func__, total_ctl_cnt);
 
     return 0;
diff --git a/plugins/tinyalsa/src/agm_pcm_plugin.c b/plugins/tinyalsa/src/agm_pcm_plugin.c
index 8c271d7..b8f375f 100644
--- a/plugins/tinyalsa/src/agm_pcm_plugin.c
+++ b/plugins/tinyalsa/src/agm_pcm_plugin.c
@@ -59,6 +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"
+
 struct agm_shared_pos_buffer {
     volatile uint32_t frame_counter;
     volatile uint32_t read_index;
@@ -98,6 +100,7 @@
     /* idx: 0: out port, 1: in port */
     struct agm_mmap_buffer_port mmap_buffer_port[2];
     bool mmap_status;
+    int fd;
 };
 
 struct pcm_plugin_hw_constraints agm_pcm_constrs = {
@@ -307,19 +310,48 @@
     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;
     snd_pcm_sframes_t circ_buf_pos;
     snd_pcm_uframes_t pos, old_hw_ptr, new_hw_ptr, hw_base;
     uint32_t read_index, wall_clk_msw, wall_clk_lsw;
-    uint64_t delta_wall_clk_us = 0;
+    int64_t delta_wall_clk_us = 0;
     uint32_t delta_wall_clk_frames = 0;
     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);
@@ -334,9 +366,9 @@
 
         // Set delta_wall_clk_us only if cached wall clk is non-zero
         if (priv->pos_buf->wall_clk_msw || priv->pos_buf->wall_clk_lsw) {
-                delta_wall_clk_us = (((uint64_t)wall_clk_msw) << 32 | wall_clk_lsw) -
+                delta_wall_clk_us = (int64_t)((((uint64_t)wall_clk_msw) << 32 | wall_clk_lsw) -
                                         (((uint64_t)priv->pos_buf->wall_clk_msw) << 32 |
-                                         priv->pos_buf->wall_clk_lsw);
+                                         priv->pos_buf->wall_clk_lsw));
         }
         // Identify the number of times of shared buffer length that the
         // hw ptr has jumped through by checking wall clock time delta
@@ -689,6 +721,10 @@
             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);
 
@@ -735,6 +771,8 @@
         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) {
@@ -923,6 +961,13 @@
         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;
@@ -970,6 +1015,10 @@
 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/plugins/tinyalsa/test/Android.mk b/plugins/tinyalsa/test/Android.mk
index abca51c..8db0db3 100644
--- a/plugins/tinyalsa/test/Android.mk
+++ b/plugins/tinyalsa/test/Android.mk
@@ -134,9 +134,9 @@
     libagm_headers \
     libacdb_headers
 
-#if android version is R, refer to qtitinyxx otherwise use upstream ones
-#This assumes we would be using AR code only for Android R and subsequent versions.
-ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+# Use flag based selection to use QTI vs open source tinycompress project
+
+ifeq ($(TARGET_USES_QTI_TINYCOMPRESS),true)
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinycompress/include
 LOCAL_SHARED_LIBRARIES += libqti-tinyalsa\
@@ -171,9 +171,9 @@
     libagm_headers \
     libacdb_headers
 
-#if android version is R, refer to qtitinyxx otherwise use upstream ones
-#This assumes we would be using AR code only for Android R and subsequent versions.
-ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+# Use flag based selection to use QTI vs open source tinycompress project
+
+ifeq ($(TARGET_USES_QTI_TINYCOMPRESS),true)
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
 LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinycompress/include
 LOCAL_SHARED_LIBRARIES += libqti-tinyalsa\
diff --git a/plugins/tinyalsa/test/agmcompresscap.c b/plugins/tinyalsa/test/agmcompresscap.c
index 08c7061..aad5287 100644
--- a/plugins/tinyalsa/test/agmcompresscap.c
+++ b/plugins/tinyalsa/test/agmcompresscap.c
@@ -471,13 +471,13 @@
 
 int main(int argc, char **argv)
 {
-    char *file;
+    char *file = NULL;
     unsigned long buffer_size = 0;
     unsigned int card = 0, device = 0, frag = 0, length = 0;
     unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS;
     unsigned int bits = 16;
     unsigned int format = DEFAULT_FORMAT;
-    char* intf_name;
+    char* intf_name = NULL;
     int ret = 0;
     unsigned int devicepp_kv = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
     unsigned int stream_kv = 0;
diff --git a/plugins/tinyalsa/test/agmhostless.c b/plugins/tinyalsa/test/agmhostless.c
index d9228a2..4819725 100644
--- a/plugins/tinyalsa/test/agmhostless.c
+++ b/plugins/tinyalsa/test/agmhostless.c
@@ -219,6 +219,11 @@
     struct group_config grp_config;
     stream_kv = stream_kv ? stream_kv : PCM_RX_LOOPBACK;
 
+    if (!cap_config || !p_config || !capture_intf || !play_intf) {
+        printf("%s: %d: Invalid arguments.\n", __func__, __LINE__);
+        return;
+    }
+
     memset(&config, 0, sizeof(config));
     config.channels = channels;
     config.rate = rate;
diff --git a/service/src/device.c b/service/src/device.c
index 743972f..b333730 100644
--- a/service/src/device.c
+++ b/service/src/device.c
@@ -1022,7 +1022,7 @@
          * Here, pcm->idname is in the form of "<dai_link->stream_name>
                                           <codec_name>-<num_codecs>"
          */
-        sscanf(buffer, "%02u-%02u: %80s", &dev_obj->card_id,
+        sscanf(buffer, "%02u-%02u: %79s", &dev_obj->card_id,
                            &dev_obj->pcm_id, dev_obj->name);
         AGM_LOGD("%d:%d:%s\n", dev_obj->card_id, dev_obj->pcm_id, dev_obj->name);
 
diff --git a/service/src/metadata.c b/service/src/metadata.c
index 87c0677..c94f856 100644
--- a/service/src/metadata.c
+++ b/service/src/metadata.c
@@ -71,6 +71,8 @@
 #define NUM_PROPS(x)                    *((uint32_t *) PTR_TO_NUM_PROPS(x))
 #define PTR_TO_PROPS(x)                 (PTR_TO_NUM_PROPS(x) + sizeof(uint32_t))
 
+#define MAX_KVPAIR 48
+
 void metadata_print(struct agm_meta_data_gsl* metadata)
 {
     int i, count = metadata->gkv.num_kvs;
@@ -201,6 +203,13 @@
     }
     va_end(valist);
 
+    if ((merged->gkv.num_kvs > MAX_KVPAIR) || (merged->ckv.num_kvs > MAX_KVPAIR)) {
+        AGM_LOGE("Num GKVs %d Num CKVs %d more than expected: %d", merged->gkv.num_kvs,
+                                                      merged->ckv.num_kvs, MAX_KVPAIR);
+        free(merged);
+        return NULL;
+    }
+
     merged->gkv.kv = calloc(merged->gkv.num_kvs, sizeof(struct agm_key_value));
     if (!merged->gkv.kv) {
         AGM_LOGE("No memory to merge gkv\n");
@@ -271,6 +280,14 @@
         AGM_LOGI("NULL metadata passed, ignoring\n");
         return ret;
     }
+
+    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);
+        ret = -EINVAL;
+        return ret;
+    }
+
     dest->gkv.num_kvs = NUM_GKV(metadata);
     dest->gkv.kv =  calloc(dest->gkv.num_kvs, sizeof(struct agm_key_value));
     if (!dest->gkv.kv) {
diff --git a/service/test/src/agm_test.c b/service/test/src/agm_test.c
index e2f0078..a3a4f2b 100644
--- a/service/test/src/agm_test.c
+++ b/service/test/src/agm_test.c
@@ -478,6 +478,10 @@
 
 	if (num_aif_info > 0) {
 		aifinfo = calloc(num_aif_info, sizeof(struct aif_info));
+		if (aifinfo == NULL) {
+			ret = -1;
+			goto fail;
+		}
 	} else {
 		ret = -1;
 		goto fail;