/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 "NanohubHAL"

#include "file.h"
#include <json/json.h>

#include <cassert>
#include <cerrno>
#include <cinttypes>
#include <string>

#include <endian.h>

#include <vector>

#include <log/log.h>

#include <endian.h>
#include <sys/stat.h>

#include <media/stagefright/foundation/ADebug.h>

#include <hardware/context_hub.h>
#include "nanohub_perdevice.h"
#include "system_comms.h"
#include "nanohubhal.h"

#define CHRE_APP_DIR        "/data/vendor/sensor/chre"
#define CHRE_APP_DIR_PERMS  (S_IRUSR | S_IWUSR | S_IXUSR)
#define CHRE_APP_FILE_PERMS (S_IRUSR | S_IWUSR)
#define CHRE_APP_SETTINGS   CHRE_APP_DIR "/apps.json"

namespace android {

namespace nanohub {

static void readAppName(MessageBuf &buf, hub_app_name_t &name)
{
    name.id = buf.readU64();
}

static void writeAppName(MessageBuf &buf, const hub_app_name_t &name)
{
    buf.writeU64(name.id);
}

static void readNanohubMemInfo(MessageBuf &buf, NanohubMemInfo &mi)
{
    uint8_t type, len;
    uint32_t ramFree = NANOHUB_MEM_SZ_UNKNOWN;
    uint32_t eeFree = NANOHUB_MEM_SZ_UNKNOWN;
    uint32_t sharedFree = NANOHUB_MEM_SZ_UNKNOWN;
    uint32_t osFree = NANOHUB_MEM_SZ_UNKNOWN;

    mi.flashSz = NANOHUB_MEM_SZ_UNKNOWN;
    mi.blSz = NANOHUB_MEM_SZ_UNKNOWN;
    mi.osSz = NANOHUB_MEM_SZ_UNKNOWN;
    mi.sharedSz = NANOHUB_MEM_SZ_UNKNOWN;
    mi.eeSz = NANOHUB_MEM_SZ_UNKNOWN;
    mi.ramSz = NANOHUB_MEM_SZ_UNKNOWN;

    mi.blUse = NANOHUB_MEM_SZ_UNKNOWN;
    mi.osUse = NANOHUB_MEM_SZ_UNKNOWN;
    mi.sharedUse = NANOHUB_MEM_SZ_UNKNOWN;
    mi.eeUse = NANOHUB_MEM_SZ_UNKNOWN;
    mi.ramUse = NANOHUB_MEM_SZ_UNKNOWN;

    while (buf.getRoom() >= 2) {
        type = buf.readU8();
        len = buf.readU8();
        if (buf.getRoom() >= len) {
            switch(type) {
            case NANOHUB_HAL_SYS_INFO_HEAP_FREE:
                if (len == sizeof(ramFree))
                    ramFree = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_RAM_SIZE:
                if (len == sizeof(mi.ramSz))
                    mi.ramSz = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_EEDATA_SIZE:
                if (len == sizeof(mi.ramSz))
                    mi.eeSz = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_EEDATA_FREE:
                if (len == sizeof(eeFree))
                    eeFree = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_CODE_SIZE:
                if (len == sizeof(mi.osSz))
                    mi.osSz = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_CODE_FREE:
                if (len == sizeof(osFree))
                    osFree = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_SHARED_SIZE:
                if (len == sizeof(mi.sharedSz))
                    mi.sharedSz = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_SHARED_FREE:
                if (len == sizeof(sharedFree))
                    sharedFree = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_SYS_INFO_END:
                if (len != 0 || buf.getRoom() != 0) {
                    ALOGE("%s: failed to read object", __func__);
                    return;
                }
                break;
            default:
                ALOGI("%s: unsupported type: %d", __func__, type);
                buf.readRaw(len);
                break;
            }
        } else {
            ALOGE("%s: failed to read object", __func__);
            return;
        }
    }

    if (buf.getRoom() != 0) {
        ALOGE("%s: failed to read object", __func__);
        return;
    }

    if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN && ramFree != NANOHUB_MEM_SZ_UNKNOWN)
        mi.ramUse = mi.ramSz - ramFree;
    if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN && eeFree != NANOHUB_MEM_SZ_UNKNOWN)
        mi.eeUse = mi.eeSz - eeFree;
    if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN && osFree != NANOHUB_MEM_SZ_UNKNOWN)
        mi.osUse = mi.osSz - osFree;
    if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN && sharedFree != NANOHUB_MEM_SZ_UNKNOWN)
        mi.sharedUse = mi.sharedSz - sharedFree;
}

NanohubRsp::NanohubRsp(MessageBuf &buf, uint32_t transactionId, bool chre)
{
    // all responses start with command and have a 4-byte status (result code)
    buf.reset();
    if (buf.getSize() < 5) {
        mStatus = -EINVAL;
    } else {
        mCmd = buf.readU8();
        mStatus = buf.readU32();
        if (chre)
            mTransactionId = transactionId;
        else
            mTransactionId = 0;
    }
}

int SystemComm::sendToSystem(const void *data, size_t len, uint32_t transactionId)
{
    if (NanoHub::messageTracingEnabled()) {
        dumpBuffer("HAL -> SYS", getSystem()->mHostIfAppName, transactionId, 0, data, len);
    }
    return NanoHub::sendToDevice(&getSystem()->mHostIfAppName, data, len, transactionId);
}

inline hub_app_name_t deviceAppNameToHost(const hub_app_name_t src)
{
    hub_app_name_t res = { .id = le64toh(src.id) };
    return res;
}

inline hub_app_name_t hostAppNameToDevice(const hub_app_name_t src)
{
    hub_app_name_t res = { .id = htole64(src.id) };
    return res;
}

