From b8e06bf824e32d94addabfb7ee9c2739c9bfab90 Mon Sep 17 00:00:00 2001 From: helgeerbe Date: Mon, 17 Apr 2023 22:18:20 +0200 Subject: [PATCH] ve.diect with hex asnync messages ignore async hex messeage on older devices --- .../VeDirectFrameHandler.cpp | 33 ++++++++++++++----- .../VeDirectFrameHandler.h | 6 +++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp index 676b265d7..d87c5a388 100644 --- a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp +++ b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp @@ -60,6 +60,7 @@ VeDirectFrameHandler::VeDirectFrameHandler() : _state(IDLE), _checksum(0), _textPointer(0), + _hexSize(0), _name(""), _value(""), _tmpFrame(), @@ -99,7 +100,9 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte) { //if (mStop) return; if ( (inbyte == ':') && (_state != CHECKSUM) ) { - _state = RECORD_HEX; + _prevState = _state; //hex frame can interrupt TEXT + _state = RECORD_HEX; + _hexSize = 0; } if (_state != RECORD_HEX) { _checksum += inbyte; @@ -177,10 +180,7 @@ void VeDirectFrameHandler::rxData(uint8_t inbyte) break; } case RECORD_HEX: - if (hexRxEvent(inbyte)) { - _checksum = 0; - _state = IDLE; - } + _state = hexRxEvent(inbyte); break; } } @@ -279,10 +279,27 @@ void VeDirectFrameHandler::logE(const char * module, const char * error) { /* * hexRxEvent - * This function included for continuity and possible future use. + * This function records hex answers or async messages */ -bool VeDirectFrameHandler::hexRxEvent(uint8_t inbyte) { - return true; // stubbed out for future +int VeDirectFrameHandler::hexRxEvent(uint8_t inbyte) { + int ret=RECORD_HEX; // default - continue recording until end of frame + + switch (inbyte) { + case '\n': + // restore previous state + ret=_prevState; + break; + + default: + _hexSize++; + if (_hexSize>=VE_MAX_HEX_LEN) { // oops -buffer overflow - something went wrong, we abort + logE(MODULE,"hexRx buffer overflow - aborting read"); + _hexSize=0; + ret=IDLE; + } + } + + return ret; } bool VeDirectFrameHandler::isDataValid() { diff --git a/lib/VeDirectFrameHandler/VeDirectFrameHandler.h b/lib/VeDirectFrameHandler/VeDirectFrameHandler.h index d96f6f827..d02024a9d 100644 --- a/lib/VeDirectFrameHandler/VeDirectFrameHandler.h +++ b/lib/VeDirectFrameHandler/VeDirectFrameHandler.h @@ -23,6 +23,8 @@ #define VE_MAX_NAME_LEN 9 // VE.Direct Protocol: max name size is 9 including /0 #define VE_MAX_VALUE_LEN 33 // VE.Direct Protocol: max value size is 33 including /0 +#define VE_MAX_HEX_LEN 100 // Maximum size of hex frame - max payload 34 byte (=68 char) + safe buffer + typedef struct { uint16_t PID; // product id @@ -69,12 +71,14 @@ class VeDirectFrameHandler { void textRxEvent(char *, char *); void frameEndEvent(bool); // copy temp struct to public struct void logE(const char *, const char *); - bool hexRxEvent(uint8_t); + int hexRxEvent(uint8_t); //bool mStop; // not sure what Victron uses this for, not using int _state; // current state + int _prevState; // previous state uint8_t _checksum; // checksum value char * _textPointer; // pointer to the private buffer we're writing to, name or value + int _hexSize; // length of hex buffer char _name[VE_MAX_VALUE_LEN]; // buffer for the field name char _value[VE_MAX_VALUE_LEN]; // buffer for the field value veStruct _tmpFrame{}; // private struct for received name and value pairs