/*
 * Copyright (C) 2018 Knowles Electronics
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "SoundTriggerHAL"
#define LOG_NDEBUG 0

#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <poll.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <log/log.h>
#include <cutils/uevent.h>
#include <cutils/properties.h>
#include <math.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/timerfd.h>

#include <hardware/hardware.h>
#include <hardware_legacy/power.h>

#include "cvq_ioctl.h"
#include "sound_trigger_hw_iaxxx.h"
#include "sound_trigger_intf.h"

#define MAX_GENERIC_SOUND_MODELS    (9)
#define MAX_KEY_PHRASES             (1)
#define MAX_MODELS                  (MAX_GENERIC_SOUND_MODELS + MAX_KEY_PHRASES)

#define MAX_USERS                   (1)
#define MAX_BUFFER_MS               (3000)
#define POWER_CONSUMPTION           (0) // TBD
#define ST_HAL_VERSION              (1)

#define UEVENT_MSG_LEN              (1024)

#define OK_GOOGLE_KW_ID             (0)
#define AMBIENT_KW_ID               (1)
#define ENTITY_KW_ID                (2)
#define WAKEUP_KW_ID                (3)
#define USELESS_KW_ID               (999)

#define CVQ_ENDPOINT                    (IAXXX_SYSID_PLUGIN_1_OUT_EP_0)
#define MUSIC_BUF_ENDPOINT              (IAXXX_SYSID_PLUGIN_3_OUT_EP_1)

#define IAXXX_VQ_EVENT_STR          "IAXXX_VQ_EVENT"
#define IAXXX_RECOVERY_EVENT_STR    "IAXXX_RECOVERY_EVENT"
#define IAXXX_FW_DWNLD_SUCCESS_STR  "IAXXX_FW_DWNLD_SUCCESS"
#define IAXXX_FW_CRASH_EVENT_STR    "IAXXX_CRASH_EVENT"

#define WAKE_LOCK_NAME "sthal_wake_lock"

#define CARD_NAME                          "iaxxx"
#define SOUND_TRIGGER_MIXER_PATH_BASE      "/vendor/etc/sound_trigger_mixer_paths"
#define SOUND_TRIGGER_MIXER_PATH_XML       "/vendor/etc/sound_trigger_mixer_paths_default.xml"

#define MAX_SND_CARD    (8)
#define RETRY_NUMBER    (10)
#define RETRY_US        (500000)
#define TUNNEL_TIMEOUT  5

#define SENSOR_CREATE_WAIT_TIME_IN_S   (1)
#define SENSOR_CREATE_WAIT_MAX_COUNT   (5)

#define CHRE_CREATE_WAIT_TIME_IN_S   (1)
#define CHRE_CREATE_WAIT_MAX_COUNT   (5)

#define ST_DEVICE_HANDSET_MIC 1

#ifdef __LP64__
#define ADNC_STRM_LIBRARY_PATH "/vendor/lib64/hw/adnc_strm.primary.default.so"
#else
#define ADNC_STRM_LIBRARY_PATH "/vendor/lib/hw/adnc_strm.primary.default.so"
#endif

static const struct sound_trigger_properties hw_properties = {
    "Knowles Electronics",      // implementor
    "Continous VoiceQ",         // description
    1,                          // version
    // Version UUID
    { 0x80f7dcd5, 0xbb62, 0x4816, 0xa931, {0x9c, 0xaa, 0x52, 0x5d, 0xf5, 0xc7}},
    MAX_MODELS,                 // max_sound_models
    MAX_KEY_PHRASES,            // max_key_phrases
    MAX_USERS,                  // max_users
    RECOGNITION_MODE_VOICE_TRIGGER | // recognition_mode
    RECOGNITION_MODE_GENERIC_TRIGGER,
    true,                       // capture_transition
    MAX_BUFFER_MS,              // max_capture_ms
    true,                      // concurrent_capture
    false,                      // trigger_in_event
    POWER_CONSUMPTION           // power_consumption_mw
};

struct model_info {
    void *recognition_cookie;
    void *sound_model_cookie;
    sound_model_handle_t model_handle;
    sound_trigger_uuid_t uuid;
    recognition_callback_t recognition_callback;
    sound_model_callback_t sound_model_callback;
    struct sound_trigger_recognition_config *config;
    int kw_id;
    sound_trigger_sound_model_type_t type;

    void *data;
    int data_sz;
    bool is_loaded;
    bool is_active;
    bool is_state_query;
};

struct knowles_sound_trigger_device {
    struct sound_trigger_hw_device device;
    struct model_info models[MAX_MODELS];
    sound_trigger_uuid_t authkw_model_uuid;
    pthread_t callback_thread;
    pthread_t monitor_thread;
    pthread_t transitions_thread;
    pthread_mutex_t lock;
    pthread_cond_t transition_cond;
    pthread_cond_t tunnel_create;
    pthread_cond_t sensor_create;
    pthread_cond_t chre_create;
    int opened;
    int send_sock;
    int recv_sock;
    struct sound_trigger_recognition_config *last_keyword_detected_config;

    // Information about streaming
    int is_streaming;
    void *adnc_cvq_strm_lib;
    int (*adnc_strm_open)(bool, int, int);
    size_t (*adnc_strm_read)(long, void *, size_t);
    int (*adnc_strm_close)(long);
    long adnc_strm_handle[MAX_MODELS];
    struct timespec adnc_strm_last_read[MAX_MODELS];

    sound_trigger_uuid_t hotword_model_uuid;
    sound_trigger_uuid_t sensor_model_uuid;
    sound_trigger_uuid_t ambient_model_uuid;
    sound_trigger_uuid_t chre_model_uuid;
    sound_trigger_uuid_t entity_model_uuid;
    sound_trigger_uuid_t wakeup_model_uuid;

    int last_detected_model_type;
    bool is_mic_route_enabled;
    bool is_bargein_route_enabled;
    bool is_chre_loaded;
    bool is_buffer_package_loaded;
    bool is_sensor_route_enabled;
    bool is_src_package_loaded;
    bool is_st_hal_ready;
    int hotword_buffer_enable;
    int music_buffer_enable;
    bool is_sensor_destroy_in_prog;
    bool is_chre_destroy_in_prog;

    // conditions indicate AHAL and mic concurrency status
    bool is_concurrent_capture;
    bool is_con_mic_route_enabled;
    bool is_ahal_media_recording;
    bool is_ahal_in_voice_voip_mode;
    bool is_ahal_voice_voip_stop;
    bool is_ahal_voice_voip_start;

    unsigned int current_enable;
    unsigned int recover_model_list;
    unsigned int rx_active_count;
    transit_case_t transit_case;

    struct audio_route *route_hdl;
    struct mixer *mixer;
    struct iaxxx_odsp_hw *odsp_hdl;

    void *audio_hal_handle;
    audio_hw_call_back_t audio_hal_cb;
    unsigned int sthal_prop_api_version;

    int snd_crd_num;
    char mixer_path_xml[NAME_MAX_SIZE];
    bool fw_reset_done_by_hal;

    // sensor stop signal event
    timer_t ss_timer;
    bool ss_timer_created;

    // Chre stop signal event
    timer_t chre_timer;
    bool chre_timer_created;
};

/*
 * Since there's only ever one sound_trigger_device, keep it as a global so
 * that other people can dlopen this lib to get at the streaming audio.
 */

static struct knowles_sound_trigger_device g_stdev =
{
    .lock = PTHREAD_MUTEX_INITIALIZER,
    .tunnel_create = PTHREAD_COND_INITIALIZER,
    .sensor_create = PTHREAD_COND_INITIALIZER,
    .chre_create = PTHREAD_COND_INITIALIZER
};

static struct timespec reset_time = {0};

static enum sthal_mode get_sthal_mode(struct knowles_sound_trigger_device *stdev)
{
    enum sthal_mode stmode = CON_DISABLED_ST;

    if (stdev->is_ahal_in_voice_voip_mode == true) {
        stmode = IN_CALL;
        goto exit;
    }

    if (stdev->is_concurrent_capture == false) {
        if (stdev->is_ahal_media_recording == true)
          stmode = CON_DISABLED_CAPTURE;
        else
          stmode = CON_DISABLED_ST;
        goto exit;
    }

    if (stdev->is_con_mic_route_enabled == true ) {
        stmode = CON_ENABLED_CAPTURE_ST;
        goto exit;
    } else {
        stmode = CON_ENABLED_ST;
        goto exit;
    }

    ALOGW("%s: Invalid ST mode, use defualt mode", __func__);

exit:
    //ALOGV("%s: ST mode is %d", __func__, stmode);
    return stmode;
}

static bool can_enable_chre(struct knowles_sound_trigger_device *stdev)
{
    bool ret = false;
    enum sthal_mode stm = get_sthal_mode(stdev);

    if (stm == CON_ENABLED_CAPTURE_ST ||
        stm == CON_ENABLED_ST ||
        stm == CON_DISABLED_ST)
        ret = true;
    return ret;
}

static bool can_update_recover_list(struct knowles_sound_trigger_device *stdev)
{
    bool ret = false;
    enum sthal_mode stm = get_sthal_mode(stdev);

    if (stm == IN_CALL || stm == CON_DISABLED_CAPTURE)
        ret = true;
    return ret;
}

static bool is_mic_controlled_by_ahal(struct knowles_sound_trigger_device *stdev)
{
    bool ret = false;

    if (get_sthal_mode(stdev) == CON_ENABLED_CAPTURE_ST)
        ret = true;
    return ret;
}

static bool check_uuid_equality(sound_trigger_uuid_t uuid1,
                                sound_trigger_uuid_t uuid2)
{
    if (uuid1.timeLow != uuid2.timeLow ||
        uuid1.timeMid != uuid2.timeMid ||
        uuid1.timeHiAndVersion != uuid2.timeHiAndVersion ||
        uuid1.clockSeq != uuid2.clockSeq) {
        return false;
    }

    for (int i = 0; i < 6; i++) {
        if(uuid1.node[i] != uuid2.node[i]) {
            return false;
        }
    }

    return true;
}

bool str_to_uuid(char* uuid_str, sound_trigger_uuid_t* uuid)
{
    if (uuid_str == NULL) {
        ALOGI("Invalid str_to_uuid input.");
        return false;
    }

    int tmp[10];
    if (sscanf(uuid_str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5,
            tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
        ALOGI("Invalid UUID, got: %s", uuid_str);
        return false;
    }
    uuid->timeLow = (unsigned int)tmp[0];
    uuid->timeMid = (unsigned short)tmp[1];
    uuid->timeHiAndVersion = (unsigned short)tmp[2];
    uuid->clockSeq = (unsigned short)tmp[3];
    uuid->node[0] = (unsigned char)tmp[4];
    uuid->node[1] = (unsigned char)tmp[5];
    uuid->node[2] = (unsigned char)tmp[6];
    uuid->node[3] = (unsigned char)tmp[7];
    uuid->node[4] = (unsigned char)tmp[8];
    uuid->node[5] = (unsigned char)tmp[9];

    return true;
}

static int find_empty_model_slot(struct knowles_sound_trigger_device *st_dev)
{
    int i = -1;
    for (i = 0; i < MAX_MODELS; i++) {
        if (st_dev->models[i].is_loaded == false)
            break;
    }

    if (i >= MAX_MODELS) {
        i = -1;
    }

    return i;
}

static int find_handle_for_kw_id(
                        struct knowles_sound_trigger_device *st_dev, int kw_id)
{
    int i = 0;
    for (i = 0; i < MAX_MODELS; i++) {
        if (kw_id == st_dev->models[i].kw_id)
            break;
    }

    return i;
}

static int find_handle_for_uuid(
                        struct knowles_sound_trigger_device *stdev,
                        sound_trigger_uuid_t uuid)
{
    int i = 0;
    for (i = 0; i < MAX_MODELS; i++) {
        if (check_uuid_equality(uuid, stdev->models[i].uuid))
            break;
    }

    if (i == MAX_MODELS)
        return -1;
    else
        return i;
}

static bool is_any_model_active(struct knowles_sound_trigger_device *stdev) {
    int i = 0;
    for (i = 0; i < MAX_MODELS; i++) {
        if (stdev->models[i].is_active == true) {
            break;
        }
    }

    if (i == MAX_MODELS)
        return false;
    else
        return true;
}

static bool is_any_model_loaded(struct knowles_sound_trigger_device *stdev) {
    int i = 0;
    for (i = 0; i < MAX_MODELS; i++) {
        if (stdev->models[i].is_loaded == true) {
            break;
        }
    }

    if (i == MAX_MODELS)
        return false;
    else
        return true;
}

static void reg_hal_event_session(
                                struct sound_trigger_recognition_config *config,
                                sound_model_handle_t handle)
{
    struct knowles_sound_trigger_device *stdev = &g_stdev;
    struct sound_trigger_event_info event_info;
    /*
     * Register config and capture_handle of trigger sound model to audio hal
     * It only register while request capturing buffer.
     */
    if (config->capture_requested && stdev->audio_hal_cb) {
        ALOGD("%s: ST_EVENT_SESSION_REGISTER capture_handle %d model %p",
            __func__, config->capture_handle, &stdev->models[handle]);
        event_info.st_ses.p_ses = (void *)&stdev->models[handle];
        event_info.st_ses.config = stdev_hotword_pcm_config;
        event_info.st_ses.capture_handle = config->capture_handle;
        event_info.st_ses.pcm = NULL;
        stdev->audio_hal_cb(ST_EVENT_SESSION_REGISTER, &event_info);
    }
}

static void dereg_hal_event_session(
                                struct sound_trigger_recognition_config *config,
                                sound_model_handle_t handle)
{
    struct knowles_sound_trigger_device *stdev = &g_stdev;
    struct sound_trigger_event_info event_info;
    /*
     * Indicate to audio hal that streaming is stopped.
     * Stop capturing data from STHAL.
     */
    if (config->capture_requested && stdev->audio_hal_cb) {
        ALOGD("%s: ST_EVENT_SESSION_DEREGISTER capture_handle %d model %p",
            __func__, config->capture_handle, &stdev->models[handle]);
        event_info.st_ses.p_ses = (void *)&stdev->models[handle];
        event_info.st_ses.capture_handle = config->capture_handle;
        event_info.st_ses.pcm = NULL;
        stdev->audio_hal_cb(ST_EVENT_SESSION_DEREGISTER, &event_info);
    }
}


static char *stdev_keyphrase_event_alloc(sound_model_handle_t handle,
                                struct sound_trigger_recognition_config *config,
                                int recognition_status)
{
    char *data;
    struct sound_trigger_phrase_recognition_event *event;
    data = (char *)calloc(1,
                        sizeof(struct sound_trigger_phrase_recognition_event));
    if (!data)
        return NULL;
    event = (struct sound_trigger_phrase_recognition_event *)data;
    event->common.status = recognition_status;
    event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
    event->common.model = handle;
    event->common.capture_available = false;

    if (config) {
        unsigned int i;

        event->num_phrases = config->num_phrases;
        if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
            event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
        for (i = 0; i < event->num_phrases; i++)
            memcpy(&event->phrase_extras[i],
                &config->phrases[i],
                sizeof(struct sound_trigger_phrase_recognition_extra));
    }

    event->num_phrases = 1;
    event->phrase_extras[0].confidence_level = 100;
    event->phrase_extras[0].num_levels = 1;
    event->phrase_extras[0].levels[0].level = 100;
    event->phrase_extras[0].levels[0].user_id = 0;
    /*
     * Signify that all the data is comming through streaming
     * and not through the buffer.
     */
    event->common.capture_available = true;
    event->common.capture_delay_ms = 0;
    event->common.capture_preamble_ms = 0;
    event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
    event->common.audio_config.sample_rate = 16000;
    event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
    event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;

    return data;
}

static char *stdev_generic_event_alloc(int model_handle, void *payload,
                                    unsigned int payload_size,
                                    int recognition_status)
{
    char *data;
    struct sound_trigger_generic_recognition_event *event;

    data = (char *)calloc(1,
                        sizeof(struct sound_trigger_generic_recognition_event) +
                        payload_size);
    if (!data) {
        ALOGE("%s: Failed to allocate memory for recog event", __func__);
        return NULL;
    }

    event = (struct sound_trigger_generic_recognition_event *)data;
    event->common.status = recognition_status;
    event->common.type = SOUND_MODEL_TYPE_GENERIC;
    event->common.model = model_handle;

    /*
     * Signify that all the data is comming through streaming and
     * not through the buffer.
     */
    event->common.capture_available = true;
    event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
    event->common.audio_config.sample_rate = 16000;
    event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
    event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;

    if (payload && payload_size > 0) {
        ALOGD("%s: Attach payload in the event", __func__);
        event->common.data_size = payload_size;
        event->common.data_offset =
                        sizeof(struct sound_trigger_generic_recognition_event);

        memcpy((data + event->common.data_offset), payload, payload_size);
    }

    return data;
}

static void stdev_close_term_sock(struct knowles_sound_trigger_device *stdev)
{
    if (stdev->send_sock >= 0) {
        close(stdev->send_sock);
        stdev->send_sock = -1;
    }

    if (stdev->recv_sock >= 0) {
        close(stdev->recv_sock);
        stdev->recv_sock = -1;
    }
}

static bool is_uuid_in_recover_list(struct knowles_sound_trigger_device *stdev,
                                    sound_model_handle_t handle)
{
    int mask = 0;
    sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;

    if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
        mask = CHRE_MASK;
    } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
               check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
        mask = PLUGIN1_MASK;
    } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
               check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
        mask = PLUGIN2_MASK;
    } else {
       //ALOGV("%s: Invalid uuid.", __func__);
    }

    return (stdev->recover_model_list & mask) ? true : false;
}