const uint8_t app_info_tags[] =
{
    NANOHUB_HAL_APP_INFO_APPID,
    NANOHUB_HAL_APP_INFO_CRC,
    NANOHUB_HAL_APP_INFO_TID,
    NANOHUB_HAL_APP_INFO_VERSION,
    NANOHUB_HAL_APP_INFO_ADDR,
    NANOHUB_HAL_APP_INFO_SIZE,
    NANOHUB_HAL_APP_INFO_HEAP,
    NANOHUB_HAL_APP_INFO_DATA,
    NANOHUB_HAL_APP_INFO_BSS,
    NANOHUB_HAL_APP_INFO_CHRE_MAJOR,
    NANOHUB_HAL_APP_INFO_CHRE_MINOR,
    NANOHUB_HAL_APP_INFO_END,
};

const uint8_t sys_info_tags[] =
{
    NANOHUB_HAL_SYS_INFO_HEAP_FREE,
    NANOHUB_HAL_SYS_INFO_RAM_SIZE,
    NANOHUB_HAL_SYS_INFO_EEDATA_SIZE,
    NANOHUB_HAL_SYS_INFO_EEDATA_FREE,
    NANOHUB_HAL_SYS_INFO_CODE_SIZE,
    NANOHUB_HAL_SYS_INFO_CODE_FREE,
    NANOHUB_HAL_SYS_INFO_SHARED_SIZE,
    NANOHUB_HAL_SYS_INFO_SHARED_FREE,
    NANOHUB_HAL_SYS_INFO_END,
};

int SystemComm::MemInfoSession::setup(const hub_message_t *, uint32_t transactionId, AppManager &)
{
    std::lock_guard<std::mutex> _l(mLock);
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    buf.writeU8(NANOHUB_HAL_SYS_INFO);
    buf.writeRaw(sys_info_tags, sizeof(sys_info_tags));

    setState(SESSION_USER);
    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}

int SystemComm::MemInfoSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre)
{
    std::lock_guard<std::mutex> _l(mLock);
    NanohubRsp rsp(buf, transactionId, chre);

    if (rsp.mCmd != NANOHUB_HAL_SYS_INFO)
        return 1;

    size_t len = buf.getRoom();

    if (getState() != SESSION_USER) {
        ALOGE("%s: Invalid state; have %d, need %d", __func__, getState(), SESSION_USER);
        return -EINVAL;
    }

    std::vector<mem_range_t> ranges;
    ranges.reserve(4);
    if (len) {
        NanohubMemInfo mi;
        readNanohubMemInfo(buf, mi);

        //if each is valid, copy to output area
        if (mi.sharedSz != NANOHUB_MEM_SZ_UNKNOWN &&
            mi.sharedUse != NANOHUB_MEM_SZ_UNKNOWN)
            ranges.push_back({
                .type = HUB_MEM_TYPE_MAIN,
                .total_bytes = mi.sharedSz,
                .free_bytes = mi.sharedSz - mi.sharedUse,
            });

        if (mi.osSz != NANOHUB_MEM_SZ_UNKNOWN &&
            mi.osUse != NANOHUB_MEM_SZ_UNKNOWN)
            ranges.push_back({
                .type = HUB_MEM_TYPE_OS,
                .total_bytes = mi.osSz,
                .free_bytes = mi.osSz - mi.osUse,
            });

        if (mi.eeSz != NANOHUB_MEM_SZ_UNKNOWN &&
            mi.eeUse != NANOHUB_MEM_SZ_UNKNOWN)
            ranges.push_back({
                .type = HUB_MEM_TYPE_EEDATA,
                .total_bytes = mi.eeSz,
                .free_bytes = mi.eeSz - mi.eeUse,
            });

        if (mi.ramSz != NANOHUB_MEM_SZ_UNKNOWN &&
            mi.ramUse != NANOHUB_MEM_SZ_UNKNOWN)
            ranges.push_back({
                .type = HUB_MEM_TYPE_RAM,
                .total_bytes = mi.ramSz,
                .free_bytes = mi.ramSz - mi.ramUse,
            });
    }

    //send it out
    sendToApp(CONTEXT_HUB_QUERY_MEMORY, transactionId,
              static_cast<const void *>(ranges.data()),
              ranges.size() * sizeof(ranges[0]));

    complete();
    return 0;
}

