// Copyright (C) 2020 Denis Shienkov <denis.shienkov@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#pragma once

#include "uvscdatatypes.h"

#include <QDir>
#include <QLibrary>

#if defined(Q_OS_WIN)
#include <qt_windows.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

// Maximum number of clients UVSC can support.
#define UVSC_MAX_CLIENTS 10
// Maximum string size.
#define UVSC_MAX_API_STR_SIZE 1024
// Auto port.
#define UVSC_PORT_AUTO 0
// Minimum auto port value.
#define UVSC_MIN_AUTO_PORT 1
// Maximum auto port value.
#define UVSC_MAX_AUTO_PORT 65535

// UVSC status codes.
enum UVSC_STATUS {
    UVSC_STATUS_SUCCESS = 0,
    UVSC_STATUS_FAILED = 1,
    UVSC_STATUS_NOT_SUPPORTED = 2,
    UVSC_STATUS_NOT_INIT = 3,
    UVSC_STATUS_TIMEOUT = 4,
    UVSC_STATUS_INVALID_CONTEXT = 5,
    UVSC_STATUS_INVALID_PARAM = 6,
    UVSC_STATUS_BUFFER_TOO_SMALL = 7,
    UVSC_STATUS_CALLBACK_IN_USE = 8,
    UVSC_STATUS_COMMAND_ERROR = 9,
    UVSC_STATUS_END
};

// uVision run modes.
enum UVSC_RUNMODE {
    UVSC_RUNMODE_NORMAL = 0,
    UVSC_RUNMODE_LABVIEW = 1,
    UVSC_RUNMODE_END = 2,
};

// Progress bar operations.
enum UVSC_PBAR {
    UVSC_PBAR_INIT = 0,
    UVSC_PBAR_TEXT = 1,
    UVSC_PBAR_POS = 2,
    UVSC_PBAR_STOP = 3,
};

// UVSC callback types.
enum UVSC_CB_TYPE {
    UVSC_CB_ERROR = 0,
    UVSC_CB_ASYNC_MSG = 1,
    UVSC_CB_DISCONNECTED = 2,
    UVSC_CB_BUILD_OUTPUT_MSG = 3,
    UVSC_CB_PROGRESS_BAR_MSG = 4,
    UVSC_CB_CMD_OUTPUT_MSG = 5,
};

// UVSC callback data.
union UVSC_CB_DATA {
    UVSOCK_CMD msg;
    UVSC_STATUS error;
    qint32 connectionHandle;
};
static_assert(sizeof(UVSC_CB_DATA) == 32800, "UVSC_CB_DATA size is not 32800 bytes");

// UVSC callback function.
typedef void (*uvsc_cb)(void *cb_custom, UVSC_CB_TYPE type, UVSC_CB_DATA *data);

// UVSC logging callback function.
typedef void (*log_cb)(const char *msg, int msgLen);

// Macro to generate functions && symbols.
#define GENERATE_SYMBOL_VARIABLE(returnType, symbolName, ...) \
    typedef returnType (*fp_##symbolName)(__VA_ARGS__); \
    static fp_##symbolName symbolName;

// Macro to resolve functions && symbols.
#define RESOLVE_SYMBOL(symbolName) \
    symbolName = reinterpret_cast<fp_##symbolName>(uvscLibrary->resolve(#symbolName)); \
    if (!symbolName) \
        return false;

// Control functions.
GENERATE_SYMBOL_VARIABLE(void, UVSC_Version, quint32 *, quint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_Init, qint32, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_UnInit, void)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_OpenConnection, qint8 *, qint32 *, qint32 *, \
                         qint8 *, UVSC_RUNMODE, uvsc_cb, void *, qint8 *, quint8, log_cb)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_CloseConnection, qint32, quint8)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_ConnHandleFromConnName, qint8 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GetLastError, qint32, \
                         UV_OPERATION *, UV_STATUS *, qint8 *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_LogControl, qint32, quint8, quint8)