static void update_recover_list(struct knowles_sound_trigger_device *stdev,
                                sound_model_handle_t handle,
                                bool enable)
{
    int mask = 0;

    sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;

    ALOGD("%s: handle %d enable %d", __func__, handle, enable);
    if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
        mask = CHRE_MASK;
    } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
               check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
        mask = PLUGIN1_MASK;
    } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
               check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
        mask = PLUGIN2_MASK;
    } else {
       //ALOGV("%s: Invalid uuid.", __func__);
    }

    if (enable)
        stdev->recover_model_list |= mask;
    else
        stdev->recover_model_list &= ~mask;

    return;
}

static int check_and_setup_src_package(
                                    struct knowles_sound_trigger_device *stdev)
{
    int err = 0;

    if (stdev->is_src_package_loaded == false) {
        err = setup_src_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to load SRC package", __func__);
            goto exit;
        } else {
            ALOGD("%s: SRC package loaded", __func__);
            stdev->is_src_package_loaded = true;
        }
    } else {
        ALOGD("%s: SRC package is already loaded", __func__);
    }

exit:
    return err;
}

static int check_and_destroy_src_package(
                                    struct knowles_sound_trigger_device *stdev)
{
    int err = 0;

    if (!is_any_model_active(stdev) && stdev->is_src_package_loaded == true) {
        err = destroy_src_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to destroy SRC package", __func__);
            goto exit;
        } else {
            ALOGD("%s: SRC package destroy", __func__);
            stdev->is_src_package_loaded = false;
        }
    }

exit:
    return err;
}

static int check_and_setup_buffer_package(
                                    struct knowles_sound_trigger_device *stdev)
{
    int err = 0;

    if (stdev->is_buffer_package_loaded == false) {
        err = setup_buffer_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to load Buffer package", __func__);
            goto exit;
        } else {
            ALOGD("%s: Buffer package loaded", __func__);
            stdev->is_buffer_package_loaded = true;
        }
    } else {
        ALOGD("%s: Buffer package is already loaded", __func__);
    }

exit:
    return err;
}

static int check_and_destroy_buffer_package(
                                    struct knowles_sound_trigger_device *stdev)
{
    int err = 0;

    if (!is_any_model_active(stdev) &&
        stdev->is_buffer_package_loaded &&
        (!stdev->is_sensor_destroy_in_prog &&
        !stdev->is_sensor_route_enabled) &&
        (!stdev->is_chre_destroy_in_prog &&
        !stdev->is_chre_loaded)) {

        err = destroy_buffer_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to destroy Buffer package", __func__);
            goto exit;
        } else {
            ALOGD("%s: Buffer package destroy", __func__);
            stdev->is_buffer_package_loaded = false;
        }
    }

exit:
    return err;
}

static int setup_package(struct knowles_sound_trigger_device *stdev,
                        struct model_info *model)
{
    int err = 0;

    if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
        if (!(stdev->current_enable & CHRE_MASK)) {
            err = setup_chre_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load CHRE package");
                goto exit;
            }
        }
        stdev->current_enable = stdev->current_enable | CHRE_MASK;
    } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
        if (!(stdev->current_enable & PLUGIN1_MASK)) {
            err = setup_hotword_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load Hotword package");
                goto exit;
            }
        }
        err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
                        model->kw_id);
        if (err != 0) {
            ALOGE("Failed to write Hotword model");
            goto exit;
        }

        //setup model state.
        stdev->current_enable = stdev->current_enable | HOTWORD_MASK;
        err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
        if (err != 0) {
            ALOGE("Failed to set Hotword state");
            goto exit;
        }
    } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
        if (!(stdev->current_enable & PLUGIN1_MASK)) {
            err = setup_hotword_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load Hotword package");
                goto exit;
            }
        }
        err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
                        model->kw_id);
        if (err != 0) {
            ALOGE("Failed to write Wakeup model");
            goto exit;
        }

        //setup model state.
        stdev->current_enable = stdev->current_enable | WAKEUP_MASK;
        err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
        if (err != 0) {
            ALOGE("Failed to set Wakeup state");
            goto exit;
        }
    } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
        if (!(stdev->current_enable & PLUGIN2_MASK)) {
            err = setup_ambient_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load Ambient package");
                goto exit;
            }
        } else {
            // tear down plugin2 for writing new model data.
            err = tear_ambient_state(stdev->odsp_hdl,
                                    stdev->current_enable);
        }
        err = write_model(stdev->odsp_hdl, model->data,
                        model->data_sz, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to write Ambient model");
            goto exit;
        }

        //setup model state.
        stdev->current_enable = stdev->current_enable | AMBIENT_MASK;
        err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
        if (err != 0) {
            ALOGE("Failed to set Ambient state");
            goto exit;
        }

    } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
        if (!(stdev->current_enable & PLUGIN2_MASK)) {
            err = setup_ambient_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load Ambient package");
                goto exit;
            }
        } else {
            // tear down plugin2 for writing new model data.
            err = tear_ambient_state(stdev->odsp_hdl,
                                    stdev->current_enable);
        }
        err = write_model(stdev->odsp_hdl, model->data,
                        model->data_sz, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to write Entity model");
            goto exit;
        }

        //setup model state.
        stdev->current_enable = stdev->current_enable | ENTITY_MASK;
        err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
        if (err != 0) {
            ALOGE("Failed to set Entity state");
            goto exit;
        }
    }

exit:
    return err;
}

static int setup_buffer(struct knowles_sound_trigger_device *stdev,
                        struct model_info *model,
                        bool enabled)
{
    int err = 0;
    if (enabled) {
        if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
            || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {

            stdev->hotword_buffer_enable++;
            if (stdev->hotword_buffer_enable > 1)
                goto exit;

            err = setup_howord_buffer(stdev->odsp_hdl);
            if (err != 0) {
                stdev->hotword_buffer_enable--;
                ALOGE("Failed to create the buffer plugin");
                goto exit;
            }
        } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
            || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {

            stdev->music_buffer_enable++;
            if (stdev->music_buffer_enable > 1)
                goto exit;

            err = setup_music_buffer(stdev->odsp_hdl);
            if (err != 0) {
                stdev->music_buffer_enable--;
                ALOGE("Failed to load music buffer package");
                goto exit;
            }
        }
    } else {
        if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
           || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
            if (stdev->hotword_buffer_enable == 0) {
                ALOGW("Invalid call for setup buffer");
                goto exit;
            }
            stdev->hotword_buffer_enable--;
            if (stdev->hotword_buffer_enable != 0)
                goto exit;

            err = destroy_howord_buffer(stdev->odsp_hdl);

            if (err != 0) {
                ALOGE("Failed to unload hotword buffer package");
                goto exit;
            }

        } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
           || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
            if (stdev->music_buffer_enable == 0) {
                ALOGW("Invalid call for setup buffer");
                goto exit;
            }
            stdev->music_buffer_enable--;
            if (stdev->music_buffer_enable != 0)
                goto exit;

            err = destroy_music_buffer(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to unload music buffer package");
                goto exit;
            }
       }
    }

exit:
    return err;
}

static int destroy_package(struct knowles_sound_trigger_device *stdev,
                        struct model_info *model)
{
    int err = 0;

    if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
        stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
        if (!(stdev->current_enable & CHRE_MASK)) {
            err = destroy_chre_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to destroy CHRE package");
                goto exit;
            }
        }
    } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
        err = tear_hotword_state(stdev->odsp_hdl, HOTWORD_MASK);
        if (err != 0) {
            ALOGE("Failed to tear Hotword state");
            goto exit;
        }

        err = flush_model(stdev->odsp_hdl, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to flush Hotword model");
            goto exit;
        }
        stdev->current_enable = stdev->current_enable & ~HOTWORD_MASK;

        if (!(stdev->current_enable & PLUGIN1_MASK)) {
            err = destroy_hotword_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to destroy Hotword package");
                goto exit;
            }
        }

    } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
        err = tear_hotword_state(stdev->odsp_hdl, WAKEUP_MASK);
        if (err != 0) {
            ALOGE("Failed to tear Wakeup state");
            goto exit;
        }

        err = flush_model(stdev->odsp_hdl, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to flush Wakeup model");
            goto exit;
        }
        stdev->current_enable = stdev->current_enable & ~WAKEUP_MASK;

        if (!(stdev->current_enable & PLUGIN1_MASK)) {
            err = destroy_hotword_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to destroy Hotword package");
                goto exit;
            }
        }

    } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
        err = tear_ambient_state(stdev->odsp_hdl, AMBIENT_MASK);
        if (err != 0) {
            ALOGE("Failed to tear Ambient state");
            goto exit;
        }

        err = flush_model(stdev->odsp_hdl, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to flush Ambient model");
            goto exit;
        }
        stdev->current_enable = stdev->current_enable & ~AMBIENT_MASK;

        if (!(stdev->current_enable & PLUGIN2_MASK)) {
            err = destroy_ambient_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to destroy Ambient package");
                goto exit;
            }
        }
    } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
        err = tear_ambient_state(stdev->odsp_hdl, ENTITY_MASK);
        if (err != 0) {
            ALOGE("Failed to tear Entity state");
            goto exit;
        }

        err = flush_model(stdev->odsp_hdl, model->kw_id);
        if (err != 0) {
            ALOGE("Failed to flush Entity model");
            goto exit;
        }
        stdev->current_enable = stdev->current_enable & ~ENTITY_MASK;

        if (!(stdev->current_enable & PLUGIN2_MASK)) {
            err = destroy_ambient_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to destroy Ambient package");
                goto exit;
            }
        }
    }
exit:
    return err;
}

static int set_package_route(struct knowles_sound_trigger_device *stdev,
                            sound_trigger_uuid_t uuid,
                            bool bargein)
{
    int ret = 0;
    /*
     *[TODO] Add correct error return value for package route
     * b/119390722 for tracing.
     */
    if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
        if (stdev->is_chre_loaded == true) {
            set_chre_audio_route(stdev->route_hdl, bargein);
        }
    } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK)) {
            set_hotword_route(stdev->route_hdl, bargein);
        }
    } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK)) {
            set_hotword_route(stdev->route_hdl, bargein);
        }
    } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK)) {
            set_ambient_route(stdev->route_hdl, bargein);
        }
    } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK)) {
            set_ambient_route(stdev->route_hdl, bargein);
        }
    }

    return ret;
}

static int tear_package_route(struct knowles_sound_trigger_device *stdev,
                            sound_trigger_uuid_t uuid,
                            bool bargein)
{
    int ret = 0;
    /*
     *[TODO] Add correct error return value for package route
     * b/119390722 for tracing.
     */
    if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
        if (stdev->is_chre_loaded == true) {
            tear_chre_audio_route(stdev->route_hdl, bargein);
        }
    } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK))
            tear_hotword_route(stdev->route_hdl, bargein);
    } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK))
            tear_hotword_route(stdev->route_hdl, bargein);
    } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK))
            tear_ambient_route(stdev->route_hdl, bargein);
    } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
        if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK))
            tear_ambient_route(stdev->route_hdl, bargein);
    }

    return ret;
}

