From 23d6b815f5d38fdc0f23666689b14e92b999a226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 22 Dec 2022 17:25:15 +0100 Subject: [PATCH] WIP: ProtobufAPI in SerialModule --- src/modules/SerialModule.cpp | 47 +++++++++++++++++++++++++++--------- src/modules/SerialModule.h | 5 +++- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/modules/SerialModule.cpp b/src/modules/SerialModule.cpp index 33bae7746..94f48aa9a 100644 --- a/src/modules/SerialModule.cpp +++ b/src/modules/SerialModule.cpp @@ -49,17 +49,20 @@ #define RXD2 16 #define TXD2 17 #define RX_BUFFER 128 +#define STRING_MAX Constants_DATA_PAYLOAD_LEN #define TIMEOUT 250 #define BAUD 38400 #define ACK 1 +// API: Defaulting to the formerly removed phone_timeout_secs value of 15 minutes +#define SERIAL_CONNECTION_TIMEOUT (15 * 60) * 1000UL + SerialModule *serialModule; SerialModuleRadio *serialModuleRadio; -SerialModule::SerialModule() : concurrency::OSThread("SerialModule") {} +SerialModule::SerialModule() : StreamAPI(&Serial2), concurrency::OSThread("SerialModule") {} -char serialBytes[Constants_DATA_PAYLOAD_LEN]; -size_t serialPayloadSize; +char serialStringChar[Constants_DATA_PAYLOAD_LEN]; SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") { @@ -80,6 +83,13 @@ SerialModuleRadio::SerialModuleRadio() : MeshModule("SerialModuleRadio") } } +// For the serial2 port we can't really detect if any client is on the other side, so instead just look for recent messages +bool SerialModule::checkIsConnected() +{ + uint32_t now = millis(); + return (now - lastContactMsec) < SERIAL_CONNECTION_TIMEOUT; +} + int32_t SerialModule::runOnce() { #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) @@ -178,19 +188,32 @@ int32_t SerialModule::runOnce() firstTime = 0; + // in API mode send rebooted sequence + if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) { + emitRebooted(); + } + } else { - // in NMEA mode send out GGA every 2 seconds, Don't read from Port - if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) { + if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) { + return StreamAPI::runOnce(); + } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) { + // in NMEA mode send out GGA every 2 seconds, Don't read from Port if (millis() - lastNmeaTime > 2000) { lastNmeaTime = millis(); printGGA(outbuf, nodeDB.getNode(myNodeInfo.my_node_num)->position); Serial2.printf("%s", outbuf); } } else { + String serialString; + while (Serial2.available()) { - serialPayloadSize = Serial2.readBytes(serialBytes, Constants_DATA_PAYLOAD_LEN); + serialString = Serial2.readString(); + serialString.toCharArray(serialStringChar, Constants_DATA_PAYLOAD_LEN); + serialModuleRadio->sendPayload(); + + DEBUG_MSG("Received: %s\n", serialStringChar); } } } @@ -221,8 +244,8 @@ void SerialModuleRadio::sendPayload(NodeNum dest, bool wantReplies) p->want_ack = ACK; - p->decoded.payload.size = serialPayloadSize; // You must specify how many bytes are in the reply - memcpy(p->decoded.payload.bytes, serialBytes, p->decoded.payload.size); + p->decoded.payload.size = strlen(serialStringChar); // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, serialStringChar, p->decoded.payload.size); service.sendToMesh(p); } @@ -231,6 +254,10 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) { #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) if (moduleConfig.serial.enabled) { + if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) { + // in API mode we don't care about stuff from radio. + return ProcessMessage::CONTINUE; + } auto &p = mp.decoded; // DEBUG_MSG("Received text msg self=0x%0x, from=0x%0x, to=0x%0x, id=%d, msg=%.*s\n", @@ -258,15 +285,13 @@ ProcessMessage SerialModuleRadio::handleReceived(const MeshPacket &mp) if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_DEFAULT || moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_SIMPLE) { - Serial2.write(p.payload.bytes, p.payload.size); + Serial2.printf("%s", p.payload.bytes); } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_TEXTMSG) { NodeInfo *node = nodeDB.getNode(getFrom(&mp)); String sender = (node && node->has_user) ? node->user.short_name : "???"; Serial2.println(); Serial2.printf("%s: %s", sender, p.payload.bytes); Serial2.println(); - } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_PROTO) { - // TODO this needs to be implemented } else if (moduleConfig.serial.mode == ModuleConfig_SerialConfig_Serial_Mode_NMEA) { // Decode the Payload some more Position scratch; diff --git a/src/modules/SerialModule.h b/src/modules/SerialModule.h index 0130bbe2d..b390d545e 100644 --- a/src/modules/SerialModule.h +++ b/src/modules/SerialModule.h @@ -8,7 +8,7 @@ #include "Router.h" #include -class SerialModule : private concurrency::OSThread +class SerialModule : public StreamAPI, private concurrency::OSThread { bool firstTime = 1; unsigned long lastNmeaTime = millis(); @@ -19,6 +19,9 @@ class SerialModule : private concurrency::OSThread protected: virtual int32_t runOnce() override; + + /// Check the current underlying physical link to see if the client is currently connected + virtual bool checkIsConnected() override; }; extern SerialModule *serialModule;