int SystemComm::AppMgmtSession::setup(const hub_message_t *appMsg, uint32_t transactionId, AppManager &appManager)
{
    std::lock_guard<std::mutex> _l(mLock);

    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    const uint8_t *msgData = static_cast<const uint8_t*>(appMsg->message);

    mCmd = appMsg->message_type;
    mLen = appMsg->message_len;
    mPos = 0;
    mNextPos = 0;
    mErrCnt = 0;

    switch (mCmd) {
    case  CONTEXT_HUB_APPS_ENABLE:
        return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_START, appManager);
    case  CONTEXT_HUB_APPS_DISABLE:
        return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_STOP, appManager);
    case  CONTEXT_HUB_UNLOAD_APP:
        return setupMgmt(appMsg, transactionId, NANOHUB_HAL_APP_MGMT_UNLOAD, appManager);
    case  CONTEXT_HUB_LOAD_APP:
    {
        const load_app_request_t *appReq = static_cast<const load_app_request_t*>(appMsg->message);
        if (appReq == nullptr || mLen <= sizeof(*appReq)) {
            ALOGE("%s: Invalid app header: too short\n", __func__);
            return -EINVAL;
        }
        mAppName = appReq->app_binary.app_id;
        if (!appManager.isAppLoaded(mAppName)) {
            appManager.addNewApp(mAppName, appReq->app_binary.app_version);
            appManager.writeApp(mAppName, msgData, mLen);
            mData.clear();
            mData = std::vector<uint8_t>(msgData, msgData + mLen);
            setState(TRANSFER);

            buf.writeU8(NANOHUB_HAL_START_UPLOAD);
            buf.writeU8(0);
            buf.writeU32(mLen);

            return sendToSystem(buf.getData(), buf.getPos(), transactionId);
        } else {
            if (appManager.cmpApp(mAppName, msgData, mLen)) {
                mFlashAddr = appManager.getFlashAddr(mAppName);
                if (appManager.isAppRunning(mAppName)) {
                    setState(STOP_RUN);

                    buf.writeU8(NANOHUB_HAL_APP_MGMT);
                    writeAppName(buf, mAppName);
                    buf.writeU8(NANOHUB_HAL_APP_MGMT_STOP);

                    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
                } else {
                    setState(RUN);

                    buf.writeU8(NANOHUB_HAL_APP_MGMT);
                    writeAppName(buf, mAppName);
                    buf.writeU8(NANOHUB_HAL_APP_MGMT_START);

                    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
                }
            } else {
                appManager.setCachedVersion(mAppName, appReq->app_binary.app_version);
                appManager.writeApp(mAppName, msgData, mLen);
                mData.clear();
                mData = std::vector<uint8_t>(msgData, msgData + mLen);
                if (appManager.isAppRunning(mAppName)) {
                    setState(STOP_TRANSFER);

                    buf.writeU8(NANOHUB_HAL_APP_MGMT);
                    writeAppName(buf, mAppName);
                    buf.writeU8(NANOHUB_HAL_APP_MGMT_STOP);

                    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
                } else {
                    setState(TRANSFER);

                    buf.writeU8(NANOHUB_HAL_START_UPLOAD);
                    buf.writeU8(0);
                    buf.writeU32(mLen);

                    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
                }
            }
        }
    }
    case  CONTEXT_HUB_OS_REBOOT:
        setState(REBOOT);

        buf.writeU8(NANOHUB_HAL_SYS_MGMT);
        buf.writeU8(NANOHUB_HAL_SYS_MGMT_REBOOT);

        return sendToSystem(buf.getData(), buf.getPos(), transactionId);

    case  CONTEXT_HUB_START_APPS:
        if (mLen == sizeof(mStatus))
            memcpy(&mStatus, msgData, mLen);
        appManager.eraseApps();
        setState(QUERY_START);

        buf.writeU8(NANOHUB_HAL_APP_INFO);
        buf.writeU32(0);
        buf.writeRaw(app_info_tags, sizeof(app_info_tags));

        return sendToSystem(buf.getData(), buf.getPos(), transactionId);
    }

    return -EINVAL;
}

int SystemComm::AppMgmtSession::setupMgmt(const hub_message_t *appMsg, uint32_t transactionId, uint32_t cmd, AppManager &appManager)
{
    int32_t result = -1; // results are only directly returned on failure
    const hub_app_name_t &appName = *static_cast<const hub_app_name_t*>(appMsg->message);
    if (appMsg->message_len != sizeof(appName)) {
        return -EINVAL;
    }
    mAppName = appName;

    switch (cmd) {
    case NANOHUB_HAL_APP_MGMT_START:
        if (appManager.isAppRunning(mAppName)) {
            appManager.setCachedStart(mAppName, true);
            sendToApp(mCmd, transactionId, &result, sizeof(result));
            complete();
            return 0;
        }
        break;
    case NANOHUB_HAL_APP_MGMT_STOP:
    case NANOHUB_HAL_APP_MGMT_UNLOAD:
        appManager.setCachedStart(mAppName, false);
        if (!appManager.isAppRunning(mAppName)) {
            sendToApp(mCmd, transactionId, &result, sizeof(result));
            complete();
            return 0;
        }
        break;
    }
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    buf.writeU8(NANOHUB_HAL_APP_MGMT);
    writeAppName(buf, appName);
    buf.writeU8(cmd);
    setState(MGMT);

    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}

int SystemComm::AppMgmtSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre)
{
    int ret = 0;
    std::lock_guard<std::mutex> _l(mLock);
    NanohubRsp rsp(buf, transactionId, chre);

    switch (getState()) {
    case TRANSFER:
        ret = handleTransfer(rsp, buf, appManager);
        break;
    case STOP_TRANSFER:
        ret = handleStopTransfer(rsp, buf, appManager);
         break;
    case QUERY_START:
        ret = handleQueryStart(rsp, buf, appManager);
        break;
    case START:
        ret = handleStart(rsp, buf, appManager);
        break;
    case FINISH:
        ret = handleFinish(rsp, buf, appManager);
        break;
    case RUN:
        ret = handleRun(rsp, buf, appManager);
        break;
    case STOP_RUN:
        ret = handleStopRun(rsp, buf, appManager);
        break;
    case REBOOT:
        ret = handleReboot(rsp, buf, appManager);
        break;
    case ERASE_TRANSFER:
        ret = handleEraseTransfer(rsp, buf, appManager);
        break;
    case MGMT:
        ret = handleMgmt(rsp, buf, appManager);
        break;
    case INFO:
        ret = handleInfo(rsp, buf, appManager);
        break;
    }

    return ret;
}