static int async_setup_aec(struct knowles_sound_trigger_device *stdev)
{
    int ret = 0;
    if (stdev->rx_active_count > 0 &&
        stdev->is_bargein_route_enabled != true &&
        stdev->is_mic_route_enabled != false) {
        ALOGD("%s: Bargein enabling", __func__);
        if (is_mic_controlled_by_ahal(stdev) == false) {
            ret = enable_mic_route(stdev->route_hdl, false,
                                INTERNAL_OSCILLATOR);
            if (ret != 0) {
                ALOGE("Failed to disable mic route with INT OSC");
                goto exit;
            }
        }
        ret = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
        if (ret != 0) {
            ALOGE("Failed to load SRC-amp package");
            goto exit;
        }
        ret = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
        if (ret != 0) {
            ALOGE("Failed to enable SRC-amp route");
            goto exit;
        }

        ret = setup_aec_package(stdev->odsp_hdl);
        if (ret != 0) {
            ALOGE("Failed to load AEC package");
            goto exit;
        }
        ret = enable_bargein_route(stdev->route_hdl, true);
        if (ret != 0) {
            ALOGE("Failed to enable buffer route");
            goto exit;
        }

        if (is_mic_controlled_by_ahal(stdev) == false) {
            ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
            if (ret != 0) {
                ALOGE("Failed to enable amp-ref route");
                goto exit;
            }
            ret = enable_mic_route(stdev->route_hdl, true,
                                EXTERNAL_OSCILLATOR);
            if (ret != 0) {
                ALOGE("Failed to enable mic route with EXT OSC");
                goto exit;
            }
        } else {
            // main mic is turned by media recording
            ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
            if (ret != 0) {
                ALOGE("Failed to enable amp-ref route");
                goto exit;
            }
        }
        stdev->is_bargein_route_enabled = true;

        if (stdev->hotword_buffer_enable) {
            ret = tear_hotword_buffer_route(stdev->route_hdl,
                                !stdev->is_bargein_route_enabled);
            if (ret != 0) {
                ALOGE("Failed to tear old buffer route");
                goto exit;
            }
            ret = set_hotword_buffer_route(stdev->route_hdl,
                                stdev->is_bargein_route_enabled);
            if (ret != 0) {
                ALOGE("Failed to enable buffer route");
                goto exit;
            }
        }

        if (stdev->music_buffer_enable) {
            ret = tear_music_buffer_route(stdev->route_hdl,
                                !stdev->is_bargein_route_enabled);
            if (ret != 0) {
                ALOGE("Failed to tear old music buffer route");
                goto exit;
            }
            ret = set_music_buffer_route(stdev->route_hdl,
                                stdev->is_bargein_route_enabled);
            if (ret != 0) {
                ALOGE("Failed to enable buffer route");
                goto exit;
            }
        }

        // Check each model, if it is active then update it's route
        for (int i = 0; i < MAX_MODELS; i++) {
            if (stdev->models[i].is_active == true) {
                // teardown the package route without bargein
                ret = tear_package_route(stdev,
                                        stdev->models[i].uuid,
                                        !stdev->is_bargein_route_enabled);
                if (ret != 0) {
                    ALOGE("Failed to tear old package route");
                    goto exit;
                }
                // resetup the package route with bargein
                ret = set_package_route(stdev,
                                        stdev->models[i].uuid,
                                        stdev->is_bargein_route_enabled);
                if (ret != 0) {
                    ALOGE("Failed to enable package route");
                    goto exit;
                }
            }
        }
    } else {
        ALOGD("%s: Bargein is already enabled", __func__);
    }

exit:
    return ret;
}

static int handle_input_source(struct knowles_sound_trigger_device *stdev,
                            bool enable)
{
    int err = 0;
    enum clock_type ct = INTERNAL_OSCILLATOR;
    enum strm_type strmt = STRM_16K;

    if (stdev->rx_active_count > 0) {
        ct = EXTERNAL_OSCILLATOR;
    }

    if (is_mic_controlled_by_ahal(stdev) == true) {
        strmt = STRM_48K;
    }

    /*
     *[TODO] Add correct error return value for input source route
     * b/119390722 for tracing.
     */
    if (enable) {
        if (stdev->is_mic_route_enabled == false) {
            err = check_and_setup_src_package(stdev);
            if (err != 0) {
                ALOGE("Fail to setup src Package");
                goto exit;
            }
            err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
            if (err != 0) {
                ALOGE("Failed to load SRC package");
                goto exit;
            }
            err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
            if (err != 0) {
                ALOGE("Failed to enable SRC-mic route");
                goto exit;
            }
        }
        if (stdev->rx_active_count > 0 &&
            stdev->is_bargein_route_enabled == false) {
            err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
            if (err != 0) {
                ALOGE("Failed to load SRC-amp package");
                goto exit;
            }
            err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
            if (err != 0) {
                ALOGE("Failed to enable SRC-amp route");
                goto exit;
            }

            err = setup_aec_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load AEC package");
                // We didn't load AEC package so don't setup the routes
                goto exit;
            }

            // Enable the bargein route if not enabled
            err = enable_bargein_route(stdev->route_hdl, true);
            if (err != 0) {
                ALOGE("Failed to enable buffer route");
                goto exit;
            }
            err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
            if (err != 0) {
                ALOGE("Failed to amp-ref route");
                goto exit;
            }
            stdev->is_bargein_route_enabled = true;
        }
        if (stdev->is_mic_route_enabled == false) {
            if (is_mic_controlled_by_ahal(stdev) == false) {
                err = enable_mic_route(stdev->route_hdl, true, ct);
                if (err != 0) {
                    ALOGE("Failed to enable mic route");
                    goto exit;
                }
            }
            stdev->is_mic_route_enabled = true;
        }
    } else {
        if (!is_any_model_active(stdev)) {
            ALOGD("None of keywords are active");
            if (stdev->rx_active_count > 0 &&
                stdev->is_bargein_route_enabled == true) {
                // Just disable the route and update the route status but retain
                // bargein status
                err = enable_bargein_route(stdev->route_hdl, false);
                if (err != 0) {
                    ALOGE("Failed to disable bargein route");
                    goto exit;
                }
                err = destroy_aec_package(stdev->odsp_hdl);
                if (err != 0) {
                    ALOGE("Failed to unload AEC package");
                    goto exit;
                }
                err = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
                if (err != 0) {
                    ALOGE("Failed to disable SRC-amp route");
                    goto exit;
                }
                err = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
                if (err != 0) {
                    ALOGE("Failed to unload SRC-amp package");
                    goto exit;
                }
                err = enable_amp_ref_route(stdev->route_hdl, false, strmt);
                if (err != 0) {
                    ALOGE("Failed to amp-ref route");
                    goto exit;
                }
                stdev->is_bargein_route_enabled = false;
           }
           if (stdev->is_mic_route_enabled == true) {
               // Close SRC package
               err = enable_src_route(stdev->route_hdl, false, SRC_MIC);
               if (err != 0) {
                   ALOGE("Failed to disable SRC-mic route");
                   goto exit;
               }
               err = destroy_src_plugin(stdev->odsp_hdl, SRC_MIC);
               if (err != 0) {
                   ALOGE("Failed to unload SRC-mic package");
                   goto exit;
               }
               if (is_mic_controlled_by_ahal(stdev) == false) {
                   err = enable_mic_route(stdev->route_hdl, false, ct);
                   if (err != 0) {
                       ALOGE("Failed to disable mic route");
                       goto exit;
                   }
               }
               stdev->is_mic_route_enabled = false;
               err = check_and_destroy_src_package(stdev);
               if (err != 0) {
                   ALOGE("Fail to destroy src Package");
                   goto exit;
               }
           }
       }
    }

exit:
    return err;
}

static void update_rx_conditions(struct knowles_sound_trigger_device *stdev,
                                 audio_event_type_t event,
                                 struct audio_event_info *config)
{
    if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
        if (stdev->rx_active_count > 0) {
            stdev->rx_active_count--;
        } else {
            ALOGW("%s: unexpected rx inactive event", __func__);
        }
    } else if (event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
        if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
            ALOGD("%s: Playback device doesn't include SPEAKER.",
                  __func__);
        } else {
            stdev->rx_active_count++;
        }
    } else {
        ALOGW("%s: invalid event %d", __func__, event);
    }
    ALOGD("%s: updated rx_concurrency as %d", __func__,
          stdev->rx_active_count);
}


static void update_sthal_conditions(struct knowles_sound_trigger_device *stdev,
                                    audio_event_type_t event,
                                    struct audio_event_info *config)
{
    if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
        // get correct voice/voip mode in sthal
        if (stdev->is_ahal_in_voice_voip_mode == false &&
            stdev->is_ahal_voice_voip_stop == true &&
            stdev->is_ahal_media_recording == true) {
            ALOGD("%s: voice/voip didn't start, treat it as media recording inactive",
                  __func__);
            stdev->is_ahal_voice_voip_stop = false;
            stdev->is_ahal_media_recording = false;
        } else if (stdev->is_ahal_voice_voip_stop == true) {
            ALOGD("%s: voice/voip device is inactive", __func__);
            stdev->is_ahal_in_voice_voip_mode = false;
            stdev->is_ahal_voice_voip_stop = false;
        } else if (stdev->is_ahal_in_voice_voip_mode == true &&
                   stdev->is_ahal_voice_voip_stop == false &&
                   stdev->is_ahal_voice_voip_start == false) {
            ALOGD("%s: voice/voip usecase didn't start in incall mode, treat it as voice/voip is inactive",
                  __func__);
            stdev->is_ahal_in_voice_voip_mode = false;
        }

        if (stdev->is_concurrent_capture == true &&
            stdev->is_ahal_in_voice_voip_mode == false) {
            if (stdev->is_ahal_media_recording == true)
                stdev->is_con_mic_route_enabled = true;
            else
                stdev->is_con_mic_route_enabled = false;
            ALOGD("%s: update mic con %d", __func__,
                  stdev->is_con_mic_route_enabled);
        }
    } else if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
        if (stdev->is_ahal_in_voice_voip_mode == false &&
                (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
                 config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
            ALOGD("%s: voice/voip is actvie, close ST mic and don't use mic concurrently",
                  __func__);
            stdev->is_ahal_in_voice_voip_mode = true;
        }
        if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE) {
            stdev->is_ahal_media_recording = true;
        }
        if (stdev->is_concurrent_capture == true &&
            stdev->is_ahal_in_voice_voip_mode == false &&
            stdev->is_con_mic_route_enabled == false &&
            config->device_info.device == ST_DEVICE_HANDSET_MIC) {
            ALOGD("%s: enable mic concurrency", __func__);
                  stdev->is_con_mic_route_enabled = true;
        }
    } else if (event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE) {
        if (stdev->is_ahal_voice_voip_start == true &&
                (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
                 config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
            stdev->is_ahal_voice_voip_stop = true;
            stdev->is_ahal_voice_voip_start = false;
        } else if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE)
            stdev->is_ahal_media_recording = false;
    } else if (event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
        if (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
            config->u.usecase.type == USECASE_TYPE_VOIP_CALL) {
            stdev->is_ahal_voice_voip_start = true;
        }
    }
}

static bool do_handle_functions(struct knowles_sound_trigger_device *stdev,
                                enum sthal_mode pre_mode,
                                enum sthal_mode cur_mode,
                                audio_event_type_t event)
{
    int ret = 0;
    int i = 0;

    ALOGD("+%s+: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);

    // handle event AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE
    if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
        if ((pre_mode == CON_DISABLED_ST && cur_mode == CON_DISABLED_CAPTURE) ||
            (pre_mode == CON_DISABLED_ST && cur_mode == IN_CALL) ||
            (pre_mode == CON_DISABLED_CAPTURE && cur_mode == IN_CALL) ||
            (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == IN_CALL) ||
            (pre_mode == CON_ENABLED_ST && cur_mode == IN_CALL)) {
            // disable all ST
            // if tunnel is active, close it first
            for (i = 0; i < MAX_MODELS; i++) {
                if (stdev->adnc_strm_handle[i] != 0) {
                    ALOGD("%s: stop tunnling for index:%d", __func__, i);
                    stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
                    stdev->adnc_strm_handle[i] = 0;
                    stdev->adnc_strm_last_read[i] = reset_time;
                }
            }
            stdev->is_streaming = 0;

            for (i = 0; i < MAX_MODELS; i++) {
                if (stdev->models[i].is_active == true) {
                    update_recover_list(stdev, i, true);
                    tear_package_route(stdev, stdev->models[i].uuid,
                                       stdev->is_bargein_route_enabled);
                    stdev->models[i].is_active = false;
                    if (!check_uuid_equality(stdev->models[i].uuid,
                                             stdev->chre_model_uuid))
                        destroy_package(stdev, &stdev->models[i]);

                    if ((stdev->hotword_buffer_enable) &&
                        !(stdev->current_enable & PLUGIN1_MASK)) {
                        tear_hotword_buffer_route(stdev->route_hdl,
                                                  stdev->is_bargein_route_enabled);
                    }

                    if ((stdev->music_buffer_enable) &&
                        !(stdev->current_enable & PLUGIN2_MASK)) {
                        tear_music_buffer_route(stdev->route_hdl,
                                                stdev->is_bargein_route_enabled);
                    }

                    setup_buffer(stdev, &stdev->models[i], false);
                }
            }
            handle_input_source(stdev, false);
            check_and_destroy_buffer_package(stdev);
        } else if (pre_mode == CON_ENABLED_ST && cur_mode == CON_ENABLED_CAPTURE_ST) {
            //reconfig mic
            if (stdev->is_mic_route_enabled == true) {
                if (stdev->is_bargein_route_enabled == true) {
                    // close amp-ref first and reconfig it again with 48K after
                    // main mic is turned on by media recording
                    ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
                    if (ret != 0) {
                        ALOGE("Failed to disable amp-ref route");
                        goto exit;
                    }
                    ret = enable_mic_route(stdev->route_hdl, false,
                                           EXTERNAL_OSCILLATOR);
                    if (ret != 0) {
                        ALOGE("Failed to disable mic route with EXT OSC");
                        goto exit;
                    }

                    ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
                    if (ret != 0) {
                        ALOGE("Failed to enable amp-ref route");
                        goto exit;
                    }
                } else {
                    ret = enable_mic_route(stdev->route_hdl, false,
                                           INTERNAL_OSCILLATOR);
                    if (ret != 0) {
                        ALOGE("Failed to disable mic route with INT OSC");
                        goto exit;
                    }
                }
            } else {
                ALOGD("%s: ST mic isn't enabled, recording mic is turned on",
                       __func__);
            }
        }
    }

    // handle event AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE
    if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
        if ((pre_mode == IN_CALL && cur_mode == CON_DISABLED_ST) ||
            (pre_mode == IN_CALL && cur_mode == CON_DISABLED_CAPTURE) ||
            (pre_mode == IN_CALL && cur_mode == CON_ENABLED_ST) ||
            (pre_mode == IN_CALL && cur_mode == CON_ENABLED_CAPTURE_ST) ||
            (pre_mode == CON_DISABLED_CAPTURE && cur_mode == CON_DISABLED_ST)) {
            //recover all STs
            for (i = 0; i < MAX_MODELS; i++) {
                // recover all models from list
                if (is_uuid_in_recover_list(stdev, i)) {
                    if (stdev->models[i].is_active == false) {
                        check_and_setup_buffer_package(stdev);
                        stdev->models[i].is_active = true;
                        handle_input_source(stdev, true);

                        setup_buffer(stdev, &stdev->models[i], true);
                        if (stdev->hotword_buffer_enable &&
                            !(stdev->current_enable & PLUGIN1_MASK)) {
                            set_hotword_buffer_route(stdev->route_hdl,
                                                     stdev->is_bargein_route_enabled);
                        }
                        if (stdev->music_buffer_enable &&
                            !(stdev->current_enable & PLUGIN2_MASK)) {
                            set_music_buffer_route(stdev->route_hdl,
                                                   stdev->is_bargein_route_enabled);
                        }

                        if (!check_uuid_equality(stdev->models[i].uuid,
                                                 stdev->chre_model_uuid))
                            setup_package(stdev, &stdev->models[i]);
                        set_package_route(stdev, stdev->models[i].uuid,
                                          stdev->is_bargein_route_enabled);
                    }
                }
            }
            stdev->recover_model_list = 0;
        } else if (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == CON_ENABLED_ST) {
            // reconfig mic
            if (stdev->is_mic_route_enabled == true) {
                if (stdev->is_bargein_route_enabled == true) {
                    ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
                    if (ret != 0) {
                        ALOGE("Failed to disable amp-ref route");
                        goto exit;
                    }
                    ret = enable_mic_route(stdev->route_hdl, true,
                                           EXTERNAL_OSCILLATOR);
                    if (ret != 0) {
                        ALOGE("Failed to enable mic route with EXT OSC");
                        goto exit;
                    }
                    // turn on amp-ref with 16khz
                    ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
                    if (ret != 0) {
                        ALOGE("Failed to enable amp-ref route");
                        goto exit;
                    }
                } else {
                    ret = enable_mic_route(stdev->route_hdl, true,
                                           INTERNAL_OSCILLATOR);
                    if (ret != 0) {
                        ALOGE("Failed to enable mic route with INT OSC");
                        goto exit;
                    }
                }
            } else {
                ALOGD("%s: ST mic isn't enabled, recording mic is turned off",
                      __func__);
            }
        }
    }

