diff --git a/README.md b/README.md index 73fa960c..d3bcbbef 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Please submit PR's using 'dev' as the base branch! For minor changes just submit your PR and I'll try to review it, but for anything more 'impactful' please open an Issue first and start a discussion. Is better to sound out what it is you want to achieve first, and try to come to a consensus on what the best approach is, especially when it impacts the structure or architecture of this codebase. Here are some general principals you should try to adhere to: -* Keep it simple. Please, don't think like a high-level lang programmer. Think embedded, and keep code concise, without any unecessary layers. +* Keep it simple. Please, don't think like a high-level lang programmer. Think embedded, and keep code concise, without any unnecessary layers. * No dynamic memory allocation, except during setup/begin functions. * Use the same brace and indenting style that's in the core source modules. (A .clang-format is prob going to be added soon, but please do NOT retroactively re-format existing code. This just creates unnecessary diffs that make finding problems harder) @@ -106,7 +106,7 @@ There are a number of fairly major features in the pipeline, with no particular - [ ] Core + Apps: support for LZW message compression - [ ] Core: dynamic CR (Coding Rate) for weak vs strong hops - [ ] Core: new framework for hosting multiple virtual nodes on one physical device -- [ ] V2 protocol spec: discussion and concensus around V2 packet protocol, including path hashes, new encryption specs, etc +- [ ] V2 protocol spec: discussion and consensus around V2 packet protocol, including path hashes, new encryption specs, etc ## 📞 Get Support diff --git a/src/helpers/esp32/SerialWifiInterface.cpp b/src/helpers/esp32/SerialWifiInterface.cpp index 2df9980a..462e3ecc 100644 --- a/src/helpers/esp32/SerialWifiInterface.cpp +++ b/src/helpers/esp32/SerialWifiInterface.cpp @@ -43,6 +43,15 @@ bool SerialWifiInterface::isWriteBusy() const { return false; } +bool SerialWifiInterface::hasReceivedFrameHeader() { + return received_frame_header.type != 0 && received_frame_header.length != 0; +} + +void SerialWifiInterface::resetReceivedFrameHeader() { + received_frame_header.type = 0; + received_frame_header.length = 0; +} + size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { // check if new client connected auto newClient = server.available(); @@ -54,6 +63,9 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { // switch active connection to new client client = newClient; + + // forget received frame header + resetReceivedFrameHeader(); } @@ -86,13 +98,69 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { send_queue[i] = send_queue[i + 1]; } } else { - int len = client.available(); - if (len > 0) { - uint8_t buf[MAX_FRAME_SIZE + 4]; - client.readBytes(buf, len); - memcpy(dest, buf+3, len-3); // remove header (don't even check ... problems are on the other dir) - return len-3; + + // check if we are waiting for a frame header + if(!hasReceivedFrameHeader()){ + + // make sure we have received enough bytes for a frame header + // 3 bytes frame header = (1 byte frame type) + (2 bytes frame length as unsigned 16-bit little endian) + int frame_header_length = 3; + if(client.available() >= frame_header_length){ + + // read frame header + client.readBytes(&received_frame_header.type, 1); + client.readBytes((uint8_t*)&received_frame_header.length, 2); + + } + } + + // check if we have received a frame header + if(hasReceivedFrameHeader()){ + + // make sure we have received enough bytes for the required frame length + int available = client.available(); + int frame_type = received_frame_header.type; + int frame_length = received_frame_header.length; + if(frame_length > available){ + WIFI_DEBUG_PRINTLN("Waiting for %d more bytes", frame_length - available); + return 0; + } + + // skip frames that are larger than MAX_FRAME_SIZE + if(frame_length > MAX_FRAME_SIZE){ + WIFI_DEBUG_PRINTLN("Skipping frame: length=%d is larger than MAX_FRAME_SIZE=%d", frame_length, MAX_FRAME_SIZE); + while(frame_length > 0){ + uint8_t skip[1]; + int skipped = client.read(skip, 1); + frame_length -= skipped; + } + resetReceivedFrameHeader(); + return 0; + } + + // skip frames that are not expected type + // '<' is 0x3c which indicates a frame sent from app to radio + if(frame_type != '<'){ + WIFI_DEBUG_PRINTLN("Skipping frame: type=0x%x is unexpected", frame_type); + while(frame_length > 0){ + uint8_t skip[1]; + int skipped = client.read(skip, 1); + frame_length -= skipped; + } + resetReceivedFrameHeader(); + return 0; + } + + // read frame data to provided buffer + client.readBytes(dest, frame_length); + + // ready for next frame + resetReceivedFrameHeader(); + return frame_length; + + } + } } diff --git a/src/helpers/esp32/SerialWifiInterface.h b/src/helpers/esp32/SerialWifiInterface.h index 2b6c6edd..19291497 100644 --- a/src/helpers/esp32/SerialWifiInterface.h +++ b/src/helpers/esp32/SerialWifiInterface.h @@ -12,11 +12,18 @@ class SerialWifiInterface : public BaseSerialInterface { WiFiServer server; WiFiClient client; + struct FrameHeader { + uint8_t type; + uint16_t length; + }; + struct Frame { uint8_t len; uint8_t buf[MAX_FRAME_SIZE]; }; + FrameHeader received_frame_header; + #define FRAME_QUEUE_SIZE 4 int recv_queue_len; Frame recv_queue[FRAME_QUEUE_SIZE]; @@ -33,6 +40,8 @@ public: _isEnabled = false; _last_write = 0; send_queue_len = recv_queue_len = 0; + received_frame_header.type = 0; + received_frame_header.length = 0; } void begin(int port); @@ -47,6 +56,9 @@ public: size_t writeFrame(const uint8_t src[], size_t len) override; size_t checkRecvFrame(uint8_t dest[]) override; + + bool hasReceivedFrameHeader(); + void resetReceivedFrameHeader(); }; #if WIFI_DEBUG_LOGGING && ARDUINO diff --git a/src/helpers/radiolib/CustomLR1110.h b/src/helpers/radiolib/CustomLR1110.h index 2e536de5..e4332013 100644 --- a/src/helpers/radiolib/CustomLR1110.h +++ b/src/helpers/radiolib/CustomLR1110.h @@ -10,7 +10,7 @@ class CustomLR1110 : public LR1110 { size_t getPacketLength(bool update) override { size_t len = LR1110::getPacketLength(update); if (len == 0 && getIrqStatus() & RADIOLIB_LR11X0_IRQ_HEADER_ERR) { - // we've just recieved a corrupted packet + // we've just received a corrupted packet // this may have triggered a bug causing subsequent packets to be shifted // call standby() to return radio to known-good state // recvRaw will call startReceive() to restart rx diff --git a/src/helpers/sensors/EnvironmentSensorManager.cpp b/src/helpers/sensors/EnvironmentSensorManager.cpp index 77a791bd..b7238def 100644 --- a/src/helpers/sensors/EnvironmentSensorManager.cpp +++ b/src/helpers/sensors/EnvironmentSensorManager.cpp @@ -615,6 +615,7 @@ void EnvironmentSensorManager::rakGPSInit(){ MESH_DEBUG_PRINTLN("No GPS found"); gps_active = false; gps_detected = false; + Serial1.end(); return; } @@ -653,8 +654,7 @@ bool EnvironmentSensorManager::gpsIsAwake(uint8_t ioPin){ _location = &RAK12500_provider; return true; - } - else if(Serial1){ + } else if (Serial1.available()) { MESH_DEBUG_PRINTLN("Serial GPS init correctly and is turned on"); if(PIN_GPS_EN){ gpsResetPin = PIN_GPS_EN; @@ -664,6 +664,8 @@ bool EnvironmentSensorManager::gpsIsAwake(uint8_t ioPin){ gps_detected = true; return true; } + + pinMode(ioPin, INPUT); MESH_DEBUG_PRINTLN("GPS did not init with this IO pin... try the next"); return false; } diff --git a/variants/heltec_v3/platformio.ini b/variants/heltec_v3/platformio.ini index 36c6386f..dcb2873c 100644 --- a/variants/heltec_v3/platformio.ini +++ b/variants/heltec_v3/platformio.ini @@ -189,6 +189,7 @@ build_flags = -D WIFI_DEBUG_LOGGING=1 -D WIFI_SSID='"myssid"' -D WIFI_PWD='"mypwd"' + -D OFFLINE_QUEUE_SIZE=256 ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${Heltec_lora32_v3.build_src_filter} @@ -341,6 +342,7 @@ build_flags = -D WIFI_DEBUG_LOGGING=1 -D WIFI_SSID='"myssid"' -D WIFI_PWD='"mypwd"' + -D OFFLINE_QUEUE_SIZE=256 ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${Heltec_lora32_v3.build_src_filter} diff --git a/variants/heltec_v4/platformio.ini b/variants/heltec_v4/platformio.ini index c26a5bc6..ecfd7889 100644 --- a/variants/heltec_v4/platformio.ini +++ b/variants/heltec_v4/platformio.ini @@ -176,6 +176,7 @@ build_flags = -D WIFI_DEBUG_LOGGING=1 -D WIFI_SSID='"myssid"' -D WIFI_PWD='"mypwd"' + -D OFFLINE_QUEUE_SIZE=256 ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${Heltec_lora32_v4.build_src_filter} diff --git a/variants/thinknode_m6/platformio.ini b/variants/thinknode_m6/platformio.ini index 16394ced..db22073c 100644 --- a/variants/thinknode_m6/platformio.ini +++ b/variants/thinknode_m6/platformio.ini @@ -90,7 +90,6 @@ build_src_filter = ${ThinkNode_M6.build_src_filter} + + +<../examples/companion_radio/*.cpp> - +<../examples/companion_radio/ui-new/*.cpp> lib_deps = ${ThinkNode_M6.lib_deps} densaugeo/base64 @ ~1.4.0 @@ -113,7 +112,6 @@ build_src_filter = ${ThinkNode_M6.build_src_filter} + + +<../examples/companion_radio/*.cpp> - +<../examples/companion_radio/ui-new/*.cpp> lib_deps = ${ThinkNode_M6.lib_deps} densaugeo/base64 @ ~1.4.0 diff --git a/variants/xiao_s3_wio/platformio.ini b/variants/xiao_s3_wio/platformio.ini index 8979edc2..22bb4090 100644 --- a/variants/xiao_s3_wio/platformio.ini +++ b/variants/xiao_s3_wio/platformio.ini @@ -195,6 +195,29 @@ lib_deps = densaugeo/base64 @ ~1.4.0 adafruit/Adafruit SSD1306 @ ^2.5.13 +[env:Xiao_S3_WIO_companion_radio_wifi] +extends = Xiao_S3_WIO +build_src_filter = ${Xiao_S3_WIO.build_src_filter} + + + + + + + +<../examples/companion_radio/*.cpp> +build_flags = + ${Xiao_S3_WIO.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D OFFLINE_QUEUE_SIZE=256 + -D WIFI_DEBUG_LOGGING=1 + -D WIFI_SSID='"myssid"' + -D WIFI_PWD='"password"' + ; -D BLE_DEBUG_LOGGING=1 + ; -D MESH_PACKET_LOGGING=1 + ; -D MESH_DEBUG=1 +lib_deps = + ${Xiao_S3_WIO.lib_deps} + densaugeo/base64 @ ~1.4.0 + [env:Xiao_S3_WIO_sensor] extends = Xiao_S3_WIO build_src_filter = ${Xiao_S3_WIO.build_src_filter}