int SystemComm::AppMgmtSession::handleTransfer(NanohubRsp &rsp, MessageBuf &, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_CONT_UPLOAD && rsp.mCmd != NANOHUB_HAL_START_UPLOAD)
        return 1;

    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));
    int32_t result = 0;

    static_assert(NANOHUB_UPLOAD_CHUNK_SZ_MAX <= (MAX_RX_PACKET-5),
                  "Invalid chunk size");

    if (rsp.mStatus == NANOHUB_HAL_UPLOAD_ACCEPTED) {
        mPos = mNextPos;
        mErrCnt = 0;
    } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_RESEND) {
        mErrCnt ++;
    } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_RESTART) {
        mPos = 0;
        mErrCnt ++;
    } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_CANCEL ||
               rsp.mStatus == NANOHUB_HAL_UPLOAD_CANCEL_NO_RETRY) {
        mPos = mLen;
        result = NANOHUB_APP_NOT_LOADED;
    } else if (rsp.mStatus == NANOHUB_HAL_UPLOAD_NO_SPACE) {
        mPos = 0;
        mErrCnt = 0;
        setState(ERASE_TRANSFER);

        buf.writeU8(NANOHUB_HAL_SYS_MGMT);
        buf.writeU8(NANOHUB_HAL_SYS_MGMT_ERASE);

        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else if (mErrCnt > 5) {
        mPos = mLen;
        result = NANOHUB_APP_NOT_LOADED;
    } else {
        mErrCnt ++;
    }

    if (result != 0) {
        appManager.clearCachedApp(mAppName);

        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    } else if (mPos < mLen) {
        uint32_t chunkSize = mLen - mPos;

        if (chunkSize > NANOHUB_UPLOAD_CHUNK_SZ_MAX) {
            chunkSize = NANOHUB_UPLOAD_CHUNK_SZ_MAX;
        }

        buf.writeU8(NANOHUB_HAL_CONT_UPLOAD);
        buf.writeU32(mPos);
        buf.writeRaw(&mData[mPos], chunkSize);
        mNextPos = mPos + chunkSize;
    } else {
        buf.writeU8(NANOHUB_HAL_FINISH_UPLOAD);
        setState(FINISH);
    }

    return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
}

int SystemComm::AppMgmtSession::handleStopTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd != NANOHUB_HAL_APP_MGMT_STOP)
        return 1;

    MgmtStatus sts = { .value = buf.readU32() };

    ALOGI("Nanohub NEW APP STOP: %08" PRIX32 "\n", sts.value);
    if (rsp.mStatus == 0) {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        setState(TRANSFER);

        buf.writeU8(NANOHUB_HAL_START_UPLOAD);
        buf.writeU8(0);
        buf.writeU32(mLen);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else {
        int32_t result = NANOHUB_APP_NOT_LOADED;

        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    }
}

int SystemComm::AppMgmtSession::handleQueryStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{

    if (rsp.mCmd != NANOHUB_HAL_APP_INFO)
        return 1;

    size_t len = buf.getRoom();
    if (len) {
        uint32_t nextAddr = appManager.readNanohubAppInfo(buf);

        if (nextAddr) {
            char data[MAX_RX_PACKET];
            MessageBuf buf(data, sizeof(data));

            buf.writeU8(NANOHUB_HAL_APP_INFO);
            buf.writeU32(nextAddr);
            buf.writeRaw(app_info_tags, sizeof(app_info_tags));

            return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
        }
    }

    appManager.getAppsToStart(mAppList);
    if (mAppList.empty()) {
        sendToApp(CONTEXT_HUB_OS_REBOOT, 0, &mStatus, sizeof(mStatus));
        complete();
        return 0;
    } else {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        mAppName = mAppList.back();
        mAppList.pop_back();
        setState(START);

        buf.writeU8(NANOHUB_HAL_APP_MGMT);
        writeAppName(buf, mAppName);
        buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    }
}

int SystemComm::AppMgmtSession::handleStart(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd != NANOHUB_HAL_APP_MGMT_START)
        return 1;

    MgmtStatus sts = { .value = buf.readU32() };

    ALOGI("Nanohub EXISTING APP START: %08" PRIX32 "\n", sts.value);
    if (mAppList.empty()) {
        sendToApp(CONTEXT_HUB_OS_REBOOT, 0, &mStatus, sizeof(mStatus));
        complete();
        return 0;
    } else {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        mAppName = mAppList.back();
        mAppList.pop_back();

        buf.writeU8(NANOHUB_HAL_APP_MGMT);
        writeAppName(buf, mAppName);
        buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    }
}

int SystemComm::AppMgmtSession::handleFinish(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_FINISH_UPLOAD)
        return 1;

    mFlashAddr = buf.readU32();
    uint32_t crc = buf.readU32();
    mData.clear();

    if (rsp.mStatus == 0) {
        appManager.setCachedCrc(mAppName, crc);
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        setState(RUN);

        buf.writeU8(NANOHUB_HAL_APP_MGMT);
        writeAppName(buf, mAppName);
        buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else {
        int32_t result = NANOHUB_APP_NOT_LOADED;
        appManager.clearCachedApp(mAppName);

        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    }
}

int SystemComm::AppMgmtSession::handleRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd != NANOHUB_HAL_APP_MGMT_START)
        return 1;

    MgmtStatus sts = { .value = buf.readU32() };

    ALOGI("Nanohub NEW APP START: %08" PRIX32 "\n", sts.value);
    if (rsp.mStatus == 0) {
        appManager.setCachedStart(mAppName, true);
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        setState(INFO);

        buf.writeU8(NANOHUB_HAL_APP_INFO);
        buf.writeU32(mFlashAddr);
        buf.writeRaw(app_info_tags, sizeof(app_info_tags));

        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else {
        appManager.setCachedStart(mAppName, false);
        int32_t result = NANOHUB_APP_NOT_LOADED;
        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    }
}

int SystemComm::AppMgmtSession::handleInfo(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_INFO)
        return 1;
    int32_t result = 0;
    size_t len = buf.getRoom();
    if (len) {
        appManager.readNanohubAppInfo(buf);
        appManager.saveApps();
    }
    sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
    complete();
    return 0;
}

int SystemComm::AppMgmtSession::handleStopRun(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd != NANOHUB_HAL_APP_MGMT_STOP)
        return 1;

    MgmtStatus sts = { .value = buf.readU32() };

    ALOGI("Nanohub NEW APP STOP: %08" PRIX32 "\n", sts.value);
    if (rsp.mStatus == 0) {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        setState(RUN);

        buf.writeU8(NANOHUB_HAL_APP_MGMT);
        writeAppName(buf, mAppName);
        buf.writeU8(NANOHUB_HAL_APP_MGMT_START);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else {
        int32_t result = NANOHUB_APP_NOT_LOADED;

        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    }
}