exit:
    ALOGD("-%s-: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);
    return ret;
}

// stdev needs to be locked before calling this function
static int restart_recognition(struct knowles_sound_trigger_device *stdev)
{
    int err = 0;
    int i = 0;
    enum strm_type strmt = STRM_16K;
    enum clock_type ct = INTERNAL_OSCILLATOR;
    /*
     * The libaudioroute library doesn't set the mixer controls if previously
     * applied values are the same or the active_count > 0, so we need to
     * teardown the route so that it can clear up the value and active_count.
     * Then we could setup the routes again.
     */

    stdev->current_enable = 0;
    stdev->hotword_buffer_enable = 0;
    stdev->music_buffer_enable = 0;

    if (stdev->rx_active_count == 0 &&
        stdev->is_bargein_route_enabled == true) {
        /* rx stream is disabled during codec recovery.
         * Need to reset the enabled flag
         */
        stdev->is_bargein_route_enabled = false;
    } else if (stdev->rx_active_count > 0 &&
               stdev->is_bargein_route_enabled == false) {
        /* rx stream is enabled during codec recovery.
         * Need to raise the enabled flag
         */
        stdev->is_bargein_route_enabled = true;
    }

    if (stdev->is_buffer_package_loaded == true) {
        err = setup_buffer_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to restart Buffer package", __func__);
        }
    }

    if (stdev->is_src_package_loaded == true) {
        err = setup_src_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: Failed to restart SRC package", __func__);
        }
    }

    /*
     * If ST mode is IN_CALL, make sure mic route as false,
     * that would be reloaded after ending the call
     */
    if (get_sthal_mode(stdev) == IN_CALL) {
        ALOGD("%s: ST mode is in_call, reset all routes", __func__);

        stdev->is_mic_route_enabled = false;

        // if chre enabled before crash during call, need to setup package for SLPI.
        if (stdev->is_chre_loaded == true) {
            err = setup_chre_package(stdev->odsp_hdl);
            if (err != 0) {
                ALOGE("Failed to load CHRE package");
            }
            stdev->current_enable = stdev->current_enable | CHRE_MASK;
        }
        goto reload_oslo;
    }


    /*
     * Reset mic and src package if sound trigger recording is active
     * The src-mic, src-amp must be enable before AEC enable, because
     * the endpoint sequence control.
     *
     * The stream 0 should be enable at last moment for the data alignment.
     */
    if (stdev->is_mic_route_enabled == true) {
        // recover src package if sound trigger recording is active
        err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
        if (err != 0) {
            ALOGE("failed to load SRC package");
        }
        err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
        if (err != 0) {
            ALOGE("Failed to restart SRC-mic route");
        }
    }

    if (stdev->rx_active_count > 0 &&
        stdev->is_bargein_route_enabled == true) {
        ct = EXTERNAL_OSCILLATOR;
        if (is_mic_controlled_by_ahal(stdev) == true) {
            strmt = STRM_48K;
        }
        err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
        if (err != 0) {
            ALOGE("failed to load SRC package");
        }
        err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
        if (err != 0) {
            ALOGE("Failed to restart SRC-amp route");
        }

        err = setup_aec_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("Failed to restart AEC package");
        }
        err = enable_bargein_route(stdev->route_hdl, true);
        if (err != 0) {
            ALOGE("Failed to restart bargein route");
        }
        err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
        if (err != 0) {
            ALOGE("Failed to restart amp-ref route");
        }
    }

    if (stdev->is_mic_route_enabled == true) {
        if (is_mic_controlled_by_ahal(stdev) == false) {
            err = enable_mic_route(stdev->route_hdl, true, ct);
            if (err != 0) {
                ALOGE("failed to restart mic route");
            }
        }
    }

    // Download all the keyword models files that were previously loaded
    for (i = 0; i < MAX_MODELS; i++) {
        if (stdev->models[i].is_active == true) {
            if (stdev->is_buffer_package_loaded == true) {
                setup_buffer(stdev, &stdev->models[i], true);
            }
            if (check_uuid_equality(stdev->models[i].uuid, stdev->hotword_model_uuid) ||
                (check_uuid_equality(stdev->models[i].uuid, stdev->wakeup_model_uuid))) {
                if ((stdev->hotword_buffer_enable) &&
                    (!(stdev->current_enable & HOTWORD_MASK) ||
                      (stdev->current_enable & WAKEUP_MASK))) {
                    set_hotword_buffer_route(stdev->route_hdl,
                                            stdev->is_bargein_route_enabled);
                }
            }
            if (check_uuid_equality(stdev->models[i].uuid, stdev->ambient_model_uuid) ||
                (check_uuid_equality(stdev->models[i].uuid, stdev->entity_model_uuid))) {
                if ((stdev->music_buffer_enable) &&
                    (!(stdev->current_enable & AMBIENT_MASK) ||
                      (stdev->current_enable & ENTITY_MASK))) {
                    set_music_buffer_route(stdev->route_hdl,
                                        stdev->is_bargein_route_enabled);
                }
            }
            setup_package(stdev, &stdev->models[i]);
            set_package_route(stdev, stdev->models[i].uuid,
                            stdev->is_bargein_route_enabled);
        }
    }

reload_oslo:
    // reload Oslo part after every package loaded to avoid HMD memory overlap
    // issue, b/128914464
    for (i = 0; i < MAX_MODELS; i++) {
        if (stdev->models[i].is_loaded == true) {
            if (check_uuid_equality(stdev->models[i].uuid,
                                    stdev->sensor_model_uuid)) {
                // setup the sensor route
                err = setup_sensor_package(stdev->odsp_hdl);
                if (err != 0) {
                    ALOGE("%s: setup Sensor package failed", __func__);
                    goto exit;
                }

                err = set_sensor_route(stdev->route_hdl, true);
                if (err != 0) {
                    ALOGE("%s: Sensor route fail", __func__);
                    goto exit;
                }
                stdev->is_sensor_route_enabled = true;
            }
        }
    }
    ALOGD("%s: recovery done", __func__);
exit:
    return err;
}

// stdev needs to be locked before calling this function
static int crash_recovery(struct knowles_sound_trigger_device *stdev)
{
    int err = 0;

    set_default_apll_clk(stdev->mixer);
    setup_slpi_wakeup_event(stdev->odsp_hdl, true);

    // Redownload the keyword model files and start recognition
    err = restart_recognition(stdev);
    if (err != 0) {
        ALOGE("%s: ERROR: Failed to download the keyword models and restarting"
            " recognition", __func__);
        goto exit;
    }

    // Reset the flag only after successful recovery
    stdev->is_st_hal_ready = true;

exit:
    return err;
}

static void sensor_crash_handler(struct knowles_sound_trigger_device *stdev)
{
    int i;

    if (stdev->is_sensor_destroy_in_prog == false)
        return;

    if (stdev->ss_timer_created) {
        timer_delete(stdev->ss_timer);
        stdev->ss_timer_created = false;
    }

    if (stdev->is_sensor_route_enabled == true) {
        for (i = 0; i < MAX_MODELS; i++) {
            if (check_uuid_equality(stdev->models[i].uuid,
                                    stdev->sensor_model_uuid) &&
                stdev->models[i].is_loaded == true) {
                stdev->models[i].is_loaded = false;
                memset(&stdev->models[i].uuid, 0,
                       sizeof(sound_trigger_uuid_t));
                break;
            }
        }
        stdev->is_sensor_route_enabled = false;
        stdev->current_enable &= ~OSLO_MASK;
    }
    stdev->is_sensor_destroy_in_prog = false;

    // There could be another thread waiting for us to destroy
    // so signal that thread, if no one is waiting then this signal
    // will have no effect
    pthread_cond_signal(&stdev->sensor_create);
}

static void destroy_sensor_model(struct knowles_sound_trigger_device *stdev)
{
    int ret, i;
    ALOGD("+%s+", __func__);

    if (stdev->is_sensor_route_enabled == true) {
        ret = set_sensor_route(stdev->route_hdl, false);
        if (ret != 0) {
            ALOGE("%s: tear Sensor route fail", __func__);
        }
        stdev->is_sensor_route_enabled = false;

        ret = destroy_sensor_package(stdev->odsp_hdl);
        if (ret != 0) {
            ALOGE("%s: destroy Sensor package failed %d",
                  __func__, ret);
        }
        stdev->current_enable = stdev->current_enable & ~OSLO_MASK;
    }

    // now we can change the flag
    for (i = 0 ; i < MAX_MODELS ; i++) {
        if (check_uuid_equality(stdev->models[i].uuid,
                                stdev->sensor_model_uuid) &&
            stdev->models[i].is_loaded == true) {
            memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
            stdev->models[i].is_loaded = false;
            break;
        }
    }

    stdev->is_sensor_destroy_in_prog = false;
    check_and_destroy_buffer_package(stdev);

    // There could be another thread waiting for us to destroy so signal that
    // thread, if no one is waiting then this signal will have no effect
    pthread_cond_signal(&stdev->sensor_create);

    ALOGD("-%s-", __func__);
}

static void sensor_timeout_recover()
{
    int err = 0;
    ALOGD("+%s+", __func__);

    struct knowles_sound_trigger_device *stdev = &g_stdev;
    pthread_mutex_lock(&stdev->lock);
    // We are here because we timed out so check if we still need to destroy
    // the sensor package, if yes then reset the firmware
    if (stdev->is_sensor_destroy_in_prog == true) {
        if (stdev->is_st_hal_ready) {
            stdev->is_st_hal_ready = false;
            // reset the firmware and wait for firmware download complete
            err = reset_fw(stdev->odsp_hdl);
            if (err == -1) {
                ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
                      __func__, errno, strerror(errno));
            }
            reset_all_route(stdev->route_hdl);
            sensor_crash_handler(stdev);
        }
    }
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s-", __func__);
}

static int start_sensor_model(struct knowles_sound_trigger_device * stdev)
{
    struct timespec ts;
    int wait_counter = 0, err = 0;

    while (stdev->is_sensor_destroy_in_prog == true &&
           wait_counter < SENSOR_CREATE_WAIT_MAX_COUNT) {
        // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
        // within that time we don't get any response, we will go ahead with the
        // sensor model creation. Note this might result in an error which would
        // be better than blocking the thread indefinitely.
        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += SENSOR_CREATE_WAIT_TIME_IN_S;
        err = pthread_cond_timedwait(&stdev->sensor_create, &stdev->lock, &ts);
        if (err == ETIMEDOUT) {
            ALOGE("%s: WARNING: Sensor create timed out after %ds",
                  __func__, SENSOR_CREATE_WAIT_TIME_IN_S);
            wait_counter++;
        }
    }

    // If firmware crashed when we are waiting
    if (stdev->is_st_hal_ready == false) {
        err = -EAGAIN;
        goto exit;
    }

    if (stdev->is_sensor_destroy_in_prog == true) {
        ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
              "Host 1, and fw reset is not yet complete", __func__,
              SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT);
        err = -EAGAIN;
        goto exit;
    }

    // setup the sensor route
    err = check_and_setup_buffer_package(stdev);
    if (err != 0) {
        ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
        goto exit;
    }

    if(stdev->is_sensor_route_enabled == false) {
        err = setup_sensor_package(stdev->odsp_hdl);
        if (err) {
            ALOGE("%s: Failed to setup sensor package", __func__);
            goto exit;
        }
        // Don't download the keyword model file, just setup the
        // sensor route
        err = set_sensor_route(stdev->route_hdl, true);
        if (err) {
            ALOGE("%s: Sensor route fail", __func__);
            goto exit;
        }
        stdev->is_sensor_route_enabled = true;
        stdev->current_enable = stdev->current_enable | OSLO_MASK;
    }

exit:
    return err;
}

static void chre_crash_handler(struct knowles_sound_trigger_device *stdev)
{
    int i;

    if (stdev->is_chre_destroy_in_prog == false)
        return;

    if (stdev->chre_timer_created) {
        timer_delete(stdev->chre_timer);
        stdev->chre_timer_created = false;
    }

    if (stdev->is_chre_loaded == true) {
        for (i = 0; i < MAX_MODELS; i++) {
            if (check_uuid_equality(stdev->models[i].uuid,
                                    stdev->chre_model_uuid)) {
                stdev->models[i].is_active = false;
                stdev->models[i].is_loaded = false;
                memset(&stdev->models[i].uuid, 0,
                       sizeof(sound_trigger_uuid_t));
                break;
            }
        }
        stdev->is_chre_loaded = false;
        stdev->current_enable &= ~CHRE_MASK;
    }
    stdev->is_chre_destroy_in_prog = false;

    // There could be another thread waiting for us to destroy
    // so signal that thread, if no one is waiting then this signal
    // will have no effect
    pthread_cond_signal(&stdev->chre_create);
}

