/*
 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of The Linux Foundation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#define LOG_TAG "sthal_SoundTriggerSession"
#define ATRACE_TAG (ATRACE_TAG_AUDIO | ATRACE_TAG_HAL)
#define LOG_NDEBUG 0
/*#define VERY_VERY_VERBOSE_LOGGING*/
#ifdef VERY_VERY_VERBOSE_LOGGING
#define ALOGVV ALOGV
#else
#define ALOGVV(a...) do { } while(0)
#endif

#include "SoundTriggerSession.h"

#include <log/log.h>
#include <utils/Trace.h>
#include <cstring>
#include <chrono>
#include <thread>

#include "PalApi.h"

SoundTriggerSession::SoundTriggerSession(sound_model_handle_t handle,
                                         audio_hw_call_back_t callback)
{
    state_ = IDLE;
    sm_handle_ = handle;
    rec_config_payload_ = nullptr;
    rec_config_ = nullptr;
    hal_callback_ = callback;
    pal_handle_ = nullptr;
}

SoundTriggerSession::~SoundTriggerSession()
{
    if (pal_handle_ && state_ != IDLE)
        pal_stream_close(pal_handle_);
    pal_handle_ = nullptr;

    if (rec_config_payload_) {
        free(rec_config_payload_);
        rec_config_payload_ = nullptr;
    }
    rec_config_ = nullptr;
}