/* reboot notification, when triggered by App request */
int SystemComm::AppMgmtSession::handleReboot(NanohubRsp &rsp, MessageBuf &buf, AppManager &)
{
    if (rsp.mCmd != NANOHUB_HAL_SYS_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd == NANOHUB_HAL_SYS_MGMT_REBOOT)
        ALOGI("Nanohub reboot status [USER REQ]: %08" PRIX32 "\n", rsp.mStatus);

    // reboot notification is sent by SessionManager
    complete();

    return 0;
}

int SystemComm::AppMgmtSession::handleEraseTransfer(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_SYS_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();

    if (cmd == NANOHUB_HAL_SYS_MGMT_ERASE && rsp.mStatus == 0) {
        char data[MAX_RX_PACKET];
        MessageBuf buf(data, sizeof(data));
        appManager.eraseApps();
        setState(TRANSFER);

        buf.writeU8(NANOHUB_HAL_START_UPLOAD);
        buf.writeU8(0);
        buf.writeU32(mLen);
        return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
    } else {
        int32_t result = NANOHUB_APP_NOT_LOADED;

        sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
        complete();
        return 0;
    }
}

int SystemComm::AppMgmtSession::handleMgmt(NanohubRsp &rsp, MessageBuf &buf, AppManager &appManager)
{
    if (rsp.mCmd != NANOHUB_HAL_APP_MGMT)
        return 1;

    uint8_t cmd = buf.readU8();
    MgmtStatus sts = { .value = buf.readU32() };

    bool valid = false;

    int32_t result = rsp.mStatus;

    if (result != 0)
        result = -1;

    switch (cmd) {
    case NANOHUB_HAL_APP_MGMT_STOP:
        valid = mCmd == CONTEXT_HUB_APPS_DISABLE;
        if (valid && rsp.mStatus == 0)
            appManager.clearRunning(mAppName);
        break;
    case NANOHUB_HAL_APP_MGMT_START:
        valid = mCmd == CONTEXT_HUB_APPS_ENABLE;
        if (valid && rsp.mStatus == 0) {
            appManager.setCachedStart(mAppName, true);
            char data[MAX_RX_PACKET];
            MessageBuf buf(data, sizeof(data));
            setState(INFO);

            buf.writeU8(NANOHUB_HAL_APP_INFO);
            buf.writeU32(appManager.getFlashAddr(mAppName));
            buf.writeRaw(app_info_tags, sizeof(app_info_tags));

            return sendToSystem(buf.getData(), buf.getPos(), rsp.mTransactionId);
        }
        break;
    case NANOHUB_HAL_APP_MGMT_UNLOAD:
        valid = mCmd == CONTEXT_HUB_UNLOAD_APP;
        if (valid && rsp.mStatus == 0)
            appManager.clearRunning(mAppName);
        break;
    default:
        return 1;
    }

    ALOGI("Nanohub MGMT response: CMD=%02X; STATUS=%08" PRIX32, rsp.mCmd, sts.value);
    if (!valid) {
        ALOGE("Invalid response for this state: APP CMD=%02X", mCmd);
        return -EINVAL;
    }

    sendToApp(mCmd, rsp.mTransactionId, &result, sizeof(result));
    complete();
    return 0;
}

int SystemComm::KeyInfoSession::setup(const hub_message_t *, uint32_t transactionId, AppManager &) {
    std::lock_guard<std::mutex> _l(mLock);
    mKeyNum = 0;
    mKeyOffset = 0;
    mRsaKeyData.clear();
    setState(SESSION_USER);
    mStatus = -EBUSY;
    return requestRsaKeys(transactionId);
}

int SystemComm::KeyInfoSession::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &, bool chre)
{
    std::lock_guard<std::mutex> _l(mLock);
    NanohubRsp rsp(buf, transactionId, chre);

    if (getState() != SESSION_USER) {
        // invalid state
        mStatus = -EFAULT;
        return mStatus;
    }

    uint32_t keyLen = buf.readU32();
    uint32_t dataLen = buf.getRoom();

    if (dataLen) {
        mRsaKeyData.insert(mRsaKeyData.end(),
                           buf.getData() + buf.getPos(),
                           buf.getData() + buf.getSize());
        if (mKeyOffset + dataLen >= keyLen) {
            mKeyNum++;
            mKeyOffset = 0;
        } else {
            mKeyOffset += dataLen;
        }
        return requestRsaKeys(transactionId);
    } else {
        mStatus = 0;
        complete();
        return 0;
    }
}

int SystemComm::KeyInfoSession::requestRsaKeys(uint32_t transactionId)
{
    char data[MAX_RX_PACKET];
    MessageBuf buf(data, sizeof(data));

    buf.writeU8(NANOHUB_HAL_KEY_INFO);
    buf.writeU32(mKeyNum);
    buf.writeU32(mKeyOffset);

    return sendToSystem(buf.getData(), buf.getPos(), transactionId);
}

