diff --git a/lib/channel/GwChannelList.cpp b/lib/channel/GwChannelList.cpp index 5465ea9..2acbdd5 100644 --- a/lib/channel/GwChannelList.cpp +++ b/lib/channel/GwChannelList.cpp @@ -58,6 +58,64 @@ void GwChannelList::allChannels(ChannelAction action){ action(*it); } } + +void GwChannelList::addSerial(int id,const String &mode,int rx,int tx){ + if (id != SERIAL1_CHANNEL_ID && id != SERIAL2_CHANNEL_ID){ + logger->logDebug(GwLog::ERROR,"trying to set up an unknown serial channel: %d",id); + return; + } + if (rx < 0 && tx < 0){ + logger->logDebug(GwLog::ERROR,"useless config for serial %d: both rx/tx undefined"); + return; + } + String cfgName; + bool canRead=false; + bool canWrite=false; + if (mode == "BI"){ + cfgName=(id==SERIAL1_CHANNEL_ID)?config->receiveSerial:config->receiveSerial2; + canRead=config->getBool(cfgName); + cfgName=(id==SERIAL2_CHANNEL_ID)?config->sendSerial:config->sendSerial2; + canWrite=config->getBool(cfgName); + } + if (mode == "TX"){ + canWrite=true; + } + if (mode == "RX"){ + canRead=true; + } + if (mode == "UNI"){ + cfgName=(id == SERIAL1_CHANNEL_ID)?config->serialDirection:config->serial2Dir; + String cfgMode=config->getString(cfgName); + if (cfgMode == "receive"){ + canRead=true; + } + if (cfgMode == "send"){ + canWrite=true; + } + } + if (rx < 0) canRead=false; + if (tx < 0) canWrite=false; + HardwareSerial *serialStream=(id == SERIAL1_CHANNEL_ID)?&Serial1:&Serial2; + LOG_DEBUG(GwLog::DEBUG,"serial set up: mode=%s,rx=%d,canRead=%d,tx=%d,canWrite=%d", + mode.c_str(),rx,(int)canRead,tx,(int)canWrite); + serialStream->begin(config->getInt(config->serialBaud,115200),SERIAL_8N1,rx,tx); + GwSerial *serial = new GwSerial(logger, serialStream, id, canRead); + LOG_DEBUG(GwLog::LOG, "starting serial %d ", id); + GwChannel *channel = new GwChannel(logger, (id == SERIAL1_CHANNEL_ID) ? "SER" : "SER2", id); + channel->setImpl(serial); + channel->begin( + canRead || canWrite, + canWrite, + canRead, + config->getString((id == SERIAL1_CHANNEL_ID) ? config->serialReadF : config->serial2ReadF), + config->getString((id == SERIAL1_CHANNEL_ID) ? config->serialWriteF : config->serial2WriteF), + false, + config->getBool((id == SERIAL1_CHANNEL_ID) ? config->serialToN2k : config->serial2ToN2k), + false, + false); + LOG_DEBUG(GwLog::LOG, "%s", channel->toString().c_str()); + theChannels.push_back(channel); +} void GwChannelList::begin(bool fallbackSerial){ LOG_DEBUG(GwLog::DEBUG,"GwChannelList::begin"); GwChannel *channel=NULL; @@ -102,57 +160,25 @@ void GwChannelList::begin(bool fallbackSerial){ theChannels.push_back(channel); //serial 1 - bool serCanRead=true; - bool serCanWrite=true; - int serialrx=-1; - int serialtx=-1; - #ifdef GWSERIAL_MODE - #ifdef GWSERIAL_TX - serialtx=GWSERIAL_TX; - #endif - #ifdef GWSERIAL_RX - serialrx=GWSERIAL_RX; - #endif - if (serialrx != -1 && serialtx != -1){ - serialMode=GWSERIAL_MODE; - } + #ifndef GWSERIAL_TX + #define GWSERIAL_TX -1 + #endif + #ifndef GWSERIAL_RX + #define GWSERIAL_RX -1 + #endif + #ifdef GWSERIAL_MODE + addSerial(SERIAL1_CHANNEL_ID,GWSERIAL_MODE,GWSERIAL_RX,GWSERIAL_TX); + #endif + //serial 2 + #ifndef GWSERIAL2_TX + #define GWSERIAL2_TX -1 + #endif + #ifndef GWSERIAL2_RX + #define GWSERIAL2_RX -1 + #endif + #ifdef GWSERIAL2_MODE + addSerial(SERIAL2_CHANNEL_ID,GWSERIAL2_MODE,GWSERIAL2_RX,GWSERIAL2_TX); #endif - //the serial direction is from the config (only valid for mode UNI) - String serialDirection=config->getString(config->serialDirection); - //we only consider the direction if mode is UNI - if (serialMode != String("UNI")){ - serialDirection=String(""); - //if mode is UNI it depends on the selection - serCanRead=config->getBool(config->receiveSerial); - serCanWrite=config->getBool(config->sendSerial); - } - if (serialDirection == "receive" || serialDirection == "off" || serialMode == "RX") serCanWrite=false; - if (serialDirection == "send" || serialDirection == "off" || serialMode == "TX") serCanRead=false; - LOG_DEBUG(GwLog::DEBUG,"serial set up: mode=%s,direction=%s,rx=%d,tx=%d", - serialMode.c_str(),serialDirection.c_str(),serialrx,serialtx - ); - if (serialtx != -1 || serialrx != -1 ){ - LOG_DEBUG(GwLog::LOG,"creating serial interface rx=%d, tx=%d",serialrx,serialtx); - Serial1.begin(config->getInt(config->serialBaud,115200),SERIAL_8N1,serialrx,serialtx); - GwSerial *serial=new GwSerial(logger,&Serial1,SERIAL1_CHANNEL_ID,serCanRead); - LOG_DEBUG(GwLog::LOG,"starting serial1 "); - channel=new GwChannel(logger,"SER",SERIAL1_CHANNEL_ID); - channel->setImpl(serial); - channel->begin( - serCanRead || serCanWrite, - serCanWrite, - serCanRead, - config->getString(config->serialReadF), - config->getString(config->serialWriteF), - false, - config->getBool(config->serialToN2k), - false, - false - ); - LOG_DEBUG(GwLog::LOG,"%s",channel->toString().c_str()); - theChannels.push_back(channel); - } - //tcp client bool tclEnabled=config->getBool(config->tclEnabled); channel=new GwChannel(logger,"TCPClient",TCP_CLIENT_CHANNEL_ID); diff --git a/lib/channel/GwChannelList.h b/lib/channel/GwChannelList.h index 1cca126..c4072e2 100644 --- a/lib/channel/GwChannelList.h +++ b/lib/channel/GwChannelList.h @@ -29,6 +29,7 @@ class GwChannelList{ GwSocketServer *sockets; GwTcpClient *client; String serialMode=F("NONE"); + void addSerial(int id,const String &mode,int rx,int tx); public: GwChannelList(GwLog *logger, GwConfigHandler *config); typedef std::function ChannelAction; diff --git a/src/main.cpp b/src/main.cpp index 5521501..877ed98 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -427,7 +427,7 @@ class CapabilitiesRequest : public GwRequestMessage{ protected: virtual void processRequest(){ int numCapabilities=userCodeHandler.getCapabilities()->size(); - GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+6)); + GwJsonDocument json(JSON_OBJECT_SIZE(numCapabilities*3+8)); for (auto it=userCodeHandler.getCapabilities()->begin(); it != userCodeHandler.getCapabilities()->end();it++){ json[it->first]=it->second; @@ -438,6 +438,12 @@ class CapabilitiesRequest : public GwRequestMessage{ String serial(F("NONE")); #endif json["serialmode"]=serial; + #ifdef GWSERIAL2_MODE + String serial2(F(GWSERIAL2_MODE)); + #else + String serial2(F("NONE")); + #endif + json["serial2mode"]=serial2; #ifdef GWBUTTON_PIN json["hardwareReset"]="true"; #endif diff --git a/web/config.json b/web/config.json index cee92ae..78e3196 100644 --- a/web/config.json +++ b/web/config.json @@ -392,6 +392,128 @@ ] }, "category": "serial port" + } + , + { + "name": "serial2Dir", + "label": "serial2 direction", + "type": "list", + "default": "receive", + "list": [ + "send", + "receive", + "off" + ], + "description": "use the serial2 port to send or receive data", + "capabilities": { + "serial2mode": [ + "UNI" + ] + }, + "category": "serial2 port" + }, + { + "name": "serial2Baud", + "label": "serial2 baud rate", + "type": "list", + "default": "115200", + "description": "baud rate for the serial port 2", + "list": [ + 1200, + 2400, + 4800, + 9600, + 14400, + 19200, + 28800, + 38400, + 57600, + 115200, + 230400, + 460800 + ], + "capabilities": { + "serial2mode": [ + "RX", + "TX", + "UNI", + "BI" + ] + }, + "category": "serial2 port" + }, + { + "name": "sendSerial2", + "label": "NMEA to Serial2", + "type": "boolean", + "default": "true", + "description": "send out NMEA data on the serial port 2", + "capabilities": { + "serial2mode": [ + "TX", + "BI" + ] + }, + "category": "serial2 port" + }, + { + "name": "receiveSerial2", + "label": "NMEA from Serial2", + "type": "boolean", + "default": "true", + "description": "receive NMEA data on the serial port 2", + "capabilities": { + "serial2mode": [ + "RX", + "BI" + ] + }, + "category": "serial2 port" + }, + { + "name": "serial2ToN2k", + "label": "serial2 to NMEA2000", + "type": "boolean", + "default": "true", + "description": "convert NMEA0183 from the serial port 2 to NMEA2000", + "capabilities": { + "serial2mode": [ + "RX", + "BI", + "UNI" + ] + }, + "category": "serial2 port" + }, + { + "name": "serial2ReadF", + "label": "serial2 read Filter", + "type": "filter", + "default": "", + "description": "filter for NMEA0183 data when reading from serial2\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB", + "capabilities": { + "serial2mode": [ + "RX", + "BI", + "UNI" + ] + }, + "category": "serial2 port" + }, + { + "name": "serial2WriteF", + "label": "serial2 write Filter", + "type": "filter", + "default": "", + "description": "filter for NMEA0183 data when writing to serial2\nselect aison|aisoff, set a whitelist or a blacklist with NMEA sentences like RMC,RMB", + "capabilities": { + "serial2mode": [ + "TX", + "BI", + "UNI" + ] + }, + "category": "serial2 port" }, { "name": "serverPort",