// Messaging functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_SET_OPTIONS, qint32, UVSOCK_OPTIONS *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_UVSOCK_VERSION, qint32, qint32 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_EXT_VERSION, qint32, EXTVERS *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_HIDE, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_SHOW, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_MAXIMIZE, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_MINIMIZE, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_RESTORE, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_UI_LOCK, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_UI_UNLOCK, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GEN_CHECK_LICENSE, qint32, UVLICINFO *)
// Project functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_LOAD, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_CLOSE, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ADD_FILE, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_DEL_FILE, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ENUM_FILES, qint32, SSTR *, \
                         qint32, SSTR *, qint32 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ADD_GROUP, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_DEL_GROUP, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_SET_TARGET, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_SET_OUTPUTNAME, qint32, PRJDATA *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ENUM_GROUPS, qint32, \
                         SSTR *, qint32 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ENUM_TARGETS, qint32, \
                         SSTR *, qint32 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_ACTIVE_FILES, qint32, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_BUILD, qint32, quint8)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_BUILD_CANCEL, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_CLEAN, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_FLASH_DOWNLOAD, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_GET_OPTITEM, qint32, TRNOPT *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_SET_OPTITEM, qint32, TRNOPT *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_GET_DEBUG_TARGET, qint32, DBGTGTOPT *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_SET_DEBUG_TARGET, qint32, DBGTGTOPT *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_CMD_PROGRESS, qint32, PGRESS *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_GET_OUTPUTNAME, qint32, \
                         iPATHREQ *, SSTR *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_PRJ_GET_CUR_TARGET, qint32, \
                         iPATHREQ *, SSTR *, qint32)
// Debug functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENTER, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EXIT, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_START_EXECUTION, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_RUN_TO_ADDRESS, qint32, quint64)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STOP_EXECUTION, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STATUS, qint32, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_HLL, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_HLL_N, qint32, quint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_INSTRUCTION, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_INSTRUCTION_N, qint32, quint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_INTO, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_INTO_N, qint32, quint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_STEP_OUT, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_RESET, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_MEM_READ, qint32, AMEM *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_MEM_WRITE, qint32, AMEM *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_CREATE_BP, qint32, \
                         BKPARM *, qint32, BKRSP *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_CHANGE_BP, qint32, \
                         BKCHG *, qint32, BKRSP *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUMERATE_BP, qint32, \
                         BKRSP *, qint32 *, qint32*)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_SERIAL_GET, qint32, SERIO *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_SERIAL_PUT, qint32, SERIO *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_CALC_EXPRESSION, qint32, VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EVAL_WATCH_EXPRESSION, qint32, \
                         VSET *, qint32, VARINFO *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_REMOVE_WATCH_EXPRESSION, qint32, \
                         VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_VARIABLES, qint32, \
                         IVARENUM *, VARINFO *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_VARIABLE_SET, qint32, VARVAL *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_VTR, qint32, \
                         iVTRENUM *, AVTR *, qint32 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_VTR_GET, qint32, VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_VTR_SET, qint32, VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ITM_REGISTER, qint32, ITMOUT *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ITM_UNREGISTER, qint32, ITMOUT *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_STACK, qint32, \
                         iSTKENUM *, STACKENUM *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_TASKS, qint32, TASKENUM *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_MENUS, qint32, \
                         MENUID *, MENUENUM *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_MENU_EXEC, qint32, MENUID *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ADR_TOFILELINE, qint32, \
                         ADRMTFL *, AFLMAP *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ADR_SHOWCODE, qint32, iSHOWSYNC *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_POWERSCALE_SHOWCODE, qint32, UVSC_PSTAMP *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_WAKE, qint32, iINTERVAL *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_SLEEP, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EXEC_CMD, qint32, EXECCMD *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EVAL_EXPRESSION_TO_STR, qint32, \
                         VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_FILELINE_TO_ADR, qint32, \
                         AFLMAP *, qint32, VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_REGISTER_GROUPS, qint32, \
                         SSTR *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_ENUM_REGISTERS, qint32, \
                         REGENUM *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_READ_REGISTERS, qint32, qint8 *, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_REGISTER_SET, qint32, VSET *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_DSM_READ, qint32, AMEM *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EVTR_REGISTER, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EVTR_UNREGISTER, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_DBG_EVTR_ENUMSCVDFILES, qint32, \
                         SSTR *, qint32 *)
// Build output functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GetBuildOutputSize, qint32, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GetBuildOutput, qint32, qint8 *, qint32)
// Command output functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GetCmdOutputSize, qint32, qint32 *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_GetCmdOutput, qint32, qint8 *, qint32)
// Queue functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_ReadBuildQ, qint32, qint8 *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_ReadPBarQ, qint32, \
                         UVSC_PBAR *, qint8 *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_ReadAsyncQ, qint32, \
                         qint32, UVSOCK_CMD *, qint32)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_FlushAsyncQ, qint32, qint32)