void SystemComm::AppManager::dumpAppInfo(std::string &result)
{
    char buffer[256];

    for (auto &it : apps_) {
        uint64_t id = it.first;
        const auto &app = it.second;

        snprintf(buffer, sizeof(buffer), "App: 0x%016" PRIx64 "\n", id);
        result.append(buffer);
        if (app->loaded) {
            snprintf(buffer, sizeof(buffer),
                "  Version: 0x%08" PRIx32 "\n"
                "  flashAddr: 0x%08" PRIx32 "\n"
                "  Running: %s\n",
                app->version,
                app->flashAddr,
                app->running ? "true" : "false");
            result.append(buffer);

            if (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
                snprintf(buffer, sizeof(buffer),
                    "  flashUse: %d\n"
                    "  CRC: 0x%08" PRIx32 "\n",
                    app->flashUse,
                    app->crc);
                result.append(buffer);
            }

            if (app->running) {
                snprintf(buffer, sizeof(buffer),
                    "  TID: %04x\n"
                    "  ramUse: %d\n",
                    app->tid,
                    app->ramUse);
                result.append(buffer);
            }

            if (app->chre) {
                snprintf(buffer, sizeof(buffer), "  CHRE: %d.%d\n",
                    app->chre_major, app->chre_minor);
                result.append(buffer);
            }
        }

        if (app->cached_napp) {
            snprintf(buffer, sizeof(buffer),
                "  Cached Version: 0x%08" PRIx32 "\n"
                "  Cached Start: %s\n"
                "  Cached CRC: 0x%08" PRIx32 "\n",
                app->cached_version,
                app->cached_start ? "true" : "false",
                app->cached_crc);
            result.append(buffer);
        }
    }
}

bool SystemComm::AppManager::saveApps()
{
    mkdir(CHRE_APP_DIR, CHRE_APP_DIR_PERMS);
    File saved_apps_file(CHRE_APP_SETTINGS, "w");
    std::shared_ptr<Json::Value> appsObject(new Json::Value);
    status_t err;

    if ((err = saved_apps_file.initCheck()) != OK) {
        ALOGW("saved_apps file open (w) failed %d (%s)",
              err,
              strerror(-err));
        return false;
    }

    for (auto &it : apps_) {
        uint64_t id = it.first;
        const auto &app = it.second;

        if (app->cached_napp) {
            char hexId[17];
            snprintf(hexId, sizeof(hexId), "%016" PRIX64, id);
            Json::Value array(Json::arrayValue);
            array[0] = app->cached_version;
            array[1] = app->cached_start;
            array[2] = app->cached_crc;
            (*appsObject)[hexId] = array;
        }
    }

    // Write the JSON string to disk.
    Json::StyledWriter writer;
    std::string serializedSettings(writer.write(*appsObject));
    size_t size = serializedSettings.size();
    if ((err = saved_apps_file.write(serializedSettings.c_str(), size)) != (ssize_t)size) {
        ALOGW("saved_apps file write failed %d (%s)",
              err,
              strerror(-err));
        return false;
    }

    return true;
}

bool SystemComm::AppManager::restoreApps()
{
    File saved_apps_file(CHRE_APP_SETTINGS, "r");
    std::shared_ptr<Json::Value> appsObject;
    status_t err;

    if ((err = saved_apps_file.initCheck()) != OK) {
        ALOGW("saved_apps file open (r) failed %d (%s)",
              err,
              strerror(-err));
        return false;
    }

    off64_t size = saved_apps_file.seekTo(0, SEEK_END);
    saved_apps_file.seekTo(0, SEEK_SET);

    if (size > 0) {
        char *buf = (char *)malloc(size);
        CHECK_EQ(saved_apps_file.read(buf, size), (ssize_t)size);

        std::string str(buf);
        std::shared_ptr<Json::Value> in(new Json::Value);
        Json::Reader reader;
        bool valid = reader.parse(str, *in);
        free(buf);

        if (valid && in->isObject()) {
            appsObject = in;
        }
    }

    if (appsObject == nullptr) {
        appsObject = std::shared_ptr<Json::Value>(new Json::Value(Json::objectValue));
    }

    Json::Value::Members apps = appsObject->getMemberNames();
    for (auto &it : apps) {
        Json::Value &val = (*appsObject)[it];
        if (val.isArray()) {
            uint32_t version = val[0].asUInt();
            uint32_t start = val[1].asUInt();
            uint32_t crc = val[2].asUInt();

            uint64_t id = strtoull(it.c_str(), nullptr, 16);
            apps_[id] = std::unique_ptr<AppData>(new AppData);
            apps_[id]->loaded = false;
            apps_[id]->running = false;
            apps_[id]->chre = false;
            apps_[id]->cached_napp = true;
            apps_[id]->cached_version = version;
            apps_[id]->cached_start = start;
            apps_[id]->cached_crc = crc;
        }
    }

    return true;
}

bool SystemComm::AppManager::eraseApps()
{
    for (auto it=apps_.begin(); it != apps_.end();) {
        if (!it->second->cached_napp)
            it = apps_.erase(it);
        else {
            it->second->loaded = false;
            it->second->running = false;
            it->second->chre = false;
            ++it;
        }
    }

    return true;
}

bool SystemComm::AppManager::writeApp(hub_app_name_t &appName, const uint8_t *data, int32_t len)
{
    mkdir(CHRE_APP_DIR, CHRE_APP_DIR_PERMS);
    char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];

    snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);

    int fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, CHRE_APP_FILE_PERMS);
    if (fd == -1)
        return false;

    if (write(fd, data, len) == len) {
        close(fd);
        return true;
    } else {
        close(fd);
        return false;
    }
}

int32_t SystemComm::AppManager::readApp(hub_app_name_t &appName, void **data)
{
    char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];

    snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);

    int32_t ret = -1;
    *data = nullptr;
    int fd = open(file, O_RDONLY);

    if (fd >= 0) {
        struct stat sb;
        if (fstat(fd, &sb) == 0) {
            *data = malloc(sb.st_size);
            if (*data != nullptr && read(fd, *data, sb.st_size) == sb.st_size)
                ret = sb.st_size;
            else {
                free(*data);
                *data = nullptr;
            }
        }
        close(fd);
    }
    return ret;
}