int SoundTriggerSession::pal_callback(
    pal_stream_handle_t *stream_handle,
    uint32_t event_id,
    uint32_t *event_data,
    uint32_t event_size,
    uint64_t cookie)
{
    int32_t status = 0;
    bool lock_status = false;
    unsigned int size = 0;
    int i = 0;
    int j = 0;
    recognition_callback_t callback;
    SoundTriggerSession *session = nullptr;
    struct pal_st_recognition_event *event = nullptr;
    struct sound_trigger_recognition_event *st_event = nullptr;
    struct sound_trigger_phrase_recognition_event *phrase_event = nullptr;
    struct pal_st_phrase_recognition_event *pal_phrase_event = nullptr;

    if (!stream_handle || !event_data) {
        status = -EINVAL;
        ALOGE("%s: error, invalid stream handle or event data", __func__);
        goto exit;
    }

    ALOGD("%s: stream_handle (%p), event_id (%x), event_size (%d),"
        "cookie (%" PRIu64 ")", __func__, stream_handle, event_id,
        event_size, cookie);

    session = (SoundTriggerSession *)cookie;
    /*
     * Sometimes Client may call unload directly, which may get blocked
     * in PAL when releasing second stage engine thread, as it is waiting
     * for this callback to finish. Check if session state changes to non
     * ACTIVE state.
     */
    do {
        lock_status = session->ses_mutex_.try_lock();
    } while(!lock_status && (session->state_ == ACTIVE));

    if (session->state_ != ACTIVE) {
        ALOGW("%s: skip notification as client has stopped", __func__);
        goto exit;
    }

    event = (struct pal_st_recognition_event *)event_data;

    if (event->type == PAL_SOUND_MODEL_TYPE_GENERIC) {
        // parse event and check if keyword detected
        size = sizeof(struct sound_trigger_recognition_event) +
               event->data_size;
        st_event = (struct sound_trigger_recognition_event *)calloc(1, size);
        if (!st_event) {
            status = -ENOMEM;
            ALOGE("%s: error, failed to allocate recognition event", __func__);
            goto exit;
        }

        st_event->data_offset = sizeof(struct sound_trigger_recognition_event);
    } else if (event->type == PAL_SOUND_MODEL_TYPE_KEYPHRASE) {
        size = sizeof(struct sound_trigger_phrase_recognition_event) +
               event->data_size;
        phrase_event =
            (struct sound_trigger_phrase_recognition_event *)calloc(1, size);
        if (!phrase_event) {
            status = -ENOMEM;
            ALOGE("%s: error, failed to allocate recognition event", __func__);
            goto exit;
        }

        st_event = (struct sound_trigger_recognition_event *)phrase_event;
        st_event->data_offset =
            sizeof(struct sound_trigger_phrase_recognition_event);

        // copy data only related to phrase event
        pal_phrase_event = (struct pal_st_phrase_recognition_event *)event;
        phrase_event->num_phrases = pal_phrase_event->num_phrases;
        for (i = 0; i < phrase_event->num_phrases; i++) {
            phrase_event->phrase_extras[i].id =
                pal_phrase_event->phrase_extras[i].id;
            phrase_event->phrase_extras[i].recognition_modes =
                pal_phrase_event->phrase_extras[i].recognition_modes;
            phrase_event->phrase_extras[i].confidence_level =
                pal_phrase_event->phrase_extras[i].confidence_level;
            phrase_event->phrase_extras[i].num_levels =
                pal_phrase_event->phrase_extras[i].num_levels;

            for (j = 0; j < phrase_event->phrase_extras[i].num_levels; j++) {
                phrase_event->phrase_extras[i].levels[j].user_id =
                    pal_phrase_event->phrase_extras[i].levels[j].user_id;
                phrase_event->phrase_extras[i].levels[j].level =
                    pal_phrase_event->phrase_extras[i].levels[j].level;
            }
        }
    } else {
        ALOGE("%s: Invalid event type :%d", __func__, event->type);
        status = -EINVAL;
        goto exit;
    }

    // copy members inside structrue
    st_event->status = event->status;
    st_event->type = (sound_trigger_sound_model_type_t)event->type;
    st_event->model = session->GetSoundModelHandle();
    st_event->capture_available = event->capture_available;
    st_event->capture_session = session->GetCaptureHandle();
    st_event->capture_delay_ms = event->capture_delay_ms;
    st_event->capture_preamble_ms = event->capture_preamble_ms;
    st_event->trigger_in_data = event->trigger_in_data;

    st_event->audio_config.sample_rate = event->media_config.sample_rate;
    if (event->media_config.ch_info.channels == 1)
        st_event->audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
    else if (event->media_config.ch_info.channels == 2)
        st_event->audio_config.channel_mask = AUDIO_CHANNEL_IN_STEREO;
    st_event->audio_config.format = AUDIO_FORMAT_PCM_16_BIT;

    st_event->data_size = event->data_size;

    // copy opaque data
    memcpy((uint8_t *)st_event + st_event->data_offset,
           (uint8_t *)event + event->data_offset,
           st_event->data_size);

    // callback to SoundTriggerService
    session->GetRecognitionCallback(&callback);
    session->ses_mutex_.unlock();
    lock_status = false;
    ATRACE_BEGIN("sthal: client detection callback");
    callback(st_event, session->GetCookie());
    ATRACE_END();

exit:
    // release resources allocated
    if (phrase_event)
        free(phrase_event);
    else if (st_event)
        free(st_event);
    if (lock_status)
        session->ses_mutex_.unlock();
    ALOGV("%s: Exit, status %d", __func__, status);

    return status;
}

bool SoundTriggerSession::IsACDSoundModel(struct sound_trigger_sound_model *sound_model)
{
    //todo: get this from PAL instead of hardcoding.
    const sound_trigger_uuid_t qc_acd_uuid = { 0x4e93281b, 0x296e, 0x4d73, 0x9833,
                                              { 0x27, 0x10, 0xc3, 0xc7, 0xc1, 0xdb } };

    if (sound_model &&
        !std::memcmp(&sound_model->vendor_uuid, &qc_acd_uuid,
                     sizeof(sound_trigger_uuid_t)))
        return true;
    else
        return false;
}

