Merge pull request #1308 from liamcottle/fix/wifi-interface-frames

Fix: WiFi Interface Frame Parsing
This commit is contained in:
ripplebiz 2026-01-04 16:19:57 +11:00 committed by GitHub
commit 09005fa455
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 86 additions and 6 deletions

View file

@ -43,6 +43,15 @@ bool SerialWifiInterface::isWriteBusy() const {
return false; 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[]) { size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) {
// check if new client connected // check if new client connected
auto newClient = server.available(); auto newClient = server.available();
@ -55,6 +64,9 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) {
// switch active connection to new client // switch active connection to new client
client = newClient; client = newClient;
// forget received frame header
resetReceivedFrameHeader();
} }
if (client.connected()) { if (client.connected()) {
@ -86,13 +98,69 @@ size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) {
send_queue[i] = send_queue[i + 1]; send_queue[i] = send_queue[i + 1];
} }
} else { } else {
int len = client.available();
if (len > 0) { // check if we are waiting for a frame header
uint8_t buf[MAX_FRAME_SIZE + 4]; if(!hasReceivedFrameHeader()){
client.readBytes(buf, len);
memcpy(dest, buf+3, len-3); // remove header (don't even check ... problems are on the other dir) // make sure we have received enough bytes for a frame header
return len-3; // 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;
}
} }
} }

View file

@ -12,11 +12,18 @@ class SerialWifiInterface : public BaseSerialInterface {
WiFiServer server; WiFiServer server;
WiFiClient client; WiFiClient client;
struct FrameHeader {
uint8_t type;
uint16_t length;
};
struct Frame { struct Frame {
uint8_t len; uint8_t len;
uint8_t buf[MAX_FRAME_SIZE]; uint8_t buf[MAX_FRAME_SIZE];
}; };
FrameHeader received_frame_header;
#define FRAME_QUEUE_SIZE 4 #define FRAME_QUEUE_SIZE 4
int recv_queue_len; int recv_queue_len;
Frame recv_queue[FRAME_QUEUE_SIZE]; Frame recv_queue[FRAME_QUEUE_SIZE];
@ -33,6 +40,8 @@ public:
_isEnabled = false; _isEnabled = false;
_last_write = 0; _last_write = 0;
send_queue_len = recv_queue_len = 0; send_queue_len = recv_queue_len = 0;
received_frame_header.type = 0;
received_frame_header.length = 0;
} }
void begin(int port); void begin(int port);
@ -47,6 +56,9 @@ public:
size_t writeFrame(const uint8_t src[], size_t len) override; size_t writeFrame(const uint8_t src[], size_t len) override;
size_t checkRecvFrame(uint8_t dest[]) override; size_t checkRecvFrame(uint8_t dest[]) override;
bool hasReceivedFrameHeader();
void resetReceivedFrameHeader();
}; };
#if WIFI_DEBUG_LOGGING && ARDUINO #if WIFI_DEBUG_LOGGING && ARDUINO