bool SystemComm::AppManager::cmpApp(hub_app_name_t &appName, const uint8_t *data, uint32_t len)
{
    char file[strlen(CHRE_APP_DIR) + strlen("/") + 16 + strlen(".napp") + 1];

    snprintf(file, sizeof(file), "%s/%016" PRIX64 ".napp", CHRE_APP_DIR, appName.id);

    if (!isAppLoaded(appName))
        return false;

    if ((!apps_[appName.id]->cached_napp) ||
        (apps_[appName.id]->crc != apps_[appName.id]->cached_crc))
        return false;

    bool success = false;
    int fd = open(file, O_RDONLY);

    if (fd >= 0) {
        struct stat sb;
        if (fstat(fd, &sb) == 0 && sb.st_size == len) {
            void *buf = malloc(len);
            if (buf != nullptr && read(fd, buf, sb.st_size) == sb.st_size && memcmp(data, buf, len) == 0)
                success = true;
            free(buf);
        }
        close(fd);
    }
    return success;
}

uint32_t SystemComm::AppManager::readNanohubAppInfo(MessageBuf &buf)
{
    hub_app_name_t name;

    uint8_t tag, len;
    uint32_t ramUse = 0;
    bool ramUseValid = true;

    // first tag must be the appid
    if (buf.getRoom() < 2 + sizeof(name.id)) {
        ALOGE("%s: failed to read object", __func__);
        return 0;
    }

    tag = buf.readU8();
    len = buf.readU8();
    if (tag != NANOHUB_HAL_APP_INFO_APPID || len != sizeof(name.id)) {
        ALOGE("%s: invalid first tag: %d", __func__, tag);
        return 0;
    }

    readAppName(buf, name);
    if (!isAppPresent(name)) {
        apps_[name.id] = std::unique_ptr<AppData>(new AppData);
        apps_[name.id]->loaded = false;
        apps_[name.id]->chre = false;
        apps_[name.id]->running = false;
        apps_[name.id]->cached_napp = false;
    }
    const auto &app = apps_[name.id];

    while (buf.getRoom() >= 2) {
        tag = buf.readU8();
        len = buf.readU8();
        if (buf.getRoom() >= len) {
            switch(tag) {
            case NANOHUB_HAL_APP_INFO_CRC:
                if (len == 0)
                    app->crc = 0;
                else if (len == sizeof(app->crc))
                    app->crc = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_TID:
                if (len == 0) {
                    app->tid = NANOHUB_TID_UNKNOWN;
                    ramUseValid = false;
                    app->loaded = true;
                    app->running = false;
                } else if (len  == sizeof(app->tid)) {
                    app->tid = buf.readU32();
                    app->loaded = true;
                    app->running = true;
                } else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_VERSION:
                if (len == sizeof(app->version))
                    app->version = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_ADDR:
                if (len == sizeof(app->flashAddr))
                    app->flashAddr = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_SIZE:
                if (len == 0)
                    app->flashUse = NANOHUB_MEM_SZ_UNKNOWN;
                else if (len == sizeof(app->flashUse))
                    app->flashUse = buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_HEAP:
            case NANOHUB_HAL_APP_INFO_DATA:
            case NANOHUB_HAL_APP_INFO_BSS:
                if (len == 0)
                    ramUseValid = false;
                else if (len == sizeof(uint32_t))
                    ramUse += buf.readU32();
                else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_CHRE_MAJOR:
                if (len == 0)
                    app->chre = false;
                else if (len == sizeof(app->chre_major)) {
                    app->chre = true;
                    app->chre_major = buf.readU8();
                } else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_CHRE_MINOR:
                if (len == 0)
                    app->chre = false;
                else if (len == sizeof(app->chre_minor)) {
                    app->chre = true;
                    app->chre_minor = buf.readU8();
                } else
                    buf.readRaw(len);
                break;
            case NANOHUB_HAL_APP_INFO_END:
                if (len != 0 || buf.getRoom() != 0) {
                    ALOGE("%s: failed to read object", __func__);
                    return 0;
                }
                break;
            default:
                ALOGI("%s: unsupported tag: %d", __func__, tag);
                buf.readRaw(len);
                break;
            }
        } else {
            ALOGE("%s: failed to read object", __func__);
            return 0;
        }
    }

    if (buf.getRoom() != 0) {
        ALOGE("%s: failed to read object", __func__);
        return 0;
    }

    if (ramUseValid)
        app->ramUse = ramUse;
    else
        app->ramUse = NANOHUB_MEM_SZ_UNKNOWN;

    return app->flashAddr +
        (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN ? ((app->flashUse+3)&~3) : 4);
}

void SystemComm::AppManager::sendAppInfoToApp(uint32_t transactionId) {
    std::vector<hub_app_info> appInfo;
    for (auto &it : apps_) {
        uint64_t id = it.first;
        const auto &app = it.second;

        // TODO: Still have some non-chre apps that need to be reported
        // if (!app->chre || !app->running || app->flashUse == NANOHUB_MEM_SZ_UNKNOWN)
        if (!app->running || app->flashUse == NANOHUB_MEM_SZ_UNKNOWN)
            continue;

        hub_app_info info;
        info.app_name = { .id = id };
        info.version = app->version;
        info.num_mem_ranges = 0;
        if (app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
            mem_range_t &range = info.mem_usage[info.num_mem_ranges++];
            range.type = HUB_MEM_TYPE_MAIN;
            range.total_bytes = app->flashUse;
        }
        if (app->ramUse != NANOHUB_MEM_SZ_UNKNOWN) {
            mem_range_t &range = info.mem_usage[info.num_mem_ranges++];
            range.type = HUB_MEM_TYPE_RAM;
            range.total_bytes = app->ramUse;
        }

        appInfo.push_back(info);
    }
    sendToApp(CONTEXT_HUB_QUERY_APPS, transactionId,
              static_cast<const void *>(appInfo.data()),
              appInfo.size() * sizeof(appInfo[0]));
}

