C_runtime/PLCObject.hpp
author Edouard Tisserant <edouard@beremiz.fr>
Wed, 16 Oct 2024 15:45:15 +0200
changeset 4048 b3ea419a4d47
parent 4032 1ffff67678ad
permissions -rw-r--r--
SVGHMI: swap position and range of ForEach widget so that both range and size can be optional.
/*
    Copyright Edouard TISSERANT 2024
    See COPYING for details
*/

#if !defined(_PLCObject_hpp_)
#define _PLCObject_hpp_

#include <map>
#include <vector>
#include <mutex>
#include <thread>

#include "blob.hpp"

#include "erpc_PLCObject_interface.hpp"

using namespace erpcShim;

#define FOR_EACH_PLC_SYMBOLS_DO(ACTION) \
    ACTION(PLC_ID)\
    ACTION(startPLC)\
    ACTION(stopPLC)\
    ACTION(ResetDebugVariables)\
    ACTION(RegisterDebugVariable)\
    ACTION(FreeDebugData)\
    ACTION(GetDebugData)\
    ACTION(suspendDebug)\
    ACTION(resumeDebug)\
    ACTION(ResetLogCount)\
    ACTION(GetLogCount)\
    ACTION(LogMessage)\
    ACTION(GetLogMessage)

extern "C" {   
    typedef struct s_PLCSyms{
        uint8_t *PLC_ID;
        int (*startPLC)(int argc,char **argv);
        int (*stopPLC)(void);
        void (*ResetDebugVariables)(void);
        int (*RegisterDebugVariable)(unsigned int idx, void* force, size_t force_size);
        void (*FreeDebugData)(void);
        int (*GetDebugData)(unsigned int *tick, unsigned int *size, void **buffer);
        int (*suspendDebug)(int disable);
        void (*resumeDebug)(void);
        void (*ResetLogCount)(void);
        uint32_t (*GetLogCount)(uint8_t level);
        int (*LogMessage)(uint8_t level, char* buf, uint32_t size);
        uint32_t (*GetLogMessage)(uint8_t level, uint32_t msgidx, char* buf, uint32_t max_size, uint32_t* tick, uint32_t* tv_sec, uint32_t* tv_nsec);
    } PLCSyms;
}
class PLCObject : public BeremizPLCObjectService_interface
{
    public:

        PLCObject(void);
        ~PLCObject(void);

        // ERPC interface
        uint32_t AppendChunkToBlob(const binary_t * data, const binary_t * blobID, binary_t * newBlobID);
        uint32_t GetLogMessage(uint8_t level, uint32_t msgID, log_message * message);
        uint32_t GetPLCID(PSKID * plcID);
        uint32_t GetPLCstatus(PLCstatus * status);
        uint32_t GetTraceVariables(uint32_t debugToken, TraceVariables * traces);
        uint32_t MatchMD5(const char * MD5, bool * match);
        uint32_t NewPLC(const char * md5sum, const binary_t * plcObjectBlobID, const list_extra_file_1_t * extrafiles, bool * success);
        uint32_t PurgeBlobs(void);
        uint32_t RepairPLC(void);
        uint32_t ResetLogCount(void);
        uint32_t SeedBlob(const binary_t * seed, binary_t * blobID);
        uint32_t SetTraceVariablesList(const list_trace_order_1_t * orders, int32_t * debugtoken);
        uint32_t StartPLC(void);
        uint32_t StopPLC(bool * success);
        uint32_t ExtendedCall(const char * method, const binary_t * argument, binary_t * answer);

        // Public interface used by runtime
        uint32_t AutoLoad();
        uint32_t LogMessage(uint8_t level, std::string message);

    private:
        // A map of all the blobs
        std::map<std::vector<uint8_t>, Blob*> m_mapBlobIDToBlob;

        // PLC object library handle
        void * m_handle;

        // Shared object mutex
        std::mutex m_PLClibMutex;

        // Symbols resolved from the PLC object
        PLCSyms m_PLCSyms;

        // argc and argv for the PLC object
        int m_argc;
        char ** m_argv;

        // PLC status
        PLCstatus m_status;

        // PSK
        std::string m_PSK_ID;
        std::string m_PSK_secret;

        // Debug token, used for consistency check of traces
        uint32_t m_debugToken;

        // Trace thread
        std::thread m_traceThread;

        // Trace thread mutex
        std::mutex m_tracesMutex;

        // Trace double buffer
        std::vector<trace_sample> m_traces;

        uint32_t BlobAsFile(const binary_t * BlobID, std::filesystem::path filename);
        uint32_t LoadPLC(void);
        uint32_t UnLoadPLC(void);
        uint32_t PurgePLC(void);
        void PurgeTraceBuffer(void);
        void TraceThreadProc(void);
};

#endif