/*
 * 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_music_playing;
    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;
    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->is_music_playing == true &&
        stdev->is_bargein_route_enabled != true &&
        stdev->is_mic_route_enabled != false) {
        ALOGD("%s: Bargein enable", __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;
                }
            }
        }
    }

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->is_music_playing == true) {
        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->is_music_playing == true &&
            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->is_music_playing == true &&
                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_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->is_music_playing == true &&
        stdev->is_bargein_route_enabled == true) {
        ct = EXTERNAL_OSCILLATOR;
    }

    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, tear all route and they will be
     * reloaded after ending the call
     */
    if (get_sthal_mode(stdev) == IN_CALL) {
        ALOGD("%s: ST mode is in_call, reset all routes", __func__);
        err = enable_mic_route(stdev->route_hdl, false, ct);
        if (err != 0) {
            ALOGE("failed to tear mic route");
        }
        stdev->is_mic_route_enabled = false;

        err = enable_src_route(stdev->route_hdl, false, SRC_MIC);
        if (err != 0) {
            ALOGE("Failed to tear SRC-mic route");
        }
        if (stdev->is_music_playing == true &&
            stdev->is_bargein_route_enabled == true) {
            err = enable_amp_ref_route(stdev->route_hdl, false, strmt);
            if (err != 0) {
                ALOGE("Failed to tear amp-ref route");
            }
            err = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
            if (err != 0) {
                ALOGE("Failed to tear SRC-amp route");
            }
            err = enable_bargein_route(stdev->route_hdl, false);
            if (err != 0) {
                ALOGE("Failed to tear bargein route");
            }
        }
        // reset model route
        for (i = 0; i < MAX_MODELS; i++) {
            if (check_uuid_equality(stdev->models[i].uuid, stdev->hotword_model_uuid) ||
                (check_uuid_equality(stdev->models[i].uuid, stdev->wakeup_model_uuid))) {
                tear_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))) {
                tear_music_buffer_route(stdev->route_hdl,
                                        stdev->is_bargein_route_enabled);
            }
            tear_package_route(stdev, stdev->models[i].uuid,
                               stdev->is_bargein_route_enabled);
        }
        // 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, false, SRC_MIC);
        if (err != 0) {
            ALOGE("Failed to tear SRC-mic route");
        }
        err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
        if (err != 0) {
            ALOGE("Failed to restart SRC-mic route");
        }
    }

    if (stdev->is_music_playing == true &&
        stdev->is_bargein_route_enabled == true) {
        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, false, SRC_AMP_REF);
        if (err != 0) {
            ALOGE("Failed to tear SRC-amp route");
        }
        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, false);
        if (err != 0) {
            ALOGE("Failed to tear bargein route");
        }
        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, false, strmt);
        if (err != 0) {
            ALOGE("Failed to tear amp-ref 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, false, ct);
            if (err != 0) {
                ALOGE("failed to tear mic route");
            }
            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))) {
                    tear_hotword_buffer_route(stdev->route_hdl,
                                            stdev->is_bargein_route_enabled);
                    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))) {
                    tear_music_buffer_route(stdev->route_hdl,
                                        stdev->is_bargein_route_enabled);
                    set_music_buffer_route(stdev->route_hdl,
                                        stdev->is_bargein_route_enabled);
                }
            }
            setup_package(stdev, &stdev->models[i]);
            tear_package_route(stdev, stdev->models[i].uuid,
                            stdev->is_bargein_route_enabled);
            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)) {
                err = set_sensor_route(stdev->route_hdl, false);
                if (err != 0) {
                    ALOGE("%s: tear Sensor route fail", __func__);
                    goto exit;
                }
                stdev->is_sensor_route_enabled = false;

                // 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));
            }
            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));
            }
            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;
                    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);
        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_music_playing = 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->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);
    }

    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->is_music_playing != false) {
            stdev->is_music_playing = false;
            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 disable");
                    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 {
            ALOGD("%s: STHAL setup playback Inactive alrealy", __func__);
        }
        break;
    case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
        ALOGD("%s: handle playback stream active", __func__);
        if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
            ALOGD("%s: Playback device doesn't include SPEAKER.",
                __func__);
            goto exit;
        }
        if (stdev->is_music_playing != true) {
            stdev->is_music_playing = true;
            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 {
            ALOGD("%s: STHAL setup playback active alrealy", __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,
    },
};