int SystemComm::AppManager::getAppsToStart(std::vector<hub_app_name_t> &apps)
{
    int cnt = 0;
    apps.clear();

    for (auto &it : apps_) {
        uint64_t id = it.first;
        const auto &app = it.second;

        if (app->cached_napp && app->cached_start && app->loaded &&
            !app->running && app->flashUse != NANOHUB_MEM_SZ_UNKNOWN) {
            apps.push_back({ .id = id });
            cnt++;
        }
    }

    return cnt;
}

int SystemComm::doHandleRx(uint64_t appId, uint32_t transactionId, const char *data, int len, bool chre)
{
    bool reboot = false;
    uint32_t rebootStatus;
    //we only care for messages from HostIF
    if (appId != mHostIfAppName.id)
        return 1;

    //they must all be at least 1 byte long
    if (!len) {
        return -EINVAL;
    }
    MessageBuf buf(data, len);
    if (NanoHub::messageTracingEnabled()) {
        dumpBuffer("SYS -> HAL", mHostIfAppName, transactionId, 0, buf.getData(), buf.getSize());
    }
    int status = mSessions.handleRx(buf, transactionId, mAppManager, chre, reboot, rebootStatus);
    if (status) {
        // provide default handler for any system message, that is not properly handled
        dumpBuffer(status > 0 ? "HAL (not handled)" : "HAL (error)",
                   mHostIfAppName, transactionId, 0, buf.getData(), buf.getSize(), status);
        status = status > 0 ? 0 : status;
    }
    if (reboot) {
        hub_message_t msg =
        {
            .app_name.id = appId,
            .message_type = CONTEXT_HUB_START_APPS,
            .message_len = sizeof(rebootStatus),
            .message = &rebootStatus,
        };

        status = doHandleTx(&msg, 0xFFFFFFFF);
    }

    return status;
}

void SystemComm::doDumpAppInfo(std::string &result)
{
    mAppManager.dumpAppInfo(result);
}

int SystemComm::SessionManager::handleRx(MessageBuf &buf, uint32_t transactionId, AppManager &appManager, bool chre, bool &reboot, uint32_t &rebootStatus)
{
    int status = 1;
    std::unique_lock<std::mutex> lk(lock);

    // pass message to all active sessions, in arbitrary order
    // 1st session that handles the message terminates the loop
    for (auto pos = sessions_.begin(); pos != sessions_.end() && status > 0; next(pos)) {
        if (!isActive(pos)) {
            continue;
        }
        Session *session = pos->second;
        status = session->handleRx(buf, transactionId, appManager, chre);
        if (status < 0) {
            session->complete();
        }
    }

    NanohubRsp rsp(buf, transactionId, chre);
    if (rsp.mCmd == NANOHUB_HAL_SYS_MGMT) {
        uint8_t cmd = buf.readU8();

        if (cmd == NANOHUB_HAL_SYS_MGMT_REBOOT) {
            // if this is reboot notification, kill all sessions
            for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
                if (!isActive(pos)) {
                    continue;
                }
                Session *session = pos->second;
                session->abort(-EINTR);
            }
            lk.unlock();
            // log the reboot event, if not handled
            if (status > 0) {
                ALOGW("Nanohub reboot status [UNSOLICITED]: %08" PRIX32, rsp.mStatus);
                status = 0;
            }
            reboot = true;
            rebootStatus = rsp.mStatus;
        }
    }

    return status;
}

int SystemComm::SessionManager::setup_and_add(int id, Session *session, const hub_message_t *appMsg, uint32_t transactionId, AppManager &appManager)
{
    std::lock_guard<std::mutex> _l(lock);

    // scan sessions to release those that are already done
    for (auto pos = sessions_.begin(); pos != sessions_.end(); next(pos)) {
        continue;
    }

    if (sessions_.count(id) == 0 && !session->isRunning()) {
        sessions_[id] = session;
        int ret = session->setup(appMsg, transactionId, appManager);
        if (ret < 0) {
            session->complete();
        }
        return ret;
    }
    return -EBUSY;
}

int SystemComm::doHandleTx(const hub_message_t *appMsg, uint32_t transactionId)
{
    int status = 0;

    switch (appMsg->message_type) {
    case CONTEXT_HUB_LOAD_APP:
        if (!mKeySession.haveKeys()) {
            status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mKeySession, appMsg, transactionId, mAppManager);
            if (status < 0) {
                break;
            }
            mKeySession.wait();
            status = mKeySession.getStatus();
            if (status < 0) {
                break;
            }
        }
        status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg, transactionId, mAppManager);
        break;
    case CONTEXT_HUB_APPS_ENABLE:
    case CONTEXT_HUB_APPS_DISABLE:
    case CONTEXT_HUB_UNLOAD_APP:
        // all APP-modifying commands share session key, to ensure they can't happen at the same time
        status = mSessions.setup_and_add(CONTEXT_HUB_LOAD_APP, &mAppMgmtSession, appMsg, transactionId, mAppManager);
        break;

    case CONTEXT_HUB_QUERY_APPS:
        mAppManager.sendAppInfoToApp(transactionId);
        break;

    case CONTEXT_HUB_QUERY_MEMORY:
        status = mSessions.setup_and_add(CONTEXT_HUB_QUERY_MEMORY, &mMemInfoSession, appMsg, transactionId, mAppManager);
        break;

    case CONTEXT_HUB_START_APPS:
        status = mSessions.setup_and_add(CONTEXT_HUB_START_APPS, &mAppMgmtSession, appMsg, transactionId, mAppManager);
        break;

    default:
        ALOGW("Unknown os message type %u\n", appMsg->message_type);
        return -EINVAL;
    }

   return status;
}

}; // namespace nanohub

}; // namespace android