// Advanced functions.
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_TxRxRaw, qint32, UVSOCK_CMD *)
GENERATE_SYMBOL_VARIABLE(UVSC_STATUS, UVSC_CreateMsg, UVSOCK_CMD *, UV_OPERATION, \
                         qint32, const void *)

inline bool resolveUvscSymbols(const QDir &dir, QLibrary *uvscLibrary)
{
    if (!uvscLibrary->isLoaded()) {
#ifdef Q_PROCESSOR_X86_64
        uvscLibrary->setFileName(dir.absoluteFilePath(QStringLiteral("uvsc64")));
#else
        uvscLibrary->setFileName(dir.absoluteFilePath(QStringLiteral("uvsc")));
#endif
        if (!uvscLibrary->load())
            return false;
    }

    // Control functions.
    RESOLVE_SYMBOL(UVSC_Version)
    RESOLVE_SYMBOL(UVSC_Init)
    RESOLVE_SYMBOL(UVSC_UnInit)
    RESOLVE_SYMBOL(UVSC_OpenConnection)
    RESOLVE_SYMBOL(UVSC_CloseConnection)
    RESOLVE_SYMBOL(UVSC_ConnHandleFromConnName)
    RESOLVE_SYMBOL(UVSC_GetLastError)
    RESOLVE_SYMBOL(UVSC_LogControl)
    // Messaging functions.
    RESOLVE_SYMBOL(UVSC_GEN_SET_OPTIONS)
    RESOLVE_SYMBOL(UVSC_GEN_UVSOCK_VERSION)
    RESOLVE_SYMBOL(UVSC_GEN_EXT_VERSION)
    RESOLVE_SYMBOL(UVSC_GEN_HIDE)
    RESOLVE_SYMBOL(UVSC_GEN_SHOW)
    RESOLVE_SYMBOL(UVSC_GEN_MAXIMIZE)
    RESOLVE_SYMBOL(UVSC_GEN_MINIMIZE)
    RESOLVE_SYMBOL(UVSC_GEN_RESTORE)
    RESOLVE_SYMBOL(UVSC_GEN_UI_LOCK)
    RESOLVE_SYMBOL(UVSC_GEN_UI_UNLOCK)
    RESOLVE_SYMBOL(UVSC_GEN_CHECK_LICENSE)
    // Project functions.
    RESOLVE_SYMBOL(UVSC_PRJ_LOAD)
    RESOLVE_SYMBOL(UVSC_PRJ_CLOSE)
    RESOLVE_SYMBOL(UVSC_PRJ_ADD_FILE)
    RESOLVE_SYMBOL(UVSC_PRJ_DEL_FILE)
    RESOLVE_SYMBOL(UVSC_PRJ_ENUM_FILES)
    RESOLVE_SYMBOL(UVSC_PRJ_ADD_GROUP)
    RESOLVE_SYMBOL(UVSC_PRJ_DEL_GROUP)
    RESOLVE_SYMBOL(UVSC_PRJ_SET_TARGET)
    RESOLVE_SYMBOL(UVSC_PRJ_SET_OUTPUTNAME)
    RESOLVE_SYMBOL(UVSC_PRJ_ENUM_GROUPS)
    RESOLVE_SYMBOL(UVSC_PRJ_ENUM_TARGETS)
    RESOLVE_SYMBOL(UVSC_PRJ_ACTIVE_FILES)
    RESOLVE_SYMBOL(UVSC_PRJ_BUILD)
    RESOLVE_SYMBOL(UVSC_PRJ_BUILD_CANCEL)
    RESOLVE_SYMBOL(UVSC_PRJ_CLEAN)
    RESOLVE_SYMBOL(UVSC_PRJ_FLASH_DOWNLOAD)
    RESOLVE_SYMBOL(UVSC_PRJ_GET_OPTITEM)
    RESOLVE_SYMBOL(UVSC_PRJ_SET_OPTITEM)
    RESOLVE_SYMBOL(UVSC_PRJ_GET_DEBUG_TARGET)
    RESOLVE_SYMBOL(UVSC_PRJ_SET_DEBUG_TARGET)
    RESOLVE_SYMBOL(UVSC_PRJ_CMD_PROGRESS)
    RESOLVE_SYMBOL(UVSC_PRJ_GET_OUTPUTNAME)
    RESOLVE_SYMBOL(UVSC_PRJ_GET_CUR_TARGET)
    // Debug functions.
    RESOLVE_SYMBOL(UVSC_DBG_ENTER)
    RESOLVE_SYMBOL(UVSC_DBG_EXIT)
    RESOLVE_SYMBOL(UVSC_DBG_START_EXECUTION)
    RESOLVE_SYMBOL(UVSC_DBG_RUN_TO_ADDRESS)
    RESOLVE_SYMBOL(UVSC_DBG_STOP_EXECUTION)
    RESOLVE_SYMBOL(UVSC_DBG_STATUS)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_HLL)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_HLL_N)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_INSTRUCTION)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_INSTRUCTION_N)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_INTO)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_INTO_N)
    RESOLVE_SYMBOL(UVSC_DBG_STEP_OUT)
    RESOLVE_SYMBOL(UVSC_DBG_RESET)
    RESOLVE_SYMBOL(UVSC_DBG_MEM_READ)
    RESOLVE_SYMBOL(UVSC_DBG_MEM_WRITE)
    RESOLVE_SYMBOL(UVSC_DBG_CREATE_BP)
    RESOLVE_SYMBOL(UVSC_DBG_CHANGE_BP)
    RESOLVE_SYMBOL(UVSC_DBG_ENUMERATE_BP)
    RESOLVE_SYMBOL(UVSC_DBG_SERIAL_GET)
    RESOLVE_SYMBOL(UVSC_DBG_SERIAL_PUT)
    RESOLVE_SYMBOL(UVSC_DBG_CALC_EXPRESSION)
    RESOLVE_SYMBOL(UVSC_DBG_EVAL_WATCH_EXPRESSION)
    RESOLVE_SYMBOL(UVSC_DBG_REMOVE_WATCH_EXPRESSION)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_VARIABLES)
    RESOLVE_SYMBOL(UVSC_DBG_VARIABLE_SET)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_VTR)
    RESOLVE_SYMBOL(UVSC_DBG_VTR_GET)
    RESOLVE_SYMBOL(UVSC_DBG_VTR_SET)
    RESOLVE_SYMBOL(UVSC_DBG_ITM_REGISTER)
    RESOLVE_SYMBOL(UVSC_DBG_ITM_UNREGISTER)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_STACK)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_TASKS)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_MENUS)
    RESOLVE_SYMBOL(UVSC_DBG_MENU_EXEC)
    RESOLVE_SYMBOL(UVSC_DBG_ADR_TOFILELINE)
    RESOLVE_SYMBOL(UVSC_DBG_ADR_SHOWCODE)
    RESOLVE_SYMBOL(UVSC_POWERSCALE_SHOWCODE)
    RESOLVE_SYMBOL(UVSC_DBG_WAKE)
    RESOLVE_SYMBOL(UVSC_DBG_SLEEP)
    RESOLVE_SYMBOL(UVSC_DBG_EXEC_CMD)
    RESOLVE_SYMBOL(UVSC_DBG_EVAL_EXPRESSION_TO_STR)
    RESOLVE_SYMBOL(UVSC_DBG_FILELINE_TO_ADR)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_REGISTER_GROUPS)
    RESOLVE_SYMBOL(UVSC_DBG_ENUM_REGISTERS)
    RESOLVE_SYMBOL(UVSC_DBG_READ_REGISTERS)
    RESOLVE_SYMBOL(UVSC_DBG_REGISTER_SET)
    RESOLVE_SYMBOL(UVSC_DBG_DSM_READ)
    RESOLVE_SYMBOL(UVSC_DBG_EVTR_REGISTER)
    RESOLVE_SYMBOL(UVSC_DBG_EVTR_UNREGISTER)
    RESOLVE_SYMBOL(UVSC_DBG_EVTR_ENUMSCVDFILES)
    // Build output functions.
    RESOLVE_SYMBOL(UVSC_GetBuildOutputSize)
    RESOLVE_SYMBOL(UVSC_GetBuildOutput)
    // Command output functions.
    RESOLVE_SYMBOL(UVSC_GetCmdOutputSize)
    RESOLVE_SYMBOL(UVSC_GetCmdOutput)
    // Queue functions.
    RESOLVE_SYMBOL(UVSC_ReadBuildQ)
    RESOLVE_SYMBOL(UVSC_ReadPBarQ)
    RESOLVE_SYMBOL(UVSC_ReadAsyncQ)
    RESOLVE_SYMBOL(UVSC_FlushAsyncQ)
    // Advanced functions.
    RESOLVE_SYMBOL(UVSC_TxRxRaw)
    RESOLVE_SYMBOL(UVSC_CreateMsg)
    return true;
}

#ifdef __cplusplus
}
#endif