static int start_chre_model(struct knowles_sound_trigger_device *stdev,
                            int model_id)
{
    struct timespec ts;
    int wait_counter = 0, err = 0;

    while (stdev->is_chre_destroy_in_prog == true &&
           wait_counter < CHRE_CREATE_WAIT_MAX_COUNT) {
        // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
        // within that time we don't get any response, we will go ahead with the
        // sensor model creation. Note this might result in an error which would
        // be better than blocking the thread indefinitely.
        clock_gettime(CLOCK_REALTIME, &ts);
        ts.tv_sec += CHRE_CREATE_WAIT_TIME_IN_S;
        err = pthread_cond_timedwait(&stdev->chre_create, &stdev->lock, &ts);
        if (err == ETIMEDOUT) {
            ALOGE("%s: WARNING: CHRE create timed out after %ds",
                    __func__, CHRE_CREATE_WAIT_TIME_IN_S);
            wait_counter++;
        }
    }

    // If firmware crashed when we are waiting
    if (stdev->is_st_hal_ready == false) {
        err = -EAGAIN;
        goto exit;
    }

    if (stdev->is_chre_destroy_in_prog == true) {
        ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
              "Host 1, and fw reset is not yet complete", __func__,
              CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT);
        err = -EAGAIN;
        goto exit;
    }

    err = check_and_setup_buffer_package(stdev);
    if (err != 0) {
        ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
        goto exit;
    }

    // add chre to recover list
    if (can_enable_chre(stdev)) {
        if(stdev->is_chre_loaded == false) {
            stdev->models[model_id].is_active = true;
            handle_input_source(stdev, true);
            setup_chre_package(stdev->odsp_hdl);
            set_chre_audio_route(stdev->route_hdl,
                               stdev->is_bargein_route_enabled);
            stdev->is_chre_loaded = true;
            stdev->current_enable = stdev->current_enable | CHRE_MASK;
        }
    } else {
        ALOGW("%s: device is in call, setup CHRE for SLPI",
              __func__);
        //Setup CHRE package and allow SLPI connect
        //during in-call mode.
        if (stdev->is_chre_loaded == false) {
            setup_chre_package(stdev->odsp_hdl);
            stdev->models[model_id].uuid = stdev->chre_model_uuid;
            stdev->is_chre_loaded = true;
            stdev->current_enable = stdev->current_enable | CHRE_MASK;
            if (can_update_recover_list(stdev) == true)
                update_recover_list(stdev, model_id, true);
        }
    }

exit:
    return err;
}

static void destroy_chre_model(struct knowles_sound_trigger_device *stdev)
{
    int err = 0;
    ALOGD("+%s+", __func__);

    if (stdev->is_chre_loaded == true) {
        int i;
        tear_chre_audio_route(stdev->route_hdl,
                              stdev->is_bargein_route_enabled);
        err = destroy_chre_package(stdev->odsp_hdl);
        if (err != 0) {
            ALOGE("%s: ERROR: Failed to destroy chre package", __func__);
        }

        //Need force reset the flag for chre due to in-call state
        //The model is inactive, but need to clean if user disable it
        //during call.
        for (i = 0; i < MAX_MODELS; i++) {
            if (check_uuid_equality(stdev->models[i].uuid,
                                    stdev->chre_model_uuid)) {
                stdev->models[i].is_active = false;
                stdev->models[i].is_loaded = false;
                memset(&stdev->models[i].uuid, 0,
                       sizeof(sound_trigger_uuid_t));
                break;
            }
        }
        handle_input_source(stdev, false);
        stdev->is_chre_loaded = false;
        stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
    }

    stdev->is_chre_destroy_in_prog = false;

    // setup the sensor route
    err = check_and_destroy_buffer_package(stdev);
    if (err != 0) {
        ALOGE("%s: ERROR: Failed to destroy buffer package", __func__);
    }

    // There could be another thread waiting for us to destroy so signal that
    // thread, if no one is waiting then this signal will have no effect
    pthread_cond_signal(&stdev->chre_create);

    ALOGD("-%s-", __func__);
}

static void chre_timeout_recover()
{
    int err = 0;
    ALOGD("+%s+", __func__);

    struct knowles_sound_trigger_device *stdev = &g_stdev;
    pthread_mutex_lock(&stdev->lock);
    // We are here because we timed out so check if we still need to destroy
    // the chre package, if yes then reset the firmware
    if (stdev->is_chre_destroy_in_prog == true) {
        if (stdev->is_st_hal_ready) {
            stdev->is_st_hal_ready = false;
            // reset the firmware and wait for firmware download complete
            err = reset_fw(stdev->odsp_hdl);
            if (err == -1) {
                ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
                      __func__, errno, strerror(errno));
            }
            reset_all_route(stdev->route_hdl);
            chre_crash_handler(stdev);
        }
    }
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s-", __func__);
}

static void *transitions_thread_loop(void *context)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)context;

    int err = 0;
    pthread_mutex_lock(&stdev->lock);
    while (1) {
            if (stdev->transit_case == TRANSIT_NONE)
                pthread_cond_wait(&stdev->transition_cond, &stdev->lock);

            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
            switch (stdev->transit_case) {
                case TRANSIT_NONE:
                    break;
                case TRANSIT_SETUP_AEC:
                    err = async_setup_aec(stdev);
                    break;
            }
            stdev->transit_case = TRANSIT_NONE;
            release_wake_lock(WAKE_LOCK_NAME);
    }
    pthread_mutex_unlock(&stdev->lock);
}


static void *monitor_thread_loop(void *context)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)context;
    struct timespec now;
    double diff;

    pthread_mutex_lock(&stdev->lock);
    while (1) {
            if (!stdev->is_streaming)
                pthread_cond_wait(&stdev->tunnel_create, &stdev->lock);
            pthread_mutex_unlock(&stdev->lock);

            sleep(TUNNEL_TIMEOUT);

            pthread_mutex_lock(&stdev->lock);

            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
            clock_gettime(CLOCK_REALTIME, &now);
            for (int i = 0; i < MAX_MODELS; i++) {
                if (stdev->adnc_strm_handle[i] != 0) {
                    diff = (now.tv_sec - stdev->adnc_strm_last_read[i].tv_sec)
                        + (double) ((now.tv_nsec) - (stdev->adnc_strm_last_read[i].tv_nsec))
                          / 1000000000.0;

                    if (diff > TUNNEL_TIMEOUT) {
                        ALOGE("%s: Waiting timeout for %f sec", __func__, diff);
                        stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
                        stdev->adnc_strm_handle[i] = 0;
                        stdev->is_streaming--;
                        stdev->adnc_strm_last_read[i] = reset_time;
                    }
                }
            }
            release_wake_lock(WAKE_LOCK_NAME);
    }
    pthread_mutex_unlock(&stdev->lock);
}

static void *callback_thread_loop(void *context)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)context;
    struct pollfd fds[2];
    char msg[UEVENT_MSG_LEN];
    int exit_sockets[2];
    int err = 0;
    int i, n;
    int kwid = 0;
    struct iaxxx_get_event_info ge;
    void *payload = NULL;
    unsigned int payload_size = 0, fw_status = IAXXX_FW_IDLE;
    int fw_status_retries = 0;

    ALOGI("%s", __func__);
    prctl(PR_SET_NAME, (unsigned long)"sound trigger callback", 0, 0, 0);

    pthread_mutex_lock(&stdev->lock);

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
        ALOGE("%s: Failed to create termination socket", __func__);
        goto exit;
    }

    stdev_close_term_sock(stdev);
    stdev->send_sock = exit_sockets[0];
    stdev->recv_sock = exit_sockets[1];

    memset(fds, 0, 2 * sizeof(struct pollfd));
    int timeout = -1; // Wait for event indefinitely
    fds[0].events = POLLIN;
    fds[0].fd = uevent_open_socket(64*1024, true);
    if (fds[0].fd == -1) {
        ALOGE("Error opening socket for hotplug uevent errno %d(%s)",
            errno, strerror(errno));
        goto exit;
    }
    fds[1].events = POLLIN;
    fds[1].fd = stdev->recv_sock;

    ge.event_id = -1;

    // Try to get the firmware status, if we fail, try for 10 times with a gap
    // of 500ms, if we are unable to get the status after that then exit
    do {
        err = get_fw_status(stdev->odsp_hdl, &fw_status);
        if (err == -1) {
            ALOGE("%s: ERROR: Failed to get the firmware status %d(%s)",
                    __func__, errno, strerror(errno));
            usleep(RETRY_US);
            fw_status_retries++;
        }
    } while (err != 0 && fw_status_retries < RETRY_NUMBER);

    if (err != 0) {
        ALOGE("%s: ERROR: Failed to get firmware status after %d tries",
                __func__, RETRY_NUMBER);
        goto exit;
    }

    if (fw_status == IAXXX_FW_ACTIVE) {
        stdev->is_st_hal_ready = false;
        // reset the firmware and wait for firmware download complete
        err = reset_fw(stdev->odsp_hdl);
        if (err == -1) {
            ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
                    __func__, errno, strerror(errno));
        }
        stdev->fw_reset_done_by_hal = true;
    } else if (fw_status == IAXXX_FW_CRASH) {
        // Firmware has crashed wait till it recovers
        stdev->is_st_hal_ready = false;
    } else if (fw_status == IAXXX_FW_IDLE) {
        stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
                                            stdev->mixer_path_xml);
        if (stdev->route_hdl == NULL) {
            ALOGE("Failed to init the audio_route library");
            goto exit;
        }

        set_default_apll_clk(stdev->mixer);
        setup_slpi_wakeup_event(stdev->odsp_hdl, true);
        stdev->is_st_hal_ready = true;
    }
    pthread_mutex_unlock(&stdev->lock);

    while (1) {
        err = poll(fds, 2, timeout);

        pthread_mutex_lock(&stdev->lock);
        if (err < 0) {
            ALOGE("%s: Error in poll: %d (%s)",
                __func__, errno, strerror(errno));
            break;
        }

        if (fds[0].revents & POLLIN) {
            n = uevent_kernel_multicast_recv(fds[0].fd, msg, UEVENT_MSG_LEN);
            if (n <= 0) {
                pthread_mutex_unlock(&stdev->lock);
                continue;
            }
            for (i = 0; i < n;) {
                if (strstr(msg + i, IAXXX_VQ_EVENT_STR)) {
                    ALOGI("%s", IAXXX_VQ_EVENT_STR);

                    err = get_event(stdev->odsp_hdl, &ge);
                    if (err == 0) {
                        if (ge.event_id == OK_GOOGLE_KW_ID) {
                            ALOGD("Eventid received is OK_GOOGLE_KW_ID %d",
                                OK_GOOGLE_KW_ID);
                            kwid = OK_GOOGLE_KW_ID;
                        } else if (ge.event_id == AMBIENT_KW_ID) {
                            ALOGD("Eventid received is AMBIENT_KW_ID %d",
                                AMBIENT_KW_ID);
                            kwid = AMBIENT_KW_ID;
                            reset_ambient_plugin(stdev->odsp_hdl);
                        } else if (ge.event_id == OSLO_EP_DISCONNECT) {
                            ALOGD("Eventid received is OSLO_EP_DISCONNECT %d",
                                  OSLO_EP_DISCONNECT);
                            if (stdev->is_sensor_destroy_in_prog == true) {
                                // A timer would have been created during stop,
                                // check and delete it
                                if (stdev->ss_timer_created) {
                                    timer_delete(stdev->ss_timer);
                                    stdev->ss_timer_created = false;
                                }

                                destroy_sensor_model(stdev);
                            } else {
                                ALOGE("Unexpected OSLO_EP_DISCONNECT received"
                                      ", ignoring..");
                            }
                            break;
                        } else if (ge.event_id == CHRE_EP_DISCONNECT) {
                            ALOGD("Eventid received is CHRE_EP_DISCONNECT %d",
                                  CHRE_EP_DISCONNECT);
                            if (stdev->is_chre_destroy_in_prog == true) {
                                // A timer would have been created during stop,
                                // check and delete it
                                if (stdev->chre_timer_created) {
                                    timer_delete(stdev->chre_timer);
                                    stdev->chre_timer_created = false;
                                }

                                destroy_chre_model(stdev);
                            } else {
                                ALOGE("Unexpected CHRE_EP_DISCONNECT received"
                                      ", ignoring..");
                            }
                            break;
                        } else if (ge.event_id == ENTITY_KW_ID) {
                            ALOGD("Eventid received is ENTITY_KW_ID %d",
                                ENTITY_KW_ID);
                            kwid = ENTITY_KW_ID;
                        } else if (ge.event_id == WAKEUP_KW_ID) {
                            ALOGD("Eventid received is WAKEUP_KW_ID %d",
                                WAKEUP_KW_ID);
                            kwid = WAKEUP_KW_ID;
                        } else {
                            ALOGE("Unknown event id received, ignoring %d",
                                ge.event_id);
                        }
                        stdev->last_detected_model_type = kwid;
                        break;
                    } else {
                        ALOGE("get_event failed with error %d", err);
                    }
                } else if (strstr(msg + i, IAXXX_RECOVERY_EVENT_STR)) {
                    /* If the ST HAL did the firmware reset then that means
                     * that the userspace crashed so we need to reinit the audio
                     * route library, if we didn't reset the firmware, then it
                     * was genuine firmware crash and we don't need to reinit
                     * the audio route library.
                     */
                    if (stdev->fw_reset_done_by_hal == true) {
                        stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
                                                            stdev->mixer_path_xml);
                        if (stdev->route_hdl == NULL) {
                            ALOGE("Failed to init the audio_route library");
                            goto exit;
                        }

                        stdev->fw_reset_done_by_hal = false;
                    }

                    ALOGD("Firmware has redownloaded, start the recovery");
                    int err = crash_recovery(stdev);
                    if (err != 0) {
                        ALOGE("Crash recovery failed");
                    }
                } else if (strstr(msg + i, IAXXX_FW_DWNLD_SUCCESS_STR)) {
                    ALOGD("Firmware downloaded successfully");
                    stdev->is_st_hal_ready = true;
                    set_default_apll_clk(stdev->mixer);
                } else if (strstr(msg + i, IAXXX_FW_CRASH_EVENT_STR)) {
                    ALOGD("Firmware has crashed");
                    // Don't allow any op on ST HAL until recovery is complete
                    stdev->is_st_hal_ready = false;
                    reset_all_route(stdev->route_hdl);
                    stdev->is_streaming = 0;

                    // Firmware crashed, clear CHRE/Oslo timer and flags here
                    sensor_crash_handler(stdev);
                    chre_crash_handler(stdev);
                }

                i += strlen(msg + i) + 1;
            }

            if (ge.event_id == OK_GOOGLE_KW_ID ||
                ge.event_id == AMBIENT_KW_ID ||
                ge.event_id == ENTITY_KW_ID ||
                ge.event_id == WAKEUP_KW_ID) {
                ALOGD("%s: Keyword ID %d", __func__, kwid);

                if (ge.data != 0) {
                    ALOGD("Size of payload is %d", ge.data);
                    payload_size = ge.data;
                    payload = malloc(payload_size);
                    if (payload != NULL) {
                        if (ge.event_id == AMBIENT_KW_ID ||
                            ge.event_id == ENTITY_KW_ID)
                            err = get_entity_param_blk(stdev->odsp_hdl,
                                                    payload,
                                                    payload_size);
                        else if (ge.event_id == OK_GOOGLE_KW_ID ||
                            ge.event_id == WAKEUP_KW_ID)
                            err = get_wakeup_param_blk(stdev->odsp_hdl,
                                                    payload,
                                                    payload_size);
                        if (err != 0) {
                            ALOGE("Failed to get payload data");
                            free(payload);
                            payload = NULL;
                            payload_size = 0;
                        }
                    } else {
                        ALOGE("Failed to allocate memory for payload");
                    }
                }
                int idx = find_handle_for_kw_id(stdev, kwid);
                if (idx < MAX_MODELS && stdev->models[idx].is_active == true) {
                    int recognition_status = RECOGNITION_STATUS_SUCCESS;
                    if (stdev->models[idx].is_state_query == true) {
                        recognition_status =
                            RECOGNITION_STATUS_GET_STATE_RESPONSE;

                        // We need to send this only once, so reset now
                        stdev->models[idx].is_state_query = false;
                    }
                    if (stdev->models[idx].type == SOUND_MODEL_TYPE_KEYPHRASE) {
                        struct sound_trigger_phrase_recognition_event *event;
                        event = (struct sound_trigger_phrase_recognition_event*)
                                    stdev_keyphrase_event_alloc(
                                                stdev->models[idx].model_handle,
                                                stdev->models[idx].config,
                                                recognition_status);
                        if (event) {
                            struct model_info *model;
                            model = &stdev->models[idx];

                            ALOGD("Sending recognition callback for id %d",
                                kwid);
                            model->recognition_callback(&event->common,
                                                    model->recognition_cookie);
                            // Update the config so that it will be used
                            // during the streaming
                            stdev->last_keyword_detected_config = model->config;

                            free(event);
                        } else {
                            ALOGE("Failed to allocate memory for the event");
                        }
                    } else if (stdev->models[idx].type == SOUND_MODEL_TYPE_GENERIC) {
                        struct sound_trigger_generic_recognition_event *event;
                        event = (struct sound_trigger_generic_recognition_event*)
                                stdev_generic_event_alloc(
                                            stdev->models[idx].model_handle,
                                            payload,
                                            payload_size,
                                            recognition_status);
                        if (event) {
                            struct model_info *model;
                            model = &stdev->models[idx];

                            ALOGD("Sending recognition callback for id %d",
                                kwid);
                            model->recognition_callback(&event->common,
                                                    model->recognition_cookie);
                            // Update the config so that it will be used
                            // during the streaming
                            stdev->last_keyword_detected_config = model->config;

                            free(event);
                        } else {
                            ALOGE("Failed to allocate memory for the event");
                        }
                    }
                } else {
                    ALOGE("Invalid id or keyword is not active, Subsume the event");
                }
                // Reset all event related data
                ge.event_id = -1;
                ge.data = 0;
                kwid = -1;
            }
            // Free the payload data
            if (payload) {
                free(payload);
                payload = NULL;
                payload_size = 0;
            }
        } else if (fds[1].revents & POLLIN) {
            read(fds[1].fd, &n, sizeof(n)); /* clear the socket */
            ALOGD("%s: Termination message", __func__);
            break;
        }
        else {
            ALOGI("%s: Message ignored", __func__);
        }
        pthread_mutex_unlock(&stdev->lock);
    }

