From f9bec3f0ba428a9a63e112f18920e08d080a8f33 Mon Sep 17 00:00:00 2001 From: andreas Date: Sun, 31 Oct 2021 10:59:53 +0100 Subject: [PATCH] make the converterlist an own class --- lib/nmea0183ton2k/NMEA0183ConverterList.h | 173 ++++++++++++++++++++++ lib/nmea0183ton2k/NMEA0183DataToN2K.cpp | 160 +++++++------------- 2 files changed, 226 insertions(+), 107 deletions(-) create mode 100644 lib/nmea0183ton2k/NMEA0183ConverterList.h diff --git a/lib/nmea0183ton2k/NMEA0183ConverterList.h b/lib/nmea0183ton2k/NMEA0183ConverterList.h new file mode 100644 index 0000000..5e5c786 --- /dev/null +++ b/lib/nmea0183ton2k/NMEA0183ConverterList.h @@ -0,0 +1,173 @@ +#ifndef _NMEA0183CONVERTERLIST_H +#define _NMEA0183CONVERTERLIST_H + +#include "WString.h" +#include + +template +class ConverterList +{ +public: + typedef void (T::*Converter)(const Msg &msg); + typedef void (*LConverter)(const Msg &msg, T *); + +private: + double dummy; + class ConverterEntry + { + public: + unsigned long count = 0; + unsigned long *pgn; + unsigned int numPgn = 0; + Converter converter = NULL; + LConverter lconverter = NULL; + ConverterEntry() + { + pgn = NULL; + converter = NULL; + } + ConverterEntry(unsigned long pgn, LConverter cv) + { + lconverter = cv; + this->pgn = new unsigned long[1]; + this->pgn[0] = pgn; + } + ConverterEntry(unsigned long pgn, Converter cv = NULL) + { + converter = cv; + numPgn = 1; + this->pgn = new unsigned long[1]; + this->pgn[0] = pgn; + } + ConverterEntry(unsigned long pgn1, unsigned long pgn2, Converter cv = NULL) + { + converter = cv; + numPgn = 2; + this->pgn = new unsigned long[2]; + this->pgn[0] = pgn1; + this->pgn[1] = pgn2; + } + ConverterEntry(unsigned long pgn1, unsigned long pgn2, LConverter cv = NULL) + { + lconverter = cv; + numPgn = 2; + this->pgn = new unsigned long[2]; + this->pgn[0] = pgn1; + this->pgn[1] = pgn2; + } + ConverterEntry(unsigned long pgn1, unsigned long pgn2, unsigned long pgn3, Converter cv = NULL) + { + converter = cv; + numPgn = 3; + this->pgn = new unsigned long[3]; + this->pgn[0] = pgn1; + this->pgn[1] = pgn2; + this->pgn[2] = pgn3; + } + ConverterEntry(unsigned long pgn1, unsigned long pgn2, unsigned long pgn3, LConverter cv = NULL) + { + lconverter = cv; + numPgn = 3; + this->pgn = new unsigned long[3]; + this->pgn[0] = pgn1; + this->pgn[1] = pgn2; + this->pgn[2] = pgn3; + } + }; + typedef std::map ConverterMap; + ConverterMap converters; + +public: + /** + * register a converter + * each of the converter functions must be registered in the constructor + **/ + void registerConverter(unsigned long pgn, Converter converter) + { + ConverterEntry e(pgn, converter); + converters[String(pgn)] = e; + } + void registerConverter(unsigned long pgn, LConverter converter) + { + ConverterEntry e(pgn, converter); + converters[String(pgn)] = e; + } + void registerConverter(unsigned long pgn, String sentence, Converter converter) + { + ConverterEntry e(pgn, converter); + converters[sentence] = e; + } + void registerConverter(unsigned long pgn, String sentence, LConverter converter) + { + ConverterEntry e(pgn, converter); + converters[sentence] = e; + } + void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, Converter converter) + { + ConverterEntry e(pgn, pgn2, converter); + converters[sentence] = e; + } + void registerConverter(unsigned long pgn, unsigned long pgn2, String sentence, LConverter converter) + { + ConverterEntry e(pgn, pgn2, converter); + converters[sentence] = e; + } + + bool handleMessage(String code, const Msg &msg, T *base) + { + auto it = converters.find(code); + if (it != converters.end()) + { + (it->second).count++; + if (it->second.converter) + { + //call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members + ((*base).*((it->second).converter))(msg); + } + else + { + (*(it->second).lconverter)(msg, base); + } + } + else + { + return false; + } + return true; + } + + virtual unsigned long *handledPgns() + { + //for now max 3 pgns per converter + unsigned long *rt = new unsigned long[converters.size() * 3 + 1]; + int idx = 0; + for (auto it = converters.begin(); + it != converters.end(); it++) + { + for (int i = 0; i < it->second.numPgn && i < 3; i++) + { + bool found = false; + for (int e = 0; e < idx; e++) + { + if (rt[e] == it->second.pgn[i]) + { + found = true; + break; + } + } + if (!found) + { + rt[idx] = it->second.pgn[i]; + idx++; + } + } + } + rt[idx] = 0; + return rt; + } + + int numConverters(){ + return converters.size(); + } +}; +#endif \ No newline at end of file diff --git a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp index fa6d15c..2544cc6 100644 --- a/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp +++ b/lib/nmea0183ton2k/NMEA0183DataToN2K.cpp @@ -1,5 +1,6 @@ #include "NMEA0183DataToN2K.h" #include "NMEA0183Messages.h" +#include "NMEA0183ConverterList.h" NMEA0183DataToN2K::NMEA0183DataToN2K(GwLog *logger, GwBoatData *boatData,N2kSender callback) { this->sender = callback; @@ -13,117 +14,62 @@ bool NMEA0183DataToN2K::parseAndSend(const char *buffer, int sourceId) { return false; } +class NMEA0183DataToN2KFunctions : public NMEA0183DataToN2K +{ +private: + double dummy = 0; + ConverterList converters; + void createBoatData() + { + } + void convertRMB(const tNMEA0183Msg &msg) + { + LOG_DEBUG(GwLog::DEBUG + 1, "convert RMB"); + } +//shortcut for lambda converters +#define CVL [](const tNMEA0183Msg &msg, NMEA0183DataToN2KFunctions *p) -> void + void registerConverters() + { + converters.registerConverter(129283UL, String(F("RMB")), &NMEA0183DataToN2KFunctions::convertRMB); + converters.registerConverter( + 123UL, String(F("RMC")), CVL + { + p->dummy++; + p->logger->logDebug(GwLog::DEBUG, "RMC converter"); + }); + } -class NMEA0183DataToN2KFunctions : public NMEA0183DataToN2K{ - public: - typedef void (NMEA0183DataToN2KFunctions::*Converter)(const tNMEA0183Msg &msg); - private: - class ConverterEntry +public: + virtual bool parseAndSend(const char *buffer, int sourceId) + { + LOG_DEBUG(GwLog::DEBUG + 1, "NMEA0183DataToN2K[%d] parsing %s", sourceId, buffer) + tNMEA0183Msg msg; + if (!msg.SetMessage(buffer)) { - public: - unsigned long count = 0; - unsigned long *pgn; - unsigned int numPgn=0; - Converter converter; - ConverterEntry(){ - pgn=NULL; - converter=NULL; - } - ConverterEntry(unsigned long pgn,Converter cv = NULL) { - converter = cv; - numPgn=1; - this->pgn=new unsigned long[1]; - this->pgn[0]=pgn; - } - ConverterEntry(unsigned long pgn1,unsigned long pgn2,Converter cv = NULL) { - converter = cv; - numPgn=2; - this->pgn=new unsigned long[2]; - this->pgn[0]=pgn1; - this->pgn[1]=pgn2; - } - ConverterEntry(unsigned long pgn1,unsigned long pgn2,unsigned long pgn3,Converter cv = NULL) { - converter = cv; - numPgn=3; - this->pgn=new unsigned long[3]; - this->pgn[0]=pgn1; - this->pgn[1]=pgn2; - this->pgn[2]=pgn3; - } - }; - typedef std::map ConverterMap; - ConverterMap converters; + LOG_DEBUG(GwLog::DEBUG, "NMEA0183DataToN2K[%d] invalid message %s", sourceId, buffer) + return false; + } + String code = msg.MessageCode(); + bool rt = converters.handleMessage(code, msg, this); + if (!rt) + { + LOG_DEBUG(GwLog::DEBUG, "NMEA0183DataToN2K[%d] no handler for %s", sourceId, buffer); + } + return rt; + } - /** - * register a converter - * each of the converter functions must be registered in the constructor - **/ - void registerConverter(unsigned long pgn, String sentence,Converter converter) - { - ConverterEntry e(pgn,converter); - converters[sentence] = e; - } - void registerConverter(unsigned long pgn,unsigned long pgn2, String sentence,Converter converter) - { - ConverterEntry e(pgn,pgn2,converter); - converters[sentence] = e; - } + virtual unsigned long *handledPgns() + { + return converters.handledPgns(); + } - void convertRMB(const tNMEA0183Msg &msg){ - LOG_DEBUG(GwLog::DEBUG+1,"convert RMB"); - } - public: - virtual bool parseAndSend(const char *buffer, int sourceId) { - LOG_DEBUG(GwLog::DEBUG+1,"NMEA0183DataToN2K[%d] parsing %s",sourceId,buffer) - tNMEA0183Msg msg; - if (! msg.SetMessage(buffer)){ - LOG_DEBUG(GwLog::DEBUG,"NMEA0183DataToN2K[%d] invalid message %s",sourceId,buffer) - return false; - } - String code=String(msg.MessageCode()); - ConverterMap::iterator it=converters.find(code); - if (it != converters.end()){ - (it->second).count++; - //call to member function - see e.g. https://isocpp.org/wiki/faq/pointers-to-members - ((*this).*((it->second).converter))(msg); - } - else{ - LOG_DEBUG(GwLog::DEBUG,"NMEA0183DataToN2K[%d] no handler for %s",sourceId,code.c_str()); - return false; - } - return true; - } - virtual unsigned long *handledPgns() - { - logger->logString("CONV: # %d handled PGNS", (int)converters.size()); - //for now max 3 pgns per converter - unsigned long *rt = new unsigned long[converters.size() *3 + 1]; - int idx = 0; - for (ConverterMap::iterator it = converters.begin(); - it != converters.end(); it++) - { - for (int i=0;isecond.numPgn && i < 3;i++){ - bool found=false; - for (int e=0;esecond.pgn[i]){ - found=true; - break; - } - } - if (! found){ - rt[idx] = it->second.pgn[i]; - idx++; - } - } - } - rt[idx] = 0; - return rt; - } - NMEA0183DataToN2KFunctions(GwLog *logger,GwBoatData *boatData,N2kSender callback) - :NMEA0183DataToN2K(logger,boatData,callback){ - registerConverter(129283UL,String(F("RMB")),&NMEA0183DataToN2KFunctions::convertRMB); - } - + NMEA0183DataToN2KFunctions(GwLog *logger, GwBoatData *boatData, N2kSender callback) + : NMEA0183DataToN2K(logger, boatData, callback) + { + createBoatData(); + registerConverters(); + LOG_DEBUG(GwLog::LOG, "NMEA0183DataToN2KFunctions: registered %d converters", converters.numConverters()); + } }; NMEA0183DataToN2K* NMEA0183DataToN2K::create(GwLog *logger,GwBoatData *boatData,N2kSender callback){