Skip to content

File ManusSDKCalibration.cpp

File List > api > cppSDK > SDKBase > ManusSDKCalibration.cpp

Go to the documentation of this file

// This file is to allow us to use Calibration functionality from in Manus Core using the SDK DLL. //
#include "ManusSDKTypes.h"
#include "ManusSDKExtendedTypes.h"
#include "ManusSDKExtendedTypeInitializers.h"

#include "ManusSDK.h"
#include "ManusSDKExtended.h"

#include "PlatformSpecific.hpp"

#ifndef _MANUS_CORE_LITE

SDKReturnCode Calibration_Initialize()
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_Start()
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_ShutDown()
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_RegisterCallbackForUserGloveProfile(UserGloveProfileCallback_t p_UserGloveProfileCallback)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_AddGloveData(Glove* p_GloveData)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_AddDeviceLandscape(DeviceLandscape* p_DeviceLandscape)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_AddUserLandscape(UserLandscape* p_UserLandscape)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationStart(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationStop(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationFinish(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationGetNumberOfSteps(GloveCalibrationArgs p_CalibrationArgs, uint32_t& p_NumberOfSteps)
{
    p_NumberOfSteps = 0;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationGetStepData(GloveCalibrationStepArgs p_CalibrationStepArgs, GloveCalibrationStepData& p_Data)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationStartStep(GloveCalibrationStepArgs p_CalibrationStepArgs, bool& p_Result)
{
    p_Result = false;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GetGloveCalibrationSize(uint32_t p_GloveId, uint32_t* p_Size)
{
    *p_Size = 0;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GetGloveCalibrationSizeForUser(uint32_t p_UserId, Side p_Side, GloveProfileType p_ProfileType, uint32_t* p_Size)
{
    *p_Size = 0;
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GetGloveCalibrationBytes(unsigned char* p_CalibrationBytes, uint32_t p_BytesLength)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_SetGloveCalibration(uint32_t p_GloveId, unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_SetGloveCalibrationForUser(uint32_t p_UserId, unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GetGloveCalibrationFromBytes(unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response, GloveProfile* p_GloveProfile)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

SDKReturnCode Calibration_GloveCalibrationToBytesAndGetSize(const GloveProfile* p_GloveProfilePtr, uint32_t* p_Size)
{
    return SDKReturnCode::SDKReturnCode_FunctionNotAvailable;
}

#else

#include "CoreLite/CoreLite.hpp"

#include "CoreLite/Definitions/Common.hpp"
#include "CoreLite/Definitions/Ergonomics.hpp"
#include "CoreLite/Definitions/Gestures.hpp"
#include "CoreLite/Definitions/Landscape.hpp"
#include "CoreLite/Definitions/Transform.hpp"
#include "CoreLite/Definitions/Node.hpp"
#include "CoreLite/Definitions/SkeletonOutputStream.hpp"
#include "CoreLite/Definitions/SkeletonOutput.hpp"
#include "CoreLite/Definitions/Skeleton.hpp"
#include "CoreLite/Definitions/Version.hpp"
#include "CoreLite/Definitions/Session.hpp"
#include "CoreLite/Definitions/Calibration/GloveProfile.hpp"
#include "CoreLite/Definitions/Calibration/CalibrationData.hpp"
#include "CoreLite/Definitions/Settings/BaseSettings.hpp"
#include "CoreLite/Definitions/Settings/CalibrationSettings.hpp"

#include "CoreLite/FileLoader/GloveProfileLoader.hpp"

#include "CoreLite/Service.hpp"
#include "CoreLite/Calibration/CalibrationService.hpp"

#include "CoreLite/Calibration/Command/BaseCalibrationCommand.hpp"
#include "CoreLite/Calibration/Command/CalibrationCommands.hpp"
#include "CoreLite/Calibration/Command/GloveProfileCommands.hpp"

#include "CoreLite/CoreLiteConversion.hpp"

void Calibration_OnUserProfileCallback(manusid p_UserID, const CoreLite::Definitions::Calibration::GloveProfile* p_GloveProfile);

std::unique_ptr<CoreLite::Calibration::CalibrationService> s_CalibrationService;

std::mutex s_GloveProfileMutex;
std::vector<uint8_t> s_RequestedGloveProfileBytes;

UserGloveProfileCallback_t m_RegisteredUserProfileCallback = nullptr;

SDKReturnCode Calibration_Initialize()
{
    if (!s_CalibrationService)
    {
        CoreLite::Definitions::Settings::BaseSettings::SetToDefaultDirectory();
        CoreLite::Definitions::Settings::BaseSettings::SetSettingsFileName(CoreLite::Definitions::Settings::SettingsType::Calibration, "ManusCore.GloveCalibrations");

        s_CalibrationService = std::make_unique<CoreLite::Calibration::CalibrationService>();
        s_CalibrationService->RegisterOnUserProfileUpdated(Calibration_OnUserProfileCallback);
        return SDKReturnCode::SDKReturnCode_Success;
    }
    return SDKReturnCode::SDKReturnCode_FunctionCalledAtWrongTime;
}

SDKReturnCode Calibration_Start()
{
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    s_CalibrationService->Start();
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_ShutDown()
{
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    s_CalibrationService->Stop(true);
    s_CalibrationService.reset();
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_RegisterCallbackForUserGloveProfile(UserGloveProfileCallback_t p_UserGloveProfileCallback)
{
    m_RegisteredUserProfileCallback = p_UserGloveProfileCallback;
    return SDKReturnCode::SDKReturnCode_Success;
}

void Calibration_OnUserProfileCallback(manusid p_UserID, const CoreLite::Definitions::Calibration::GloveProfile* p_GloveProfile)
{
    if (p_GloveProfile == nullptr)
        return;

    if (m_RegisteredUserProfileCallback == nullptr)
        return;

    GloveProfile t_Profile;
    GloveProfile_Init(&t_Profile);
    CoreLite::SDKConversion::GloveProfileToWrapper(p_GloveProfile, t_Profile);

    m_RegisteredUserProfileCallback(p_UserID, &t_Profile);
}

SDKReturnCode Calibration_AddGloveData(Glove* p_GloveData)
{
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }

    CoreLite::Definitions::Glove* t_GloveData = new CoreLite::Definitions::Glove(CoreLite::Definitions::GloveInfo(0, CoreLite::Definitions::Side::Invalid, CoreLite::Definitions::DeviceFamilyType::Unknown), nullptr);
    if (!CoreLite::SDKConversion::GloveFromWrapper(*p_GloveData, *t_GloveData))
        return SDKReturnCode_Error;

    s_CalibrationService->CloneAndAddGloveData(t_GloveData);
    delete t_GloveData;

    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_AddDeviceLandscape(DeviceLandscape* p_DeviceLandscape)
{
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }

    CoreLite::Definitions::DeviceLandscape* t_LandscapeData = new CoreLite::Definitions::DeviceLandscape("");
    CoreLite::SDKConversion::DeviceLandscapeFromWrapper(*p_DeviceLandscape, *t_LandscapeData);

    s_CalibrationService->CloneAndAddLandscape(t_LandscapeData);
    delete t_LandscapeData;

    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_AddUserLandscape(UserLandscape* p_UserLandscape)
{
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }

    CoreLite::Definitions::UserLandscape* t_LandscapeData;
    if (!CoreLite::SDKConversion::UserLandscapeFromWrapper(*p_UserLandscape, &t_LandscapeData))
        return SDKReturnCode::SDKReturnCode_Error;

    s_CalibrationService->CloneAndAddLandscape(t_LandscapeData);
    delete t_LandscapeData;

    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationStart(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    manusid t_GloveID = manusid(p_CalibrationArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationStart>(t_GloveID);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Result = t_Command->GetResult() == CoreLite::CommandResult::Success;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationStop(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    manusid t_GloveID = manusid(p_CalibrationArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationStop>(t_GloveID);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Result = t_Command->GetResult() == CoreLite::CommandResult::Success;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationFinish(GloveCalibrationArgs p_CalibrationArgs, bool& p_Result)
{
    p_Result = false;
    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    manusid t_GloveID = manusid(p_CalibrationArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationFinish>(t_GloveID);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Result = t_Command->GetResult() == CoreLite::CommandResult::Success;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationGetNumberOfSteps(GloveCalibrationArgs p_CalibrationArgs, uint32_t& p_NumberOfSteps)
{
    p_NumberOfSteps = 0;

    if (!s_CalibrationService) { return SDKReturnCode::SDKReturnCode_SdkNotAvailable; }
    manusid t_GloveID = manusid(p_CalibrationArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationGetNumberOfSteps>(t_GloveID);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_NumberOfSteps = t_Command->GetNumberOfSteps();
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationGetStepData(GloveCalibrationStepArgs p_CalibrationStepArgs, GloveCalibrationStepData& p_Data)
{
    GloveCalibrationStepData_Init(&p_Data);
    manusid t_GloveID = manusid(p_CalibrationStepArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationGetStepData>(t_GloveID, p_CalibrationStepArgs.stepIndex);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    CoreLite::SDKConversion::CopyGloveCalibrationStepDataToWrapper(t_Command->GetStepData(), p_Data);
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationStartStep(GloveCalibrationStepArgs p_CalibrationStepArgs, bool& p_Result)
{
    p_Result = false;
    manusid t_GloveID = manusid(p_CalibrationStepArgs.gloveId);

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::CalibrationStartStep>(t_GloveID, p_CalibrationStepArgs.stepIndex);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Result = t_Command->GetResult() == CoreLite::CommandResult::Success;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GetGloveCalibrationSize(uint32_t p_GloveId, uint32_t* p_Size)
{
    auto t_Command = std::make_shared<CoreLite::Calibration::Command::GloveProfileGet>(p_GloveId);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    auto* t_Profile = t_Command->GetGloveProfile();

    std::vector<uint8> t_GloveProfileBytes;
    if (!CoreLite::FileLoader::GloveProfileLoader::ToFile(t_Profile, t_GloveProfileBytes))
    {
        delete t_Profile;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    *p_Size = t_GloveProfileBytes.size();

    {
        const std::lock_guard<std::mutex> t_ManagedMutexLock(s_GloveProfileMutex);
        s_RequestedGloveProfileBytes = t_GloveProfileBytes;
    }

    delete t_Profile;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GetGloveCalibrationSizeForUser(uint32_t p_UserId, Side p_Side, GloveProfileType p_ProfileType, uint32_t* p_Size)
{
    // Convert to SDK Types
    CoreLite::Definitions::Side t_Side;
    if (!CoreLite::SDKConversion::SideFromWrapper(p_Side, t_Side))\
        return SDKReturnCode::SDKReturnCode_InvalidArgument;

    CoreLite::Definitions::Calibration::GloveProfileType t_ProfileType;
    if (!CoreLite::SDKConversion::GloveProfileTypeFromWrapper(p_ProfileType, t_ProfileType))
        return SDKReturnCode::SDKReturnCode_InvalidArgument;

    // Run profile get command
    auto t_Command = std::make_shared<CoreLite::Calibration::Command::GloveProfileGetForUser>(p_UserId, t_Side, t_ProfileType);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    auto* t_Profile = t_Command->GetGloveProfile();

    std::vector<uint8> t_GloveProfileBytes;
    if (!CoreLite::FileLoader::GloveProfileLoader::ToFile(t_Profile, t_GloveProfileBytes))
    {
        delete t_Profile;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    *p_Size = t_GloveProfileBytes.size();

    {
        const std::lock_guard<std::mutex> t_ManagedMutexLock(s_GloveProfileMutex);
        s_RequestedGloveProfileBytes = t_GloveProfileBytes;
    }

    delete t_Profile;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GetGloveCalibrationBytes(unsigned char* p_CalibrationBytes, uint32_t p_BytesLength)
{
    const std::lock_guard<std::mutex> t_ManagedMutexLock(s_GloveProfileMutex);

    if (s_RequestedGloveProfileBytes.size() != p_BytesLength)
        return SDKReturnCode::SDKReturnCode_Error;

    // Copy bytes
    for (size_t i = 0; i < p_BytesLength; i++)
    {
        p_CalibrationBytes[i] = s_RequestedGloveProfileBytes[i];
    }

    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_SetGloveCalibration(uint32_t p_GloveId, unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response)
{
    std::vector<uint8> t_Bytes;
    t_Bytes.resize(p_BytesLength);
    for (size_t i = 0; i < p_BytesLength; i++)
    {
        t_Bytes[i] = p_CalibrationBytes[i];
    }

    CoreLite::Definitions::Calibration::GloveProfile* t_Profile;
    if (!CoreLite::FileLoader::GloveProfileLoader::FromFile(t_Bytes, &t_Profile))
    {
        p_Response = SetGloveCalibrationReturnCode_DeserializationError;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::GloveProfileLoad>(p_GloveId, t_Profile);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    delete t_Profile;

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Response = t_Command->GetResult() == CoreLite::CommandResult::Success ? SetGloveCalibrationReturnCode_Success : SetGloveCalibrationReturnCode_Error;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_SetGloveCalibrationForUser(uint32_t p_UserId, unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response)
{
    std::vector<uint8> t_Bytes;
    t_Bytes.resize(p_BytesLength);
    for (size_t i = 0; i < p_BytesLength; i++)
    {
        t_Bytes[i] = p_CalibrationBytes[i];
    }

    CoreLite::Definitions::Calibration::GloveProfile* t_Profile;
    if (!CoreLite::FileLoader::GloveProfileLoader::FromFile(t_Bytes, &t_Profile))
    {
        p_Response = SetGloveCalibrationReturnCode_DeserializationError;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    auto t_Command = std::make_shared<CoreLite::Calibration::Command::GloveProfileLoadForUser>(p_UserId, t_Profile);
    s_CalibrationService->EnqueueAndWaitForCommand(t_Command);

    delete t_Profile;

    if (t_Command->GetResult() != CoreLite::CommandResult::Success)
        return SDKReturnCode::SDKReturnCode_Error;

    p_Response = t_Command->GetResult() == CoreLite::CommandResult::Success ? SetGloveCalibrationReturnCode_Success : SetGloveCalibrationReturnCode_Error;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GetGloveCalibrationFromBytes(unsigned char* p_CalibrationBytes, uint32_t p_BytesLength, SetGloveCalibrationReturnCode& p_Response, GloveProfile* p_GloveProfile)
{
    std::vector<uint8> t_Bytes;
    t_Bytes.resize(p_BytesLength);
    for (size_t i = 0; i < p_BytesLength; i++)
    {
        t_Bytes[i] = p_CalibrationBytes[i];
    }

    // Parse bytes
    CoreLite::Definitions::Calibration::GloveProfile* t_Profile;
    if (!CoreLite::FileLoader::GloveProfileLoader::FromFile(t_Bytes, &t_Profile))
    {
        p_Response = SetGloveCalibrationReturnCode_DeserializationError;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    // Convert to SDK type
    GloveProfile_Init(p_GloveProfile);
    if (!CoreLite::SDKConversion::GloveProfileToWrapper(t_Profile, *p_GloveProfile))
    {
        p_Response = SetGloveCalibrationReturnCode_Error;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    p_Response = SetGloveCalibrationReturnCode_Success;
    return SDKReturnCode::SDKReturnCode_Success;
}

SDKReturnCode Calibration_GloveCalibrationToBytesAndGetSize(const GloveProfile* p_GloveProfilePtr, uint32_t* p_Size)
{
    // Convert to SDK Types
    CoreLite::Definitions::Calibration::GloveProfile* t_GloveProfile;
    if (!CoreLite::SDKConversion::GloveProfileFromWrapper(*p_GloveProfilePtr, &t_GloveProfile))
        return SDKReturnCode::SDKReturnCode_InvalidArgument;

    // Convert to bytes
    std::vector<uint8> t_GloveProfileBytes;
    if (!CoreLite::FileLoader::GloveProfileLoader::ToFile(t_GloveProfile, t_GloveProfileBytes))
    {
        delete t_GloveProfile;
        return SDKReturnCode::SDKReturnCode_Error;
    }

    // Set size
    *p_Size = t_GloveProfileBytes.size();


    // Save bytes
    {
        const std::lock_guard<std::mutex> t_ManagedMutexLock(s_GloveProfileMutex);
        s_RequestedGloveProfileBytes = t_GloveProfileBytes;
    }

    delete t_GloveProfile;

    return SDKReturnCode::SDKReturnCode_Success;
}


#endif