--- a/C_runtime/Makefile Fri May 24 18:48:28 2024 +0200
+++ b/C_runtime/Makefile Fri May 24 18:55:46 2024 +0200
@@ -41,9 +41,7 @@
$(ERPC_C_ROOT)/transports/erpc_serial_transport.cpp \
$(ERPC_C_ROOT)/transports/erpc_tcp_transport.cpp
-SOURCES += $(RUNTIME_ROOT)/c_erpc_PLCObject_client.cpp \
- $(RUNTIME_ROOT)/c_erpc_PLCObject_server.cpp \
- $(RUNTIME_ROOT)/erpc_PLCObject_client.cpp \
+SOURCES += $(RUNTIME_ROOT)/erpc_PLCObject_client.cpp \ $(RUNTIME_ROOT)/erpc_PLCObject_interface.cpp \
$(RUNTIME_ROOT)/erpc_PLCObject_server.cpp \
$(RUNTIME_ROOT)/md5.cpp \
--- a/C_runtime/PLCObject.cpp Fri May 24 18:48:28 2024 +0200
+++ b/C_runtime/PLCObject.cpp Fri May 24 18:55:46 2024 +0200
@@ -4,6 +4,7 @@
@@ -26,10 +27,10 @@
m_status.PLCstatus = Empty;
- m_plcID.ID = "N/A"; // TODO
- m_plcID.PSK = "N/A"; // TODO
PLCObject::~PLCObject(void)
@@ -43,8 +44,15 @@
// Output new blob's md5 into newBlobID
- auto nh = m_mapBlobIDToBlob.extract(std::vector<uint8_t>(
- blobID->data, blobID->data + blobID->dataLength));
+ newBlobID->data = (uint8_t *)malloc(MD5::digestsize); + if (newBlobID->data == NULL) + std::vector<uint8_t> k(blobID->data, blobID->data + blobID->dataLength); + auto nh = m_mapBlobIDToBlob.extract(k); @@ -60,11 +68,14 @@
MD5::digest_t digest = blob->digest();
- nh.key() = std::vector<uint8_t>(
- (uint8_t)*digest.data, (uint8_t)*digest.data + MD5::digestsize);
+ std::vector<uint8_t> nk((uint8_t*)digest.data, (uint8_t*)digest.data + MD5::digestsize); m_mapBlobIDToBlob.insert(std::move(nh));
+ memcpy(newBlobID->data, digest.data, MD5::digestsize); + newBlobID->dataLength = MD5::digestsize; @@ -106,8 +117,25 @@
uint32_t PLCObject::GetPLCID(PSKID *plcID)
+ plcID->ID = (char *)malloc(m_PSK_ID.size() + 1); + memcpy(plcID->ID, m_PSK_ID.c_str(), m_PSK_ID.size()); + plcID->ID[m_PSK_ID.size()] = '\0'; + plcID->PSK = (char *)malloc(m_PSK_secret.size() + 1); + if (plcID->PSK == NULL) + memcpy(plcID->PSK, m_PSK_secret.c_str(), m_PSK_secret.size()); + plcID->PSK[m_PSK_secret.size()] = '\0'; @@ -129,37 +157,47 @@
// Check if there are any traces
size_t sz = m_traces.size();
- m_tracesMutex.unlock();
- // Allocate memory for traces
- traces->traces.elements = (trace_sample *)malloc(sz * sizeof(trace_sample));
- if(traces->traces.elements == NULL)
- m_tracesMutex.unlock();
- traces->traces.elementsCount = sz;
+ // Allocate memory for traces + traces->traces.elements = (trace_sample *)malloc(sz * sizeof(trace_sample)); + if(traces->traces.elements == NULL) + m_tracesMutex.unlock(); + // Copy traces from vector + memcpy(traces->traces.elements, m_traces.data(), sz * sizeof(trace_sample)); - // Copy traces from vector
- memcpy(traces->traces.elements, m_traces.data(), sz * sizeof(trace_sample));
+ // note that the data is not freed here, it is meant to be freed by eRPC server code + m_tracesMutex.unlock();
- // note that the data is not freed here, it is meant to be freed by eRPC server code
- m_tracesMutex.unlock();
+ traces->traces.elementsCount = sz; + traces->PLCstatus = m_status.PLCstatus; uint32_t PLCObject::MatchMD5(const char *MD5, bool *match)
+ // an empty PLC is never considered to match + if(m_status.PLCstatus == Empty) // Load the last transferred PLC md5 hex digest
- std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum;
+ std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum; + } catch (std::exception e) { // Compare the given MD5 with the last transferred PLC md5
*match = (md5sum == MD5);
@@ -208,11 +246,13 @@
if(m_status.PLCstatus == Started)
if(m_status.PLCstatus == Broken)
@@ -246,38 +286,65 @@
extra_files_log << extrafile->fname << std::endl;
+ uint32_t res = LoadPLC(); + m_status.PLCstatus = Stopped;
- m_PLCSyms.sym = (decltype(m_PLCSyms.sym))dlsym(m_handle, #sym); \
- if (m_PLCSyms.sym == NULL) \
+ m_PLCSyms.sym = (decltype(m_PLCSyms.sym))dlsym(m_handle, #sym); \ + if (m_PLCSyms.sym == NULL) \ + /* TODO: use log instead */ \ + std::cout << "Error dlsym " #sym ": " << dlerror() << std::endl; \ uint32_t PLCObject::LoadPLC(void)
// Load the last transferred PLC md5 hex digest
- std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum;
+ std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum; + } catch (std::exception e) { // Concatenate md5sum and shared object extension to obtain filename
- std::filesystem::path filename = std::filesystem::path(md5sum) += SHARED_OBJECT_EXT;
+ std::filesystem::path filename(md5sum + SHARED_OBJECT_EXT); // Load the shared object file
- m_handle = dlopen(filename.c_str(), RTLD_NOW);
+ m_handle = dlopen(std::filesystem::absolute(filename).c_str(), RTLD_NOW); + std::cout << "Error: " << dlerror() << std::endl; // Resolve shared object symbols
FOR_EACH_PLC_SYMBOLS_DO(DLSYM);
+ // Set content of PLC_ID to md5sum + m_PLCSyms.PLC_ID = (uint8_t *)malloc(md5sum.size() + 1); + if (m_PLCSyms.PLC_ID == NULL) + memcpy(m_PLCSyms.PLC_ID, md5sum.c_str(), md5sum.size()); + m_PLCSyms.PLC_ID[md5sum.size()] = '\0'; @@ -312,9 +379,8 @@
-uint32_t PLCObject::PurgePLC(void){
+uint32_t PLCObject::PurgePLC(void) // Open the extra files list
std::ifstream extra_files_log(std::string(ExtraFilesList), std::ios::binary);
@@ -328,20 +394,24 @@
// Load the last transferred PLC md5 hex digest
- std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum;
+ std::ifstream(std::string(LastTransferredPLC), std::ios::binary) >> md5sum; - // Concatenate md5sum and shared object extension to obtain filename
- std::filesystem::path filename =
- std::filesystem::path(md5sum) += SHARED_OBJECT_EXT;
+ // Remove the PLC object shared object file + std::filesystem::remove(md5sum + SHARED_OBJECT_EXT); + } catch (std::exception e) { - // Remove the PLC object shared object file
- std::filesystem::remove(filename);
+ // Remove the last transferred PLC md5 hex digest + std::filesystem::remove(std::string(LastTransferredPLC)); - // Remove the last transferred PLC md5 hex digest
- std::filesystem::remove(std::string(LastTransferredPLC));
- // Remove the extra files list
- std::filesystem::remove(std::string(ExtraFilesList));
+ // Remove the extra files list + std::filesystem::remove(std::string(ExtraFilesList)); + } catch (std::exception e) { @@ -388,7 +458,9 @@
MD5::digest_t digest = blob->digest();
- m_mapBlobIDToBlob[std::vector<uint8_t>((uint8_t)*digest.data, (uint8_t)*digest.data + MD5::digestsize)] = blob;
+ std::vector<uint8_t> k((uint8_t*)digest.data, (uint8_t*)digest.data + MD5::digestsize); + m_mapBlobIDToBlob[k] = blob; blobID->data = (uint8_t *)malloc(MD5::digestsize);
if (blobID->data == NULL)
@@ -400,10 +472,25 @@
+void PLCObject::PurgeTraceBuffer(void) + for(trace_sample s : m_traces){ + free(s.TraceBuffer.data); + m_tracesMutex.unlock(); uint32_t PLCObject::SetTraceVariablesList(
const list_trace_order_1_t *orders, int32_t *debugtoken)
+ if(m_status.PLCstatus == Empty) @@ -431,20 +518,23 @@
// if any error, disable debug
// since debug is already suspended, resume it first
- m_PLCSyms.ResumeDebug();
+ m_PLCSyms.resumeDebug(); m_PLCSyms.suspendDebug(1);
+ // old traces are not valid anymore // Start debug thread if not already started
if(!m_traceThread.joinable())
m_traceThread = std::thread(&PLCObject::TraceThreadProc, this);
- m_PLCSyms.ResumeDebug();
+ m_PLCSyms.resumeDebug(); *debugtoken = m_debugToken;
@@ -487,6 +577,13 @@
uint32_t PLCObject::LogMessage(uint8_t level, std::string message)
+ // if PLC isn't loaded, log to stdout + if(m_PLCSyms.LogMessage == NULL) + std::cout << level << message << std::endl; // Log std::string message with given level
return m_PLCSyms.LogMessage(level, (char *)message.c_str(), message.size());
@@ -495,7 +592,7 @@
- m_PLCSyms.ResumeDebug();
+ m_PLCSyms.resumeDebug(); while(m_status.PLCstatus == Started)
@@ -537,13 +634,7 @@
- for(trace_sample s : m_traces){
- free(s.TraceBuffer.data);
- m_tracesMutex.unlock();
LogMessage(err ? LOG_CRITICAL : LOG_INFO,
err == ENOMEM ? "Out of memory in TraceThreadProc" :
--- a/C_runtime/PLCObject.hpp Fri May 24 18:48:28 2024 +0200
+++ b/C_runtime/PLCObject.hpp Fri May 24 18:55:46 2024 +0200
@@ -10,7 +10,7 @@
#include "erpc_PLCObject_interface.hpp"
@@ -26,28 +26,29 @@
-typedef struct s_PLCSyms{
- int (*startPLC)(int argc,char **argv);
- 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);
+ typedef struct s_PLCSyms{ + int (*startPLC)(int argc,char **argv); + 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); class PLCObject : public BeremizPLCObjectService_interface
@@ -91,8 +92,9 @@
+ std::string m_PSK_secret; // Debug token, used for consistency check of traces
@@ -111,6 +113,7 @@
uint32_t UnLoadPLC(void);
uint32_t LogMessage(uint8_t level, std::string message);
+ void PurgeTraceBuffer(void); void TraceThreadProc(void);
--- a/C_runtime/posix_main.cpp Fri May 24 18:48:28 2024 +0200
+++ b/C_runtime/posix_main.cpp Fri May 24 18:55:46 2024 +0200
@@ -14,12 +14,16 @@
#include "erpc_basic_codec.hpp"
#include "erpc_serial_transport.hpp"
#include "erpc_tcp_transport.hpp"
#include "erpc_simple_server.hpp"
+// eRPC generated includes #include "erpc_PLCObject_server.hpp"
+// erpcgen includes (re-uses erpcgen's logging system and options parser) @@ -28,13 +32,14 @@
class MyMessageBufferFactory : public MessageBufferFactory
virtual MessageBuffer create()
- uint8_t *buf = new uint8_t[1024];
- return MessageBuffer(buf, 1024);
+ uint8_t *buf = new uint8_t[MSG_SIZE]; + return MessageBuffer(buf, MSG_SIZE); virtual void dispose(MessageBuffer *buf)
@@ -351,6 +356,9 @@
+ _transport->setCrc16(&crc); MyMessageBufferFactory _msgFactory;
BasicCodecFactory _basicCodecFactory;