exit:
    stdev_close_term_sock(stdev);
    pthread_mutex_unlock(&stdev->lock);

    return (void *)(long)err;
}

static int stdev_get_properties(
                            const struct sound_trigger_hw_device *dev __unused,
                            struct sound_trigger_properties *properties)
{
    ALOGV("+%s+", __func__);
    if (properties == NULL)
        return -EINVAL;
    memcpy(properties, &hw_properties, sizeof(struct sound_trigger_properties));
    ALOGV("-%s-", __func__);
    return 0;
}

static int stop_recognition(struct knowles_sound_trigger_device *stdev,
                            sound_model_handle_t handle)
{
    int status = 0;
    struct model_info *model = &stdev->models[handle];

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        status = -EAGAIN;
        goto exit;
    }

    if (model->config != NULL) {
        dereg_hal_event_session(model->config, handle);
        free(model->config);
        model->config = NULL;
    }

    model->recognition_callback = NULL;
    model->recognition_cookie = NULL;
    if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
        check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
        // This avoids any processing of chre/oslo.
        goto exit;
    }
    if (can_update_recover_list(stdev) == true) {
        update_recover_list(stdev, handle, false);
        model->is_active = false;
        goto exit;
    }

    if (stdev->adnc_strm_handle[handle] != 0) {
        ALOGD("%s: stop tunnling for index:%d", __func__, handle);
        stdev->adnc_strm_close(stdev->adnc_strm_handle[handle]);
        stdev->adnc_strm_handle[handle] = 0;
        stdev->is_streaming--;
        stdev->adnc_strm_last_read[handle] = reset_time;
    }

    model->is_active = false;

    tear_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);

    destroy_package(stdev, model);


    if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
        (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
        if ((stdev->hotword_buffer_enable) &&
            !(stdev->current_enable & PLUGIN1_MASK)) {
            tear_hotword_buffer_route(stdev->route_hdl,
                                    stdev->is_bargein_route_enabled);
        }
    }

    if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
        (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
        if ((stdev->music_buffer_enable) &&
            !(stdev->current_enable & PLUGIN2_MASK)) {
            tear_music_buffer_route(stdev->route_hdl,
                                stdev->is_bargein_route_enabled);
        }
    }

    setup_buffer(stdev, model, false);

    handle_input_source(stdev, false);

    check_and_destroy_buffer_package(stdev);

exit:
    return status;
}

static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
                                struct sound_trigger_sound_model *sound_model,
                                sound_model_callback_t callback,
                                void *cookie,
                                sound_model_handle_t *handle)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)dev;
    int ret = 0;
    int kw_model_sz = 0;
    int i = 0;

    unsigned char *kw_buffer = NULL;

    ALOGD("+%s+", __func__);
    pthread_mutex_lock(&stdev->lock);

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        ret = -EAGAIN;
        goto exit;
    }

    if (handle == NULL || sound_model == NULL) {
        ALOGE("%s: handle/sound_model is NULL", __func__);
        ret = -EINVAL;
        goto exit;
    }

    if (sound_model->data_size == 0 ||
        sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
        ALOGE("%s: Invalid sound model data", __func__);
        ret = -EINVAL;
        goto exit;
    }

    // When a delayed CHRE/Oslo destroy process is in progress,
    // we should not skip the new model and return the existing handle
    // which will be destroyed soon.
    if ((check_uuid_equality(sound_model->vendor_uuid,
                             stdev->chre_model_uuid) &&
            stdev->is_chre_destroy_in_prog) ||
            (check_uuid_equality(sound_model->vendor_uuid,
                                 stdev->sensor_model_uuid) &&
            stdev->is_sensor_destroy_in_prog)) {
        ALOGD("%s: CHRE/Oslo destroy in progress, skipped handle check.",
              __func__);
    } else {
        i = find_handle_for_uuid(stdev, sound_model->vendor_uuid);
        if (i != -1) {
            ALOGW("%s: model is existed at index %d", __func__, i);
            *handle = i;
            goto exit;
        }
    }

    // Find an empty slot to load the model
    i = find_empty_model_slot(stdev);
    if (i == -1) {
        ALOGE("%s: Can't load model no free slots available", __func__);
        ret = -ENOSYS;
        goto exit;
    }

    kw_buffer = (unsigned char *) sound_model + sound_model->data_offset;
    kw_model_sz = sound_model->data_size;
    ALOGV("%s: kw_model_sz %d", __func__, kw_model_sz);

    stdev->models[i].data = malloc(kw_model_sz);
    if (stdev->models[i].data == NULL) {
        stdev->models[i].data_sz = 0;
        ALOGE("%s: could not allocate memory for keyword model data",
            __func__);
        ret = -ENOMEM;
        goto exit;
    } else {
        memcpy(stdev->models[i].data, kw_buffer, kw_model_sz);
        stdev->models[i].data_sz = kw_model_sz;
    }

    // Send the keyword model to the chip only for hotword and ambient audio
    if (check_uuid_equality(sound_model->vendor_uuid,
                            stdev->hotword_model_uuid)) {
        stdev->models[i].kw_id = OK_GOOGLE_KW_ID;
    } else if (check_uuid_equality(sound_model->vendor_uuid,
                                stdev->wakeup_model_uuid)) {
        stdev->models[i].kw_id = WAKEUP_KW_ID;
    } else if (check_uuid_equality(sound_model->vendor_uuid,
                                stdev->ambient_model_uuid)) {
        stdev->models[i].kw_id = AMBIENT_KW_ID;
    } else if (check_uuid_equality(sound_model->vendor_uuid,
                                stdev->entity_model_uuid)) {
        stdev->models[i].kw_id = ENTITY_KW_ID;
    } else if (check_uuid_equality(sound_model->vendor_uuid,
                                stdev->sensor_model_uuid)) {
        ret = start_sensor_model(stdev);
        if (ret) {
            ALOGE("%s: ERROR: Failed to start sensor model", __func__);
            goto error;
        }
        stdev->models[i].kw_id = USELESS_KW_ID;
    } else if (check_uuid_equality(sound_model->vendor_uuid,
                                stdev->chre_model_uuid)) {
        ret = start_chre_model(stdev, i);
        if (ret) {
            ALOGE("%s: ERROR: Failed to start chre model", __func__);
            goto error;
        }
        stdev->models[i].kw_id = USELESS_KW_ID;
    } else {
        ALOGE("%s: ERROR: unknown keyword model file", __func__);
        ret = -EINVAL;
        goto error;
    }

    *handle = i;
    ALOGV("%s: Loading keyword model handle(%d) type(%d)", __func__,
        *handle, sound_model->type);
    // This will need to be replaced with UUID once they are fixed
    stdev->models[i].model_handle = *handle;
    stdev->models[i].type = sound_model->type;
    stdev->models[i].uuid = sound_model->vendor_uuid;
    stdev->models[i].sound_model_callback = callback;
    stdev->models[i].sound_model_cookie = cookie;
    stdev->models[i].recognition_callback = NULL;
    stdev->models[i].recognition_cookie = NULL;

    stdev->models[i].is_loaded = true;

error:
    if (ret != 0) {
        if (stdev->models[i].data) {
            free(stdev->models[i].data);
            stdev->models[i].data = NULL;
            stdev->models[i].data_sz = 0;
        }
        if (!is_any_model_loaded(stdev) && stdev->is_buffer_package_loaded) {
            destroy_buffer_package(stdev->odsp_hdl);
            stdev->is_buffer_package_loaded = false;
        }
    }

exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s handle %d-", __func__, *handle);
    return ret;
}

static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
                                    sound_model_handle_t handle)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)dev;
    int ret = 0;
    ALOGD("+%s handle %d+", __func__, handle);
    pthread_mutex_lock(&stdev->lock);

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        ret = -EAGAIN;
        goto exit;
    }

    // Just confirm the model was previously loaded
    if (stdev->models[handle].is_loaded == false) {
        ALOGE("%s: Invalid model(%d) being called for unload",
                __func__, handle);
        ret = -EINVAL;
        goto exit;
    }

    if (stdev->models[handle].is_active == true) {
        ret = stop_recognition(stdev, handle);
        if (ret)
            goto exit;
    }

    if (check_uuid_equality(stdev->models[handle].uuid,
                                stdev->sensor_model_uuid)) {
        // Inform the Host 1 that sensor route/packages are about to be
        // torndown and then wait for confirmation from Host 1 that it can be
        // torndown. Also start a timer for 5 seconds, if the Host 1 doesn't
        // send us the event within 5 seconds we force remove the sensor pkgs
        if (stdev->is_sensor_route_enabled == true) {
            struct itimerspec ss_timer_spec;
            struct sigevent ss_sigevent;

            // Inform the host 1
            stdev->is_sensor_destroy_in_prog = true;
            trigger_sensor_destroy_event(stdev->odsp_hdl);

            // Start timer for 5 seconds
            ss_sigevent.sigev_notify = SIGEV_THREAD;
            ss_sigevent.sigev_notify_function = sensor_timeout_recover;
            ss_sigevent.sigev_notify_attributes = NULL;

            ss_timer_spec.it_interval.tv_sec = 0;
            ss_timer_spec.it_interval.tv_nsec = 0;
            ss_timer_spec.it_value.tv_sec =
                    SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT;
            ss_timer_spec.it_value.tv_nsec = 0;

            if (stdev->ss_timer_created) {
                timer_delete(stdev->ss_timer);
                stdev->ss_timer_created = false;
            }

            if (timer_create(CLOCK_REALTIME,
                             &ss_sigevent, &stdev->ss_timer) == -1) {
                ALOGE("%s: Timer Create Failed", __func__);
            } else {
                stdev->ss_timer_created = true;
                if (timer_settime(stdev->ss_timer,
                                  0, &ss_timer_spec, NULL) == -1) {
                    ALOGE("%s: Timer Set Failed", __func__);
                }
            }
        }
    } else if (check_uuid_equality(stdev->models[handle].uuid,
                                   stdev->chre_model_uuid)) {
        // remove chre from recover list
        if (can_update_recover_list(stdev) == true)
            update_recover_list(stdev, handle, false);

         // Disable the CHRE route
        if (stdev->is_chre_loaded == true) {
            struct itimerspec chre_timer_spec;
            struct sigevent chre_sigevent;

            // Inform the host 1
            stdev->is_chre_destroy_in_prog = true;
            trigger_chre_destroy_event(stdev->odsp_hdl);

            // Start timer for 5 seconds
            chre_sigevent.sigev_notify = SIGEV_THREAD;
            chre_sigevent.sigev_notify_function = chre_timeout_recover;
            chre_sigevent.sigev_notify_attributes = NULL;

            chre_timer_spec.it_interval.tv_sec = 0;
            chre_timer_spec.it_interval.tv_nsec = 0;
            chre_timer_spec.it_value.tv_sec =
                    CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT;
            chre_timer_spec.it_value.tv_nsec = 0;

            if (stdev->chre_timer_created) {
                timer_delete(stdev->chre_timer);
                stdev->chre_timer_created = false;
            }

            if (timer_create(CLOCK_REALTIME,
                             &chre_sigevent, &stdev->chre_timer) == -1) {
                ALOGE("%s: Timer Create Failed", __func__);
            } else {
                stdev->chre_timer_created = true;
                if (timer_settime(stdev->chre_timer,
                                  0, &chre_timer_spec, NULL) == -1) {
                    ALOGE("%s: Timer Set Failed", __func__);
                }
            }
        }
    }

    stdev->models[handle].sound_model_callback = NULL;
    stdev->models[handle].sound_model_cookie = NULL;

    if (!(check_uuid_equality(stdev->models[handle].uuid,
                              stdev->sensor_model_uuid) &&
            stdev->is_sensor_destroy_in_prog) &&
        !(check_uuid_equality(stdev->models[handle].uuid,
                              stdev->chre_model_uuid) &&
            stdev->is_chre_destroy_in_prog)) {
        memset(&stdev->models[handle].uuid, 0, sizeof(sound_trigger_uuid_t));
        stdev->models[handle].is_loaded = false;
    }

    if (stdev->models[handle].data) {
        free(stdev->models[handle].data);
        stdev->models[handle].data = NULL;
        stdev->models[handle].data_sz = 0;
    }

    ALOGD("%s: Successfully unloaded the model, handle - %d",
        __func__, handle);
exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s handle %d-", __func__, handle);
    return ret;
}

static int stdev_start_recognition(
                        const struct sound_trigger_hw_device *dev,
                        sound_model_handle_t handle,
                        const struct sound_trigger_recognition_config *config,
                        recognition_callback_t callback,
                        void *cookie)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)dev;
    int status = 0;
    struct model_info *model = &stdev->models[handle];

    ALOGD("%s stdev %p, sound model %d", __func__, stdev, handle);

    pthread_mutex_lock(&stdev->lock);

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        status = -EAGAIN;
        goto exit;
    }

    if (callback == NULL) {
        ALOGE("%s: recognition_callback is null", __func__);
        status = -EINVAL;
        goto exit;
    }

    if (model->config != NULL) {
        dereg_hal_event_session(model->config, handle);
        free(model->config);
        model->config = NULL;
    }

    if (config != NULL) {
        model->config = (struct sound_trigger_recognition_config *)
                            malloc(sizeof(*config));
        if (model->config == NULL) {
            ALOGE("%s: Failed to allocate memory for model config", __func__);
            status = -ENOMEM;
            goto exit;
        }

        memcpy(model->config, config, sizeof(*config));
        reg_hal_event_session(model->config, handle);

        ALOGD("%s: Is capture requested %d",
            __func__, config->capture_requested);
    } else {
        ALOGD("%s: config is null", __func__);
        model->config = NULL;
    }

    model->recognition_callback = callback;
    model->recognition_cookie = cookie;
    if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
        check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
        // This avoids any processing of chre/oslo.
        goto exit;
    }
    if (model->is_active == true) {
        // This model is already active, do nothing except updating callbacks,
        // configs and cookie
        goto exit;
    }
    if (can_update_recover_list(stdev) == true) {
        // Device is in voice/VoIP call, add model to recover list first
        // recover model once voice/VoIP is ended.
        update_recover_list(stdev, handle, true);
        goto exit;
    }

    status = check_and_setup_buffer_package(stdev);
    if (status != 0) {
        ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
        goto exit;
    }

    model->is_active = true;

    handle_input_source(stdev, true);

    if (stdev->is_buffer_package_loaded == true) {
        setup_buffer(stdev, model, true);
    }

    if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
        (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
        if ((stdev->hotword_buffer_enable) &&
            (!(stdev->current_enable & HOTWORD_MASK) ||
              (stdev->current_enable & WAKEUP_MASK))) {
            set_hotword_buffer_route(stdev->route_hdl,
                                    stdev->is_bargein_route_enabled);
        }
    }

    if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
        (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
        if ((stdev->music_buffer_enable) &&
            (!(stdev->current_enable & AMBIENT_MASK) ||
              (stdev->current_enable & ENTITY_MASK))) {
            set_music_buffer_route(stdev->route_hdl,
                                stdev->is_bargein_route_enabled);
        }
    }

    setup_package(stdev, model);

    set_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);

exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s sound model %d-", __func__, handle);
    return status;
}

static int stdev_stop_recognition(
                        const struct sound_trigger_hw_device *dev,
                        sound_model_handle_t handle)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)dev;
    int status = 0;
    pthread_mutex_lock(&stdev->lock);
    ALOGD("+%s sound model %d+", __func__, handle);

    status = stop_recognition(stdev, handle);

    if (status != 0)
        goto exit;

    ALOGD("-%s sound model %d-", __func__, handle);
exit:
    pthread_mutex_unlock(&stdev->lock);

    return status;
}

/**
 * Get the state of a given model.
 * The model state is returned asynchronously as a RecognitionEvent via
 * the callback that was registered in StartRecognition().
 * @param modelHandle The handle of the sound model whose state is being
 *                    queried.
 * @return retval Operation completion status: 0 in case of success,
 *                -ENOSYS in case of invalid model handle,
 *                -ENOMEM in case of memory allocation failure,
 *                -ENODEV in case of initialization error,
 *                -EINVAL in case where a recognition event is already
 *                        being processed.
 */
static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
                               sound_model_handle_t sound_model_handle) {
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)dev;
    struct model_info *model = &stdev->models[sound_model_handle];
    int ret = 0;
    ALOGD("+%s+", __func__);
    pthread_mutex_lock(&stdev->lock);

    if (!stdev->opened) {
        ALOGE("%s: stdev isn't initialized", __func__);
        ret = -ENODEV;
        goto exit;
    }

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        ret = -ENODEV;
        goto exit;
    }

    if (model->is_active == false) {
        ALOGE("%s: ERROR: %d model is not active",
            __func__, sound_model_handle);
        ret = -ENOSYS;
        goto exit;
    }

    if (model->is_state_query == true) {
        ALOGE("%s: ERROR: model %d is already processing",
            __func__, sound_model_handle);
        ret = -EINVAL;
        goto exit;
    }

    model->is_state_query = true;

    if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
        ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
                            HOTWORD_SLOT_ID);
    else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))
        ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
                            WAKEUP_SLOT_ID);
    else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
        ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
                            AMBIENT_SLOT_ID);
    else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
        ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
                            ENTITY_SLOT_ID);
    } else {
        ALOGE("%s: ERROR: %d model is not supported",
            __func__, sound_model_handle);
        ret = -ENOSYS;
    }

    if (ret != 0) {
        model->is_state_query = false;
        ALOGE("%s: ERROR: Failed to get the model state", __func__);
    }

exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s-", __func__);
    return ret;
}

static int stdev_close(hw_device_t *device)
{
    struct knowles_sound_trigger_device *stdev =
        (struct knowles_sound_trigger_device *)device;
    int ret = 0;
    ALOGD("+%s+", __func__);
    pthread_mutex_lock(&stdev->lock);

    if (!stdev->opened) {
        ALOGE("%s: device already closed", __func__);
        ret = -EFAULT;
        goto exit;
    }

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        ret = -EAGAIN;
        goto exit;
    }

    setup_slpi_wakeup_event(stdev->odsp_hdl, false);

    stdev->opened = false;

    if (stdev->send_sock >= 0)
        write(stdev->send_sock, "T", 1);
    pthread_join(stdev->callback_thread, (void **)NULL);

    if (stdev->route_hdl)
        audio_route_free(stdev->route_hdl);
    if (stdev->odsp_hdl)
        iaxxx_odsp_deinit(stdev->odsp_hdl);

    if (stdev->ss_timer_created) {
        timer_delete(stdev->ss_timer);
        stdev->ss_timer_created = false;
    }

exit:
    pthread_mutex_unlock(&stdev->lock);
    ALOGD("-%s-", __func__);
    return ret;
}

__attribute__ ((visibility ("default")))
audio_io_handle_t stdev_get_audio_handle()
{
    if (g_stdev.last_keyword_detected_config == NULL) {
        ALOGI("%s: Config is NULL so returning audio handle as 0", __func__);
        return 0;
    }

    ALOGI("%s: Audio Handle is %d",
        __func__, g_stdev.last_keyword_detected_config->capture_handle);

    return g_stdev.last_keyword_detected_config->capture_handle;
}

static int open_streaming_lib(struct knowles_sound_trigger_device *stdev) {
    int ret = 0;

    if (access(ADNC_STRM_LIBRARY_PATH, R_OK) == 0) {
        stdev->adnc_cvq_strm_lib = dlopen(ADNC_STRM_LIBRARY_PATH, RTLD_NOW);
        if (stdev->adnc_cvq_strm_lib == NULL) {
            char const *err_str = dlerror();
            ALOGE("%s: module = %s error = %s", __func__,
                ADNC_STRM_LIBRARY_PATH, err_str ? err_str : "unknown");
            ALOGE("%s: DLOPEN failed for %s", __func__, ADNC_STRM_LIBRARY_PATH);
        } else {
            ALOGV("%s: DLOPEN successful for %s",
                __func__, ADNC_STRM_LIBRARY_PATH);
            for (int index = 0; index < MAX_MODELS; index++) {
                stdev->adnc_strm_handle[index] = 0;
                stdev->adnc_strm_last_read[index] = reset_time;
            }
            stdev->adnc_strm_open =
                (int (*)(bool, int, int))dlsym(stdev->adnc_cvq_strm_lib,
                "adnc_strm_open");
            stdev->adnc_strm_read =
               (size_t (*)(long, void *, size_t))dlsym(stdev->adnc_cvq_strm_lib,
                "adnc_strm_read");
            stdev->adnc_strm_close =
                (int (*)(long))dlsym(stdev->adnc_cvq_strm_lib,
                "adnc_strm_close");
            if (!stdev->adnc_strm_open || !stdev->adnc_strm_read ||
                !stdev->adnc_strm_close) {
                ALOGE("%s: Error grabbing functions in %s", __func__,
                    ADNC_STRM_LIBRARY_PATH);
                stdev->adnc_strm_open = 0;
                stdev->adnc_strm_read = 0;
                stdev->adnc_strm_close = 0;
            }
        }
    }

    return ret;
}

static struct mixer* find_stdev_mixer_path(int card_num, char *mixer_path_xml)
{
    struct mixer *mixer = NULL;
    const char *in_snd_card_name;
    char *snd_card_name = NULL;
    char *tmp = NULL;
    char *platform = NULL;
    char *snd_card = NULL;
    char *device = NULL;

    mixer = mixer_open(card_num);

    if (!mixer) {
        ALOGE("%s: Unable to open the mixer: %d", __func__,
            card_num);
        return NULL;
    }

    in_snd_card_name = mixer_get_name(mixer);
    snd_card_name = strdup(in_snd_card_name);

    if (snd_card_name == NULL) {
        ALOGE("%s: snd_card_name is NULL", __func__);
        goto on_error;
    }

    platform = strtok_r(snd_card_name, "-", &tmp);
    if (platform == NULL) {
        ALOGE("%s: snd card is invalid", __func__);
        goto on_error;
    }

    snd_card = strtok_r(NULL, "-", &tmp);
    if (snd_card == NULL) {
        ALOGE("%s: snd card is invalid", __func__);
        goto on_error;
    }

    device = strtok_r(NULL, "-", &tmp);
    if (device != NULL) {
        snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s_%s.xml",
                SOUND_TRIGGER_MIXER_PATH_BASE, device);
    } else {
        ALOGE("%s: Unknown device, try to use default xml", __func__);
        snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s",
                SOUND_TRIGGER_MIXER_PATH_XML);
    }

    ALOGD("%s: using %s", __func__, mixer_path_xml);

on_error:
    if (snd_card_name)
        free(snd_card_name);
    return mixer;
}

static int find_sound_card() {
    int retry_num = 0, snd_card_num = 0, ret = -1;
    const char *snd_card_name;
    struct mixer *mixer = NULL;
    bool card_verifed[MAX_SND_CARD] = {false};
    const int retry_limit = property_get_int32("audio.snd_card.open.retries",
                                            RETRY_NUMBER);
    ALOGD("+%s+", __func__);

    for (;;) {
        if (snd_card_num >= MAX_SND_CARD) {
            if (retry_num++ >= retry_limit) {
                ALOGE("%s: iaxxx sound card not found", __func__);
                goto exit;
            }
            snd_card_num = 0;
            usleep(RETRY_US);
            continue;
        }
        if (card_verifed[snd_card_num]) {
            snd_card_num++;
            continue;
        }

        mixer = mixer_open(snd_card_num);
        if (!mixer) {
            snd_card_num++;
            continue;
        }

        snd_card_name = mixer_get_name(mixer);
        if (strstr(snd_card_name, CARD_NAME)) {
            ALOGD("%s: find card %d has iaxxx - %s",
                __func__, snd_card_num, snd_card_name);
            ret = snd_card_num;
            break;
        }

        ALOGD("%s: sound card %s does NOT have iaxxx", __func__, snd_card_name);
        mixer_close(mixer);
        mixer = NULL;
        card_verifed[snd_card_num] = true;
        snd_card_num++;
    }

exit:
    if (mixer)
        mixer_close(mixer);

    ALOGD("-%s-", __func__);
    return ret;
}

static int load_audio_hal()
{
    char audio_hal_lib[100];
    void *sthal_prop_api_version = NULL;
    struct knowles_sound_trigger_device *stdev = &g_stdev;
    int ret = 0;

    snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
            AUDIO_HAL_LIBRARY_PATH, AUDIO_HAL_NAME_PREFIX,
            SOUND_TRIGGER_PLATFORM);
    if (access(audio_hal_lib, R_OK)) {
        ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
        return -ENOENT;
    }

    stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
    if (stdev->audio_hal_handle == NULL) {
        ALOGE("%s: ERROR. %s", __func__, dlerror());
        return -ENODEV;
    }

    stdev->audio_hal_cb = dlsym(stdev->audio_hal_handle, "audio_hw_call_back");
    if (stdev->audio_hal_cb == NULL) {
        ALOGE("%s: ERROR. %s", __func__, dlerror());
        ret = -ENODEV;
        goto error;
    }

    sthal_prop_api_version = dlsym(stdev->audio_hal_handle,
                                "sthal_prop_api_version");
    if (sthal_prop_api_version == NULL) {
        stdev->sthal_prop_api_version = 0;
        ret = 0; /* passthru for backward compability */
    } else {
        stdev->sthal_prop_api_version = *(int *)sthal_prop_api_version;
        if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
            MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
            ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
                __func__, STHAL_PROP_API_CURRENT_VERSION,
                stdev->sthal_prop_api_version);
            goto error;
        }
        ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
            stdev->sthal_prop_api_version);
    }

    ALOGD("%s: load AHAL successfully.", __func__);
    return ret;

error:
    dlclose(stdev->audio_hal_handle);
    stdev->audio_hal_handle = NULL;
    return ret;
}