int SoundTriggerSession::OpenPALStream(pal_stream_type_t stream_type)
{
    int status = 0;
    struct pal_stream_attributes stream_attributes;
    struct pal_device device;

    ALOGV("%s: Enter", __func__);

    device.id = PAL_DEVICE_IN_HANDSET_VA_MIC; // To-Do: convert into PAL Device
    device.config.sample_rate = 48000;
    device.config.bit_width = 16;
    device.config.ch_info.channels = 2;
    device.config.ch_info.ch_map[0] = PAL_CHMAP_CHANNEL_FL;
    device.config.ch_info.ch_map[1] = PAL_CHMAP_CHANNEL_FR;
    device.config.aud_fmt_id = PAL_AUDIO_FMT_PCM_S16_LE;

    stream_attributes.type = stream_type;
    stream_attributes.flags = (pal_stream_flags_t)0;
    stream_attributes.direction = PAL_AUDIO_INPUT;
    stream_attributes.in_media_config.sample_rate = 16000;
    stream_attributes.in_media_config.bit_width = 16;
    stream_attributes.in_media_config.aud_fmt_id = PAL_AUDIO_FMT_PCM_S16_LE;
    stream_attributes.in_media_config.ch_info.channels = 1;
    stream_attributes.in_media_config.ch_info.ch_map[0] = PAL_CHMAP_CHANNEL_FL;

    ALOGD("%s:(%x:status)%d", __func__, status, __LINE__);
    status = pal_stream_open(&stream_attributes,
                             1,
                             &device,
                             0,
                             nullptr,
                             &pal_callback,
                             (uint64_t)this,
                             &pal_handle_);

    ALOGD("%s:(%x:status)%d", __func__, status, __LINE__);

    if (status) {
        ALOGE("%s: Pal Stream Open Error (%x)", __func__, status);
        status = -EINVAL;
        goto exit;
    }

exit:
    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

int SoundTriggerSession::StopRecognition_l()
{
    int status = 0;

    ALOGV("%s: Enter", __func__);

    // deregister from audio hal
    RegisterHalEvent(false);

    // stop pal stream
    status = pal_stream_stop(pal_handle_);
    if (status) {
        ALOGE("%s: error, failed to stop pal stream, status = %d",
              __func__, status);
    }

    if (rec_config_payload_) {
        free(rec_config_payload_);
        rec_config_payload_ = nullptr;
    }
    rec_config_ = nullptr;

    state_ = STOPPED;
    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

int SoundTriggerSession::LoadSoundModel(
    struct sound_trigger_sound_model *sound_model)
{
    int status = 0;
    struct pal_st_sound_model *pal_common_sm = nullptr;
    struct pal_st_phrase_sound_model *pal_phrase_sm = nullptr;
    struct sound_trigger_sound_model *common_sm = nullptr;
    struct sound_trigger_phrase_sound_model *phrase_sm = nullptr;
    pal_param_payload *param_payload = nullptr;
    unsigned int size = 0;
    pal_stream_type_t stream_type = PAL_STREAM_VOICE_UI;

    ALOGV("%s: Enter", __func__);
    std::lock_guard<std::mutex> lck(ses_mutex_);

    if (IsACDSoundModel(sound_model))
        stream_type = PAL_STREAM_ACD;

    // open pal stream
    status = OpenPALStream(stream_type);
    if (status) {
        ALOGE("%s: error, failed to open PAL stream", __func__);
        goto exit;
    }

    // parse sound model into pal_sound_model
    if (sound_model->type == SOUND_MODEL_TYPE_GENERIC) {
        common_sm = sound_model;
        if ((stream_type != PAL_STREAM_ACD) &&
            (!common_sm->data_size ||
            (common_sm->data_offset < sizeof(*common_sm)))) {
            ALOGE("%s: Invalid Generic sound model params "
                  "data size=%d, data offset=%d", __func__,
                  common_sm->data_size, common_sm->data_offset);
            status = -EINVAL;
            goto exit;
        }

        size = sizeof(struct pal_st_sound_model) +
               common_sm->data_size;
        param_payload = (pal_param_payload *)calloc(1,
            sizeof(pal_param_payload) + size);
        if (!param_payload) {
            ALOGE("%s: error, failed to allocate pal sound model", __func__);
            status = -ENOMEM;
            goto exit;
        }
        param_payload->payload_size = size;
        pal_common_sm = (struct pal_st_sound_model *)param_payload->payload;

        pal_common_sm->type = (pal_st_sound_model_type_t)common_sm->type;
        memcpy(&pal_common_sm->uuid, &common_sm->uuid,
               sizeof(struct st_uuid));
        memcpy(&pal_common_sm->vendor_uuid, &common_sm->vendor_uuid,
               sizeof(struct st_uuid));
        pal_common_sm->data_size = common_sm->data_size;
        pal_common_sm->data_offset = sizeof(struct pal_st_sound_model);

        // data_size is zero for ACD streams and non-zero for other streams
        if (pal_common_sm->data_size)
            memcpy((uint8_t *)pal_common_sm + pal_common_sm->data_offset,
                   (uint8_t *)common_sm + common_sm->data_offset,
                   pal_common_sm->data_size);

    } else if (sound_model->type == SOUND_MODEL_TYPE_KEYPHRASE) {
        phrase_sm = (struct sound_trigger_phrase_sound_model *)sound_model;
        if ((phrase_sm->common.data_size == 0) ||
            (phrase_sm->common.data_offset < sizeof(*phrase_sm)) ||
            (phrase_sm->common.type != SOUND_MODEL_TYPE_KEYPHRASE) ||
            (phrase_sm->num_phrases == 0)) {
            ALOGE("%s: Invalid phrase sound model params "
                  "data size=%d, data offset=%d, type=%d phrases=%d",
                  __func__, phrase_sm->common.data_size,
                  phrase_sm->common.data_offset, phrase_sm->common.type,
                  phrase_sm->num_phrases);
            status = -EINVAL;
            goto exit;
        }

        size = sizeof(struct pal_st_phrase_sound_model) +
               phrase_sm->common.data_size;
        param_payload = (pal_param_payload *)calloc(1,
            sizeof(pal_param_payload) + size);
        if (!param_payload) {
            ALOGE("%s: error, failed to allocate pal phrase sound model",
                __func__);
            status = -ENOMEM;
            goto exit;
        }
        param_payload->payload_size = size;
        pal_phrase_sm =
            (struct pal_st_phrase_sound_model *)param_payload->payload;

        pal_phrase_sm->common.type =
            (pal_st_sound_model_type_t)phrase_sm->common.type;
        memcpy(&pal_phrase_sm->common.uuid, &phrase_sm->common.uuid,
               sizeof(struct st_uuid));
        memcpy(&pal_phrase_sm->common.vendor_uuid,
               &phrase_sm->common.vendor_uuid,
               sizeof(struct st_uuid));
        pal_phrase_sm->common.data_size = phrase_sm->common.data_size;
        pal_phrase_sm->common.data_offset =
            sizeof(struct pal_st_phrase_sound_model);
        pal_phrase_sm->num_phrases = phrase_sm->num_phrases;

        for (int i = 0; i < pal_phrase_sm->num_phrases; i++) {
            pal_phrase_sm->phrases[i].id = phrase_sm->phrases[i].id;
            pal_phrase_sm->phrases[i].recognition_mode =
                phrase_sm->phrases[i].recognition_mode;
            pal_phrase_sm->phrases[i].num_users =
                phrase_sm->phrases[i].num_users;
            for (int j = 0; j < pal_phrase_sm->phrases[i].num_users; j++)
                pal_phrase_sm->phrases[i].users[j] =
                    phrase_sm->phrases[i].users[j];

            memcpy(pal_phrase_sm->phrases[i].locale,
                   phrase_sm->phrases[i].locale,
                   SOUND_TRIGGER_MAX_LOCALE_LEN);
            memcpy(pal_phrase_sm->phrases[i].text,
                   phrase_sm->phrases[i].text,
                   SOUND_TRIGGER_MAX_STRING_LEN);
        }

        memcpy((uint8_t *)pal_phrase_sm + pal_phrase_sm->common.data_offset,
               (uint8_t *)phrase_sm + phrase_sm->common.data_offset,
               pal_phrase_sm->common.data_size);
        pal_common_sm = (struct pal_st_sound_model *)pal_phrase_sm;
    } else {
        ALOGE("%s: error, unknown sound model type %d",
              __func__, sound_model->type);
        status = -EINVAL;
        goto exit;
    }

    // load sound model with pal api
    status = pal_stream_set_param(pal_handle_,
                                  PAL_PARAM_ID_LOAD_SOUND_MODEL,
                                  param_payload);
    if (status) {
        ALOGE("%s: error, failed to load sound model into PAL, status = %d",
              __func__, status);
        goto exit;
    }

    state_ = LOADED;

exit:
    if (param_payload)
        free(param_payload);
    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

int SoundTriggerSession::UnloadSoundModel()
{
    int status = 0;

    ALOGV("%s: Enter", __func__);
    std::lock_guard<std::mutex> lck(ses_mutex_);
    if (state_ == ACTIVE) {
        status = StopRecognition_l();
        if (status) {
            ALOGE("%s: error, failed to stop recognition, status = %d",
                __func__, status);
        }
    }

    status = pal_stream_close(pal_handle_);
    if (status) {
        ALOGE("%s: error, failed to close pal stream, status = %d",
              __func__, status);
    }
    pal_handle_ = nullptr;
    if (rec_config_payload_) {
        free(rec_config_payload_);
        rec_config_payload_ = nullptr;
    }
    rec_config_ = nullptr;

    state_ = IDLE;

exit:
    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

int SoundTriggerSession::StartRecognition(
    const struct sound_trigger_recognition_config *config,
    recognition_callback_t callback,
    void *cookie,
    uint32_t version)
{
    int status = 0;
    unsigned int size = 0;

    ALOGV("%s: Enter, state = %d", __func__, state_);
    std::lock_guard<std::mutex> lck(ses_mutex_);

    if (rec_config_payload_) {
        free(rec_config_payload_); // valid due to subsequent start after a detection
        rec_config_payload_ = nullptr;
    }
    size = sizeof(struct pal_st_recognition_config) +
           config->data_size;
    rec_config_payload_ = (pal_param_payload *)calloc(1,
        sizeof(pal_param_payload) + size);
    if (!rec_config_payload_) {
        ALOGE("%s: error, failed to allocate pal recognition config", __func__);
        status = -ENOMEM;
        goto exit;
    }
    rec_config_payload_->payload_size = size;
    rec_config_ = (struct pal_st_recognition_config *)rec_config_payload_->payload;

    rec_config_->capture_handle = (int32_t)config->capture_handle;
    rec_config_->capture_device = (uint32_t)config->capture_device;
    rec_config_->capture_requested = config->capture_requested;
    rec_config_->num_phrases = config->num_phrases;
    for (int i = 0; i < rec_config_->num_phrases; i++) {
        rec_config_->phrases[i].id = config->phrases[i].id;
        rec_config_->phrases[i].recognition_modes =
            config->phrases[i].recognition_modes;
        rec_config_->phrases[i].confidence_level =
            config->phrases[i].confidence_level;
        rec_config_->phrases[i].num_levels = config->phrases[i].num_levels;

        for (int j = 0; j < rec_config_->phrases[i].num_levels; j++) {
            rec_config_->phrases[i].levels[j].user_id =
                config->phrases[i].levels[j].user_id;
            rec_config_->phrases[i].levels[j].level =
                config->phrases[i].levels[j].level;
        }
    }
    rec_config_->data_size = config->data_size;
    rec_config_->data_offset = sizeof(struct pal_st_recognition_config);
    rec_config_->cookie = (uint8_t *)this;
    if (version == SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
        memcpy((uint8_t *)rec_config_ + rec_config_->data_offset,
            (uint8_t *)config + config->data_offset -
            sizeof(struct sound_trigger_recognition_config_header),
            rec_config_->data_size);
    } else {
        memcpy((uint8_t *)rec_config_ + rec_config_->data_offset,
            (uint8_t *)config + config->data_offset,
            rec_config_->data_size);
    }

    // set recognition config
    status = pal_stream_set_param(pal_handle_,
                                  PAL_PARAM_ID_RECOGNITION_CONFIG,
                                  rec_config_payload_);
    if (status) {
        ALOGE("%s: error, failed to set recognition config, status = %d",
              __func__, status);
        goto exit;
    }

    rec_callback_ = callback;
    cookie_ = cookie;

    // start pal stream
    status = pal_stream_start(pal_handle_);
    if (status) {
        ALOGE("%s: error, failed to start pal stream, status = %d",
              __func__, status);
        goto exit;
    }
    state_ = ACTIVE;

    // register to audio hal
    RegisterHalEvent(true);

exit:
    if (status && rec_config_payload_) {
        free(rec_config_payload_);
        rec_config_payload_ = nullptr;
        rec_config_ = nullptr;
    }

    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

int SoundTriggerSession::StopRecognition()
{
    int status = 0;

    ALOGV("%s: Enter", __func__);
    std::lock_guard<std::mutex> lck(ses_mutex_);

    // deregister from audio hal
    RegisterHalEvent(false);

    // stop pal stream
    status = pal_stream_stop(pal_handle_);
    if (status) {
        ALOGE("%s: error, failed to stop pal stream, status = %d",
              __func__, status);
    }

    if (rec_config_payload_) {
        free(rec_config_payload_);
        rec_config_payload_ = nullptr;
    }
    rec_config_ = nullptr;

    state_ = STOPPED;
    ALOGV("%s: Exit, status = %d", __func__, status);

    return status;
}

void SoundTriggerSession::RegisterHalEvent(bool is_register)
{
    struct sound_trigger_event_info event_info;

    if ((rec_config_ && rec_config_->capture_requested) && hal_callback_) {
        if (is_register) {
            ALOGD("%s:[c%d] ST_EVENT_SESSION_REGISTER capture_handle %d",
                  __func__, sm_handle_, rec_config_->capture_handle);
            event_info.st_ses.p_ses = (void *)pal_handle_;
            event_info.st_ses.capture_handle = rec_config_->capture_handle;
            hal_callback_(ST_EVENT_SESSION_REGISTER, &event_info);
        } else {
            ALOGD("%s:[c%d] ST_EVENT_SESSION_DEREGISTER capture_handle %d",
                  __func__, sm_handle_, rec_config_->capture_handle);
            event_info.st_ses.p_ses = (void *)pal_handle_;
            event_info.st_ses.capture_handle = rec_config_->capture_handle;
            hal_callback_(ST_EVENT_SESSION_DEREGISTER, &event_info);
        }
    }
}

sound_model_handle_t SoundTriggerSession::GetSoundModelHandle()
{
    return sm_handle_;
}

int SoundTriggerSession::GetCaptureHandle()
{
    int handle = 0;

    if (rec_config_)
        handle = rec_config_->capture_handle;

    return handle;
}

int SoundTriggerSession::GetModuleVersion(char version[])
{
    int status = 0;
    pal_param_payload *param_payload = nullptr;
    struct version_arch_payload *version_payload = nullptr;

    ALOGV("%s: Enter", __func__);
    std::lock_guard<std::mutex> lck(ses_mutex_);
    status = OpenPALStream(PAL_STREAM_VOICE_UI);
    if (status) {
        ALOGE("%s: Failed to open pal stream, status = %d", __func__, status);
        goto exit;
    }

    status = pal_stream_get_param(pal_handle_,
        PAL_PARAM_ID_WAKEUP_MODULE_VERSION, &param_payload);
    if (status) {
        ALOGE("%s: Failed to get version, status = %d", __func__, status);
        goto exit;
    }

    version_payload = (struct version_arch_payload *)param_payload;
    snprintf(version, SOUND_TRIGGER_MAX_STRING_LEN, "%d, %s",
        version_payload->version, version_payload->arch);

exit:
    if (pal_handle_) {
        status = pal_stream_close(pal_handle_);
        if (status) {
            ALOGE("%s: error, failed to close pal stream, status = %d",
                __func__, status);
        }
        pal_handle_ = nullptr;
    }
    ALOGV("%s: Exit", __func__);
    return 0;
}

void *SoundTriggerSession::GetCookie()
{
    return cookie_;
}

void SoundTriggerSession::GetRecognitionCallback(
    recognition_callback_t *callback)
{
    *callback = rec_callback_;
}

