From c105eef9698bb583f18d93a84b03e6e08dc2a5a3 Mon Sep 17 00:00:00 2001 From: wellenvogel Date: Wed, 1 Dec 2021 20:03:33 +0100 Subject: [PATCH] #12: multiple capabilities in user task, user init function, cleanup message handling in main, clearer api --- lib/api/GwApi.h | 8 +- lib/exampletask/GwExampleTask.cpp | 9 +- lib/exampletask/GwExampleTask.h | 10 +- lib/exampletask/config.json | 2 +- lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 7 +- lib/nmea0183ton2k/NMEA0183DataToN2K.h | 2 +- lib/usercode/GwUserCode.cpp | 94 ++++++++---- lib/usercode/GwUserCode.h | 23 ++- src/main.cpp | 186 +++++++++++++----------- 9 files changed, 215 insertions(+), 126 deletions(-) diff --git a/lib/api/GwApi.h b/lib/api/GwApi.h index 1a4fd2f..fce27af 100644 --- a/lib/api/GwApi.h +++ b/lib/api/GwApi.h @@ -9,16 +9,20 @@ class GwApi{ public: virtual GwRequestQueue *getQueue()=0; - virtual void sendN2kMessage(const tN2kMsg &msg)=0; - virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId)=0; + virtual void sendN2kMessage(const tN2kMsg &msg, bool convert=true)=0; + virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId,bool convert=true)=0; virtual int getSourceId()=0; virtual GwConfigHandler *getConfig()=0; virtual GwLog *getLogger()=0; virtual GwBoatData *getBoatData()=0; + virtual ~GwApi(){} }; #ifndef DECLARE_USERTASK #define DECLARE_USERTASK(task) #endif +#ifndef DECLARE_INITFUNCTION +#define DECLARE_INITFUNCTION(task) +#endif #ifndef DECLARE_CAPABILITY #define DECLARE_CAPABILITY(name,value) #endif diff --git a/lib/exampletask/GwExampleTask.cpp b/lib/exampletask/GwExampleTask.cpp index 8ab422c..ab1c12d 100644 --- a/lib/exampletask/GwExampleTask.cpp +++ b/lib/exampletask/GwExampleTask.cpp @@ -4,6 +4,12 @@ #include "GwExampleTask.h" #include "GwApi.h" +/** + * an init function that ist being called before other initializations from the core + */ +void exampleInit(GwApi *api){ + api->getLogger()->logDebug(GwLog::LOG,"example init running"); +} #define INVALID_COORD -99999 class GetBoatDataRequest: public GwMessage{ private: @@ -32,8 +38,7 @@ class GetBoatDataRequest: public GwMessage{ longitude=api->getBoatData()->Longitude->getDataWithDefault(INVALID_COORD); }; }; -void exampleTask(void *param){ - GwApi *api=(GwApi*)param; +void exampleTask(GwApi *api){ GwLog *logger=api->getLogger(); //get some configuration data bool exampleSwitch=api->getConfig()->getConfigItem( diff --git a/lib/exampletask/GwExampleTask.h b/lib/exampletask/GwExampleTask.h index f503085..3ea4bb1 100644 --- a/lib/exampletask/GwExampleTask.h +++ b/lib/exampletask/GwExampleTask.h @@ -23,11 +23,19 @@ //brightness 0...255 #define GWLED_BRIGHTNESS 64 -void exampleTask(void *param); +void exampleTask(GwApi *param); +void exampleInit(GwApi *param); //make the task known to the core +//the task function should not return (unless you delete the task - see example code) DECLARE_USERTASK(exampleTask); +//let the core call an init function before the +//N2K Stuff and the communication is set up +//normally you should not need this at all +//this function must return when done - otherwise the core will not start up +DECLARE_INITFUNCTION(exampleInit); //we declare a capability that we can //use in config.json to only show some //elements when this capability is set correctly DECLARE_CAPABILITY(testboard,true); +DECLARE_CAPABILITY(testboard2,true); #endif \ No newline at end of file diff --git a/lib/exampletask/config.json b/lib/exampletask/config.json index 3ecaf3b..ff556d4 100644 --- a/lib/exampletask/config.json +++ b/lib/exampletask/config.json @@ -1,7 +1,7 @@ [ { "name": "exampleConfig", - "label": "logging on", + "label": "monitor position", "type": "boolean", "default": "false", "description": "switch on logging of position acquired/failed", diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index 145ecb3..bd139da 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -17,10 +17,7 @@ NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSend LOG_DEBUG(GwLog::LOG,"NMEA0183DataToN2K created %p",this); } -bool NMEA0183DataToN2K::parseAndSend(const char *buffer, int sourceId) { - LOG_DEBUG(GwLog::DEBUG,"NMEA0183DataToN2K[%d] parsing %s",sourceId,buffer) - return false; -} + class SNMEA0183Msg : public tNMEA0183Msg{ public: @@ -821,6 +818,7 @@ private: } public: + virtual bool parseAndSend(const char *buffer, int sourceId) { LOG_DEBUG(GwLog::DEBUG + 1, "NMEA0183DataToN2K[%d] parsing %s", sourceId, buffer) @@ -843,7 +841,6 @@ public: } return rt; } - virtual unsigned long *handledPgns() { return converters.handledPgns(); diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.h b/lib/nmea0183ton2k/NMEA0183DataToN2K.h index bb6255e..f329fd5 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.h +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.h @@ -13,7 +13,7 @@ class NMEA0183DataToN2K{ N2kSender sender; public: NMEA0183DataToN2K(GwLog *logger,GwBoatData *boatData,N2kSender callback); - virtual bool parseAndSend(const char *buffer, int sourceId); + virtual bool parseAndSend(const char *buffer, int sourceId)=0; virtual unsigned long *handledPgns()=0; virtual int numConverters()=0; virtual String handledKeys()=0; diff --git a/lib/usercode/GwUserCode.cpp b/lib/usercode/GwUserCode.cpp index 1e82af6..b41a65b 100644 --- a/lib/usercode/GwUserCode.cpp +++ b/lib/usercode/GwUserCode.cpp @@ -1,29 +1,35 @@ #include "GwUserCode.h" +#include "GwSynchronized.h" #include #include #include //user task handling -class UserTask{ + + + +std::vector userTasks; +std::vector initTasks; +GwUserCode::Capabilities userCapabilities; + + + +class GwUserTaskDef{ public: - String name; - TaskFunction_t task; - UserTask(String name,TaskFunction_t task){ - this->name=name; - this->task=task; + GwUserTaskDef(TaskFunction_t task,String name){ + userTasks.push_back(GwUserTask(name,task)); + } + GwUserTaskDef(GwUserTaskFunction task,String name){ + userTasks.push_back(GwUserTask(name,task)); } }; -std::vector userTasks; -GwUserCode::Capabilities userCapabilities; - -void registerUserTask(TaskFunction_t task,String name){ - userTasks.push_back(UserTask(name,task)); -} - -class GwUserTask{ +class GwInitTask{ public: - GwUserTask(TaskFunction_t task,String name){ - registerUserTask(task,name); + GwInitTask(TaskFunction_t task, String name){ + initTasks.push_back(GwUserTask(name,task)); + } + GwInitTask(GwUserTaskFunction task, String name){ + initTasks.push_back(GwUserTask(name,task)); } }; class GwUserCapability{ @@ -32,32 +38,37 @@ class GwUserCapability{ userCapabilities[name]=value; } }; -#define DECLARE_USERTASK(task) GwUserTask __##task##__(task,#task); -#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name__(#name,#value); -#include "GwUserTasks.h" +#define DECLARE_USERTASK(task) GwUserTaskDef __##task##__(task,#task); +#define DECLARE_INITFUNCTION(task) GwInitTask __Init##task##__(task,#task); +#define DECLARE_CAPABILITY(name,value) GwUserCapability __CAP##name##__(#name,#value); #include "GwApi.h" +#include "GwUserTasks.h" class TaskApi : public GwApi { GwApi *api; int sourceId; + SemaphoreHandle_t *mainLock; public: - TaskApi(GwApi *api, int sourceId) + TaskApi(GwApi *api, int sourceId, SemaphoreHandle_t *mainLock) { this->sourceId = sourceId; this->api = api; + this->mainLock=mainLock; } virtual GwRequestQueue *getQueue() { return api->getQueue(); } - virtual void sendN2kMessage(const tN2kMsg &msg) + virtual void sendN2kMessage(const tN2kMsg &msg,bool convert) { - api->sendN2kMessage(msg); + GWSYNCHRONIZED(mainLock); + api->sendN2kMessage(msg,convert); } - virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId) + virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId, bool convert) { - api->sendNMEA0183Message(msg, sourceId); + GWSYNCHRONIZED(mainLock); + api->sendNMEA0183Message(msg, this->sourceId,convert); } virtual int getSourceId() { @@ -75,27 +86,50 @@ public: { return api->getBoatData(); } + virtual ~TaskApi(){}; }; -GwUserCode::GwUserCode(GwApi *api){ +GwUserCode::GwUserCode(GwApi *api,SemaphoreHandle_t *mainLock){ this->logger=api->getLogger(); this->api=api; + this->mainLock=mainLock; } -static void startAddOnTask(GwApi *api,TaskFunction_t task,int sourceId){ - TaskApi* taskApi=new TaskApi(api,sourceId); - xTaskCreate(task,"user",2000,taskApi,3,NULL); +void userTaskStart(void *p){ + GwUserTask *task=(GwUserTask*)p; + if (task->isUserTask){ + task->usertask(task->api); + } + else{ + task->task(task->api); + } + delete task->api; + task->api=NULL; +} +void GwUserCode::startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name){ + task->api=new TaskApi(api,sourceId,mainLock); + xTaskCreate(userTaskStart,name.c_str(),2000,task,3,NULL); } void GwUserCode::startUserTasks(int baseId){ LOG_DEBUG(GwLog::DEBUG,"starting %d user tasks",userTasks.size()); for (auto it=userTasks.begin();it != userTasks.end();it++){ LOG_DEBUG(GwLog::LOG,"starting user task %s with id %d",it->name.c_str(),baseId); - startAddOnTask(api,it->task,baseId); + startAddOnTask(api,&(*it),baseId,it->name); + baseId++; + } +} +void GwUserCode::startInitTasks(int baseId){ + LOG_DEBUG(GwLog::DEBUG,"starting %d user init tasks",initTasks.size()); + for (auto it=initTasks.begin();it != initTasks.end();it++){ + LOG_DEBUG(GwLog::LOG,"starting user init task %s with id %d",it->name.c_str(),baseId); + it->api=new TaskApi(api,baseId,mainLock); + userTaskStart(&(*it)); baseId++; } } void GwUserCode::startAddonTask(String name, TaskFunction_t task, int id){ LOG_DEBUG(GwLog::LOG,"starting addon task %s with id %d",name.c_str(),id); - startAddOnTask(api,task,id); + GwUserTask *userTask=new GwUserTask(name,task); //memory leak - acceptable as only during startup + startAddOnTask(api,userTask,id,userTask->name); } GwUserCode::Capabilities * GwUserCode::getCapabilities(){ diff --git a/lib/usercode/GwUserCode.h b/lib/usercode/GwUserCode.h index aac8d1f..5d28e3e 100644 --- a/lib/usercode/GwUserCode.h +++ b/lib/usercode/GwUserCode.h @@ -4,13 +4,34 @@ #include class GwLog; class GwApi; +typedef void (*GwUserTaskFunction)(GwApi *); +class GwUserTask{ + public: + String name; + TaskFunction_t task=NULL; + GwUserTaskFunction usertask=NULL; + bool isUserTask=false; + GwApi *api=NULL; + GwUserTask(String name,TaskFunction_t task){ + this->name=name; + this->task=task; + } + GwUserTask(String name, GwUserTaskFunction task){ + this->name=name; + this->usertask=task; + this->isUserTask=true; + } +}; class GwUserCode{ GwLog *logger; GwApi *api; + SemaphoreHandle_t *mainLock; + void startAddOnTask(GwApi *api,GwUserTask *task,int sourceId,String name); public: typedef std::map Capabilities; - GwUserCode(GwApi *api); + GwUserCode(GwApi *api, SemaphoreHandle_t *mainLock); void startUserTasks(int baseId); + void startInitTasks(int baseId); void startAddonTask(String name,TaskFunction_t task, int id); Capabilities *getCapabilities(); }; diff --git a/src/main.cpp b/src/main.cpp index 331680e..09e6160 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -61,6 +61,7 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting #include "GwLeds.h" #include "GwCounter.h" #include "GwXDRMappings.h" +#include "GwSynchronized.h" #include "GwUserCode.h" @@ -72,6 +73,8 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting #define SERIAL1_CHANNEL_ID 2 #define MIN_TCP_CHANNEL_ID 3 +#define MIN_USER_TASK 200 + #define MAX_NMEA2000_MESSAGE_SEASMART_SIZE 500 #define MAX_NMEA0183_MESSAGE_SIZE 150 // For AIS @@ -100,10 +103,9 @@ N2kDataToNMEA0183 *nmea0183Converter=NULL; NMEA0183DataToN2K *toN2KConverter=NULL; tActisenseReader *actisenseReader=NULL; Stream *usbStream=NULL; +SemaphoreHandle_t mainLock; -void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg,int id); - GwRequestQueue mainQueue(&logger,20); GwWebServer webserver(&logger,&mainQueue,80); @@ -182,6 +184,81 @@ bool serCanRead=true; GwSerial *usbSerial = new GwSerial(NULL, 0, USB_CHANNEL_ID); GwSerial *serial1=NULL; +void sendBufferToChannels(const char * buffer, int sourceId){ + if (sendTCP->asBoolean() && checkFilter(buffer,MIN_TCP_CHANNEL_ID,false)){ + socketServer.sendToClients(buffer,sourceId); + updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false); + } + if (! actisenseReader && sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){ + usbSerial->sendToClients(buffer,sourceId); + updateNMEACounter(USB_CHANNEL_ID,buffer,false); + } + if (serial1 && serCanWrite && checkFilter(buffer,SERIAL1_CHANNEL_ID,false)){ + serial1->sendToClients(buffer,sourceId); + updateNMEACounter(SERIAL1_CHANNEL_ID,buffer,false); + } +} +typedef enum { + N2KT_MSGIN, //from CAN + N2KT_MSGINT, //from internal source + N2KT_MSGOUT, //from converter + N2KT_MSGACT //from actisense +} N2K_MsgDirection; +void handleN2kMessage(const tN2kMsg &n2kMsg,N2K_MsgDirection direction) +{ + logger.logDebug(GwLog::DEBUG + 1, "N2K: pgn %d, dir %d", + n2kMsg.PGN,(int)direction); + if (direction == N2KT_MSGIN){ + countNMEA2KIn.add(n2kMsg.PGN); + } + if (sendSeasmart->asBoolean()) + { + char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE]; + if (N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0) + return; + socketServer.sendToClients(buf, N2K_CHANNEL_ID); + } + if (actisenseReader && direction != N2KT_MSGACT && usbStream && usbSendActisens->asBoolean()) + { + countUSBOut.add(String(n2kMsg.PGN)); + n2kMsg.SendInActisenseFormat(usbStream); + } + if (direction != N2KT_MSGOUT){ + nmea0183Converter->HandleMsg(n2kMsg); + } + if (direction != N2KT_MSGIN){ + countNMEA2KOut.add(n2kMsg.PGN); + NMEA2000.SendMsg(n2kMsg); + } +}; + +void handleReceivedNmeaMessage(const char *buf, int sourceId){ + if (! checkFilter(buf,sourceId,true)) return; + updateNMEACounter(sourceId,buf,true); + if ( (sourceId >= MIN_USER_TASK) || + (sourceId == USB_CHANNEL_ID && n2kFromUSB->asBoolean())|| + (sourceId >= MIN_TCP_CHANNEL_ID && n2kFromTCP->asBoolean())|| + (sourceId == SERIAL1_CHANNEL_ID && n2kFromSerial->asBoolean()) + ) + toN2KConverter->parseAndSend(buf,sourceId); + sendBufferToChannels(buf,sourceId); +} + +//***************************************************************************** +void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg, int sourceId,bool convert=false) { + logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183(1)"); + char buf[MAX_NMEA0183_MESSAGE_SIZE+3]; + if ( !NMEA0183Msg.GetMessage(buf, MAX_NMEA0183_MESSAGE_SIZE) ) return; + logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183: %s",buf); + if (convert){ + toN2KConverter->parseAndSend(buf,sourceId); + } + size_t len=strlen(buf); + buf[len]=0x0d; + buf[len+1]=0x0a; + buf[len+2]=0; + sendBufferToChannels(buf,sourceId); +} class GwSerialLog : public GwLogWriter{ static const size_t bufferSize=4096; @@ -216,6 +293,7 @@ class GwSerialLog : public GwLogWriter{ GwSerialLog logWriter; + class ApiImpl : public GwApi { private: @@ -230,13 +308,14 @@ public: { return &mainQueue; } - virtual void sendN2kMessage(const tN2kMsg &msg) + virtual void sendN2kMessage(const tN2kMsg &msg,bool convert) { - NMEA2000.SendMsg(msg); + handleN2kMessage(msg,convert?N2KT_MSGINT:N2KT_MSGOUT); + } - virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId) + virtual void sendNMEA0183Message(const tNMEA0183Msg &msg, int sourceId,bool convert) { - SendNMEA0183Message(msg, sourceId); + SendNMEA0183Message(msg, sourceId,convert); } virtual int getSourceId() { @@ -252,6 +331,7 @@ public: virtual GwBoatData *getBoatData(){ return &boatData; } + virtual ~ApiImpl(){} }; bool delayedRestart(){ @@ -264,7 +344,7 @@ bool delayedRestart(){ },"reset",1000,&logger,0,NULL) == pdPASS; } -GwUserCode userCodeHandler(new ApiImpl(200)); +GwUserCode userCodeHandler(new ApiImpl(MIN_USER_TASK),&mainLock); #define JSON_OK "{\"status\":\"OK\"}" @@ -488,25 +568,10 @@ protected: } }; -//received or converted N2K message -void handleN2kMessage(const tN2kMsg &n2kMsg){ - if ( sendSeasmart->asBoolean() ) { - char buf[MAX_NMEA2000_MESSAGE_SEASMART_SIZE]; - if ( N2kToSeasmart(n2kMsg, millis(), buf, MAX_NMEA2000_MESSAGE_SEASMART_SIZE) == 0 ) return; - socketServer.sendToClients(buf,N2K_CHANNEL_ID); - } - logger.logDebug(GwLog::DEBUG+1,"handling pgn %d",n2kMsg.PGN); - nmea0183Converter->HandleMsg(n2kMsg); - logger.logDebug(GwLog::DEBUG+1,"done pgn %d",n2kMsg.PGN); - }; -void trySendActisense(const tN2kMsg &n2kMsg){ - if (actisenseReader && usbStream && usbSendActisens->asBoolean()){ - countUSBOut.add(String(n2kMsg.PGN)); - n2kMsg.SendInActisenseFormat(usbStream); - } -} -void setup() { + +void setup() { + mainLock=xSemaphoreCreateMutex(); uint8_t chipid[6]; uint32_t id = 0; config.loadConfig(); @@ -533,6 +598,7 @@ void setup() { logger.logDebug(GwLog::LOG,"created GwSerial for USB port"); } logger.logDebug(GwLog::LOG,"config: %s", config.toString().c_str()); + userCodeHandler.startInitTasks(MIN_USER_TASK); #ifdef GWSERIAL_MODE int serialrx=-1; int serialtx=-1; @@ -623,13 +689,14 @@ void setup() { logger.flush(); nmea0183Converter= N2kDataToNMEA0183::create(&logger, &boatData, - SendNMEA0183Message, N2K_CHANNEL_ID,config.getString(config.talkerId,String("GP")),&xdrMappings); + [](const tNMEA0183Msg &msg, int sourceId){ + SendNMEA0183Message(msg,sourceId,false); + } + , N2K_CHANNEL_ID,config.getString(config.talkerId,String("GP")),&xdrMappings); toN2KConverter= NMEA0183DataToN2K::create(&logger,&boatData,[](const tN2kMsg &msg)->bool{ logger.logDebug(GwLog::DEBUG+2,"send N2K %ld",msg.PGN); - countNMEA2KOut.add(msg.PGN); - NMEA2000.SendMsg(msg); - trySendActisense(msg); + handleN2kMessage(msg,N2KT_MSGOUT); return true; }); @@ -683,16 +750,12 @@ void setup() { usbStream=usbSerial->getStream(false); actisenseReader->SetReadStream(usbStream); actisenseReader->SetMsgHandler([](const tN2kMsg &msg){ - countNMEA2KOut.add(msg.PGN); - NMEA2000.SendMsg(msg); - handleN2kMessage(msg); countUSBIn.add(String(msg.PGN)); + handleN2kMessage(msg,N2KT_MSGACT); }); } NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){ - countNMEA2KIn.add(n2kMsg.PGN); - trySendActisense(n2kMsg); - handleN2kMessage(n2kMsg); + handleN2kMessage(n2kMsg,N2KT_MSGIN); }); NMEA2000.Open(); logger.logDebug(GwLog::LOG,"starting addon tasks"); @@ -700,58 +763,14 @@ void setup() { userCodeHandler.startAddonTask(F("handleButtons"),handleButtons,100); setLedMode(LED_GREEN); userCodeHandler.startAddonTask(F("handleLeds"),handleLeds,101); - userCodeHandler.startUserTasks(200); + { + GWSYNCHRONIZED(&mainLock); + userCodeHandler.startUserTasks(MIN_USER_TASK); + } logger.logDebug(GwLog::LOG,"setup done"); } //***************************************************************************** - - - - - - - -void sendBufferToChannels(const char * buffer, int sourceId){ - if (sendTCP->asBoolean() && checkFilter(buffer,MIN_TCP_CHANNEL_ID,false)){ - socketServer.sendToClients(buffer,sourceId); - updateNMEACounter(MIN_TCP_CHANNEL_ID,buffer,false); - } - if (! actisenseReader && sendUsb->asBoolean() && checkFilter(buffer,USB_CHANNEL_ID,false)){ - usbSerial->sendToClients(buffer,sourceId); - updateNMEACounter(USB_CHANNEL_ID,buffer,false); - } - if (serial1 && serCanWrite && checkFilter(buffer,SERIAL1_CHANNEL_ID,false)){ - serial1->sendToClients(buffer,sourceId); - updateNMEACounter(SERIAL1_CHANNEL_ID,buffer,false); - } -} - -//***************************************************************************** -void SendNMEA0183Message(const tNMEA0183Msg &NMEA0183Msg, int sourceId) { - if ( ! sendTCP->asBoolean() && ! sendUsb->asBoolean() ) return; - logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183(1)"); - char buf[MAX_NMEA0183_MESSAGE_SIZE+3]; - if ( !NMEA0183Msg.GetMessage(buf, MAX_NMEA0183_MESSAGE_SIZE) ) return; - logger.logDebug(GwLog::DEBUG+2,"SendNMEA0183: %s",buf); - size_t len=strlen(buf); - buf[len]=0x0d; - buf[len+1]=0x0a; - buf[len+2]=0; - sendBufferToChannels(buf,sourceId); -} - -void handleReceivedNmeaMessage(const char *buf, int sourceId){ - if (! checkFilter(buf,sourceId,true)) return; - updateNMEACounter(sourceId,buf,true); - if ((sourceId == USB_CHANNEL_ID && n2kFromUSB->asBoolean())|| - (sourceId >= MIN_TCP_CHANNEL_ID && n2kFromTCP->asBoolean())|| - (sourceId == SERIAL1_CHANNEL_ID && n2kFromSerial->asBoolean()) - ) - toN2KConverter->parseAndSend(buf,sourceId); - sendBufferToChannels(buf,sourceId); -} - void handleSendAndRead(bool handleRead){ socketServer.loop(handleRead); usbSerial->loop(handleRead); @@ -800,6 +819,7 @@ class NMEAMessageReceiver : public GwBufferWriter{ NMEAMessageReceiver receiver; unsigned long lastHeapReport=0; void loop() { + GWSYNCHRONIZED(&mainLock); logger.flush(); gwWifi.loop(); unsigned long now=millis();