static int stdev_open(const hw_module_t *module, const char *name,
        hw_device_t **device)
{
    struct knowles_sound_trigger_device *stdev;
    int ret = 0, i = 0;
    int snd_card_num = 0;

    ALOGE("!! Knowles SoundTrigger v1!!");

    if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
        return -EINVAL;

    if (device == NULL)
        return -EINVAL;

    stdev = &g_stdev;
    pthread_mutex_lock(&stdev->lock);

    snd_card_num = find_sound_card();
    if (snd_card_num == -1) {
        ALOGE("%s: Unable to find the sound card %s", __func__, CARD_NAME);
        ret = -EAGAIN;
        goto exit;
    }

    if (stdev->opened) {
        ALOGE("%s: Only one sountrigger can be opened at a time", __func__);
        ret = -EBUSY;
        goto exit;
    }

    ret = open_streaming_lib(stdev);
    if (ret != 0) {
        ALOGE("%s: Couldnot open the streaming library", __func__);
        goto error;
    }

    ret = load_audio_hal();
    if (ret != 0) {
        ALOGE("%s: Couldn't load AHAL", __func__);
        goto error;
    }

    stdev->device.common.tag = HARDWARE_DEVICE_TAG;
    stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_2;
    stdev->device.common.module = (struct hw_module_t *)module;
    stdev->device.common.close = stdev_close;
    stdev->device.get_properties = stdev_get_properties;
    stdev->device.load_sound_model = stdev_load_sound_model;
    stdev->device.unload_sound_model = stdev_unload_sound_model;
    stdev->device.start_recognition = stdev_start_recognition;
    stdev->device.stop_recognition = stdev_stop_recognition;
    stdev->device.get_model_state = stdev_get_model_state;

    stdev->opened = true;
    /* Initialize all member variable */
    for (i = 0; i < MAX_MODELS; i++) {
        stdev->models[i].type = SOUND_MODEL_TYPE_UNKNOWN;
        memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
        stdev->models[i].config = NULL;
        stdev->models[i].data = NULL;
        stdev->models[i].data_sz = 0;
        stdev->models[i].is_loaded = false;
        stdev->models[i].is_active = false;
        stdev->last_keyword_detected_config = NULL;
        stdev->models[i].is_state_query = false;
    }

    stdev->is_mic_route_enabled = false;
    stdev->is_con_mic_route_enabled = false;
    stdev->is_ahal_in_voice_voip_mode = false;
    stdev->is_ahal_voice_voip_stop = false;
    stdev->is_ahal_voice_voip_start = false;
    stdev->is_bargein_route_enabled = false;
    stdev->is_chre_loaded = false;
    stdev->is_buffer_package_loaded = false;
    stdev->hotword_buffer_enable = 0;
    stdev->music_buffer_enable = 0;
    stdev->current_enable = 0;
    stdev->is_sensor_route_enabled = false;
    stdev->recover_model_list = 0;
    stdev->rx_active_count = 0;
    stdev->is_ahal_media_recording = false;
    stdev->is_concurrent_capture = hw_properties.concurrent_capture;

    stdev->is_sensor_destroy_in_prog = false;
    stdev->ss_timer_created = false;

    stdev->is_chre_destroy_in_prog = false;
    stdev->chre_timer_created = false;

    stdev->snd_crd_num = snd_card_num;
    stdev->fw_reset_done_by_hal = false;

    str_to_uuid(HOTWORD_AUDIO_MODEL, &stdev->hotword_model_uuid);
    str_to_uuid(WAKEUP_MODEL, &stdev->wakeup_model_uuid);
    str_to_uuid(SENSOR_MANAGER_MODEL, &stdev->sensor_model_uuid);
    str_to_uuid(AMBIENT_AUDIO_MODEL, &stdev->ambient_model_uuid);
    str_to_uuid(CHRE_AUDIO_MODEL, &stdev->chre_model_uuid);
    str_to_uuid(ENTITY_AUDIO_MODEL, &stdev->entity_model_uuid);

    stdev->odsp_hdl = iaxxx_odsp_init();
    if (stdev->odsp_hdl == NULL) {
        ALOGE("%s: Failed to get handle to ODSP HAL", __func__);
        ret = -EIO;
        goto error;
    }
    stdev->mixer = find_stdev_mixer_path(stdev->snd_crd_num, stdev->mixer_path_xml);
    if (stdev->mixer == NULL) {
        ALOGE("Failed to init the mixer");
        ret = -EAGAIN;
        goto error;
    }

    ALOGD("stdev before pthread_create %p", stdev);
    // Create a thread to handle all events from kernel
    pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
                callback_thread_loop, stdev);

    pthread_create(&stdev->monitor_thread, (const pthread_attr_t *) NULL,
                monitor_thread_loop, stdev);

    pthread_create(&stdev->transitions_thread, (const pthread_attr_t *) NULL,
                transitions_thread_loop, stdev);

    *device = &stdev->device.common; /* same address as stdev */
exit:
    pthread_mutex_unlock(&stdev->lock);
    return ret;

error:
    if (stdev->adnc_cvq_strm_lib)
        dlclose(stdev->adnc_cvq_strm_lib);
    if (stdev->audio_hal_handle)
        dlclose(stdev->audio_hal_handle);
    if (stdev->route_hdl)
        audio_route_free(stdev->route_hdl);
    if (stdev->odsp_hdl)
        iaxxx_odsp_deinit(stdev->odsp_hdl);
    if (stdev->mixer)
        mixer_close(stdev->mixer);

    pthread_mutex_unlock(&stdev->lock);
    return ret;
}

/* AHAL calls this callback to communicate with STHAL */
int sound_trigger_hw_call_back(audio_event_type_t event,
                            struct audio_event_info *config)
{
    int ret = 0;
    int i = 0;
    int index = -1;
    struct knowles_sound_trigger_device *stdev = &g_stdev;
    enum sthal_mode pre_mode, cur_mode;

    if (!stdev)
        return -ENODEV;

    if (!stdev->opened) {
        ALOGE("%s: Error SoundTrigger has not been opened", __func__);
        return -EINVAL;
    }

    pthread_mutex_lock(&stdev->lock);

    // update conditions for mic concurrency whatever firmware status may be.
    if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
        event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
        event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
        event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
        pre_mode = get_sthal_mode(stdev);
        update_sthal_conditions(stdev, event, config);
        cur_mode = get_sthal_mode(stdev);
    }

    // update conditions for bargein whatever firmware status may be.
    if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
        event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
        update_rx_conditions(stdev, event, config);
    }

    if (stdev->is_st_hal_ready == false) {
        ALOGE("%s: ST HAL is not ready yet", __func__);
        ret = -EINVAL;
        goto exit;
    }

    switch (event) {
    case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
    case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
        ALOGD("%s: handle capture device event %d", __func__, event);

        //handle capture device on/off event
        do_handle_functions(stdev, pre_mode, cur_mode, event);

        break;
    case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
    case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
        ALOGD("%s: handle capture stream event %d, usecase %d",
              __func__, event, config->u.usecase.type);

        break;
    case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
        ALOGD("%s: handle playback stream inactive", __func__);

        if (stdev->rx_active_count == 0) {
            if (stdev->is_mic_route_enabled != false) {
                // Atleast one keyword model is active so update the routes
                // Check if the bargein route is enabled if not enable bargein route
                // Check each model, if it is active then update it's route
                if (stdev->is_bargein_route_enabled != false) {
                    ALOGD("Bargein disabling");
                    stdev->is_bargein_route_enabled = false;
                    // Check each model, if it is active then update it's route
                    // Disable the bargein route
                    for (i = 0; i < MAX_MODELS; i++) {
                        if (stdev->models[i].is_active == true) {
                            // teardown the package route with bargein
                            ret = tear_package_route(stdev,
                                                    stdev->models[i].uuid,
                                                    !stdev->is_bargein_route_enabled);
                            if (ret != 0) {
                                ALOGE("Failed to tear old package route");
                                goto exit;
                            }
                            // resetup the package route with out bargein
                            ret = set_package_route(stdev,
                                                    stdev->models[i].uuid,
                                                    stdev->is_bargein_route_enabled);
                            if (ret != 0) {
                                ALOGE("Failed to enable package route");
                                goto exit;
                            }
                        }
                    }

                    //Switch buffer input source
                    if (stdev->hotword_buffer_enable) {
                        ret = tear_hotword_buffer_route(stdev->route_hdl,
                                            !stdev->is_bargein_route_enabled);
                        if (ret != 0) {
                            ALOGE("Failed to tear old buffer route");
                            goto exit;
                        }
                        ret = set_hotword_buffer_route(stdev->route_hdl,
                                            stdev->is_bargein_route_enabled);
                        if (ret != 0) {
                            ALOGE("Failed to enable buffer route");
                            goto exit;
                        }
                    }

                    if (stdev->music_buffer_enable) {
                        ret = tear_music_buffer_route(stdev->route_hdl,
                                            !stdev->is_bargein_route_enabled);
                        if (ret != 0) {
                            ALOGE("Failed to tear old music buffer route");
                            goto exit;
                        }
                        ret = set_music_buffer_route(stdev->route_hdl,
                                            stdev->is_bargein_route_enabled);
                        if (ret != 0) {
                            ALOGE("Failed to enable buffer route");
                            goto exit;
                        }
                    }

                    ret = enable_bargein_route(stdev->route_hdl, false);
                    if (ret != 0) {
                        ALOGE("Failed to enable buffer route");
                        goto exit;
                    }

                    ret = destroy_aec_package(stdev->odsp_hdl);
                    if (ret != 0) {
                        ALOGE("Failed to unload AEC package");
                        goto exit;
                    }

                    ret = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
                    if (ret != 0) {
                        ALOGE("Failed to disable SRC-amp route");
                        goto exit;
                    }

                    ret = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
                    if (ret != 0) {
                        ALOGE("Failed to unload SRC-amp package");
                        goto exit;
                    }

                    if (is_mic_controlled_by_ahal(stdev) == false) {
                        ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
                        if (ret != 0) {
                            ALOGE("Failed to disable amp-ref route");
                            goto exit;
                        }
                        ret = enable_mic_route(stdev->route_hdl, false,
                                            EXTERNAL_OSCILLATOR);
                        if (ret != 0) {
                            ALOGE("Failed to disable mic route with INT OSC");
                            goto exit;
                        }
                        ret = enable_mic_route(stdev->route_hdl, true,
                                            INTERNAL_OSCILLATOR);
                        if (ret != 0) {
                            ALOGE("Failed to enable mic route with EXT OSC");
                            goto exit;
                        }
                    } else {
                        // main mic is turned by media record, close it by 48khz
                        ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
                        if (ret != 0) {
                            ALOGE("Failed to disable amp-ref route");
                            goto exit;
                        }
                    }
                } else {
                    ALOGW("%s: barge-in isn't enabled", __func__);
                }
            }
        } else {
            ALOGD("%s: rx stream is still active", __func__);
        }
        break;
    case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
        ALOGD("%s: handle playback stream active", __func__);

        if (stdev->rx_active_count > 0) {
            if (stdev->is_mic_route_enabled != false) {
                // Atleast one keyword model is active so update the routes
                // Check if the bargein route is enabled if not enable bargein route
                // Check each model, if it is active then update it's route
                stdev->transit_case = TRANSIT_SETUP_AEC;
                pthread_cond_signal(&stdev->transition_cond);
            }
        } else {
            ALOGW("%s: unexpeted stream active event", __func__);
        }
        break;
    case AUDIO_EVENT_STOP_LAB:
        /* Close Stream Driver */
        for (i = 0; i < MAX_MODELS; i++) {
            if (stdev->models[i].is_active &&
                stdev->models[i].config &&
                (stdev->models[i].config->capture_handle ==
                 config->u.ses_info.capture_handle)) {
                index = i;
                break;
            }
        }

        /*
         * Close unused adnc if ...
         * 1. No capture handle is found
         * 2. Model is inactive
         * 3. adnc stream handle is existed
         */
        if (index == -1 && stdev->is_streaming > 0) {
            ALOGD("%s: close unused adnc handle, cap_handle:%d", __func__,
                  config->u.ses_info.capture_handle);
            for (i = 0; i < MAX_MODELS; i++) {
                if (stdev->adnc_strm_handle[i] != 0 &&
                    !stdev->models[i].is_active) {
                    stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
                    stdev->adnc_strm_handle[i] = 0;
                    stdev->is_streaming--;
                    stdev->adnc_strm_last_read[i] = reset_time;
                }
            }
            goto exit;
        }

        ALOGD("%s: close streaming %d, cap_handle:%d, index:%d",
              __func__, event, config->u.ses_info.capture_handle, index);
        if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
            stdev->adnc_strm_close(stdev->adnc_strm_handle[index]);
            stdev->adnc_strm_handle[index] = 0;
            stdev->is_streaming--;
            stdev->adnc_strm_last_read[index] = reset_time;
        }

        break;

    case AUDIO_EVENT_SSR:
        /*[TODO] Do we need to handle adsp SSR event ? */
        ALOGD("%s: handle audio subsystem restart %d", __func__, event);
        break;

    case AUDIO_EVENT_READ_SAMPLES:
        /* It is possible to change session info, check config */
        if (config->u.aud_info.ses_info == NULL) {
            ALOGE("%s: Invalid config, event:%d", __func__, event);
            ret = -EINVAL;
            goto exit;
        }

        for (i = 0; i < MAX_MODELS; i++) {
            if (stdev->models[i].is_active &&
                stdev->models[i].config &&
                (stdev->models[i].config->capture_handle ==
                 config->u.aud_info.ses_info->capture_handle)) {
                index = i;
                break;
            }
        }

        /* Open Stream Driver */
        if (index != -1 && stdev->adnc_strm_handle[index] == 0) {
            if (stdev->adnc_strm_open == NULL) {
                ALOGE("%s: Error adnc streaming not supported", __func__);
            } else {
                bool keyword_stripping_enabled = false;
                int stream_end_point;
                switch (stdev->last_detected_model_type) {
                    case OK_GOOGLE_KW_ID:
                        stream_end_point = CVQ_ENDPOINT;
                        break;
                    case AMBIENT_KW_ID:
                    case ENTITY_KW_ID:
                        stream_end_point = MUSIC_BUF_ENDPOINT;
                        break;
                    default:
                        stream_end_point = CVQ_ENDPOINT;
                        break;
                };
                stdev->adnc_strm_handle[index] = stdev->adnc_strm_open(
                                            keyword_stripping_enabled, 0,
                                            stream_end_point);
                if (stdev->adnc_strm_handle[index]) {
                    ALOGD("Successfully opened adnc strm! index %d handle %d",
                          index, config->u.aud_info.ses_info->capture_handle);
                    stdev->is_streaming++;

                    clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
                    if (stdev->is_streaming == 1)
                        pthread_cond_signal(&stdev->tunnel_create);
                } else {
                    ALOGE("%s: DSP is currently not streaming", __func__);
                }
            }
        }

        if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
            //ALOGD("%s: soundtrigger HAL adnc_strm_read", __func__);
            clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
            pthread_mutex_unlock(&stdev->lock);
            stdev->adnc_strm_read(stdev->adnc_strm_handle[index],
                                config->u.aud_info.buf,
                                config->u.aud_info.num_bytes);
            pthread_mutex_lock(&stdev->lock);
        } else {
            ALOGE("%s: soundtrigger is not streaming", __func__);
        }

        break;

    case AUDIO_EVENT_NUM_ST_SESSIONS:
    case AUDIO_EVENT_DEVICE_CONNECT:
    case AUDIO_EVENT_DEVICE_DISCONNECT:
    case AUDIO_EVENT_SVA_EXEC_MODE:
    case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
        ALOGV("%s: useless event %d", __func__, event);
        break;

    default:
        ALOGW("%s: Unknown event %d", __func__, event);
        break;
    }

exit:
    pthread_mutex_unlock(&stdev->lock);
    return ret;
}

static struct hw_module_methods_t hal_module_methods = {
    .open = stdev_open,
};

struct sound_trigger_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
        .name = "Knowles Sound Trigger HAL",
        .author = "Knowles Electronics",
        .methods = &hal_module_methods,
    },
};
