Move CRC check of multidata command from InverterAbstract to MultiDataCommand class

This commit is contained in:
Thomas Basler 2022-08-03 19:51:10 +02:00
parent 3abc7d7e3d
commit 037f7b9caf
12 changed files with 48 additions and 28 deletions

View File

@ -103,10 +103,12 @@ void HoymilesRadio::loop()
} else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) { } else if (verifyResult == FRAGMENT_RETRANSMIT_TIMEOUT) {
Serial.println(F("Retransmit timeout")); Serial.println(F("Retransmit timeout"));
_commandQueue.pop();
_busyFlag = false; _busyFlag = false;
} else if (verifyResult == FRAGMENT_CRC_ERROR) { } else if (verifyResult == FRAGMENT_HANDLE_ERROR) {
Serial.println(F("Packet CRC error")); Serial.println(F("Packet handling error"));
_commandQueue.pop();
_busyFlag = false; _busyFlag = false;
} else if (verifyResult > 0) { } else if (verifyResult > 0) {

View File

@ -9,8 +9,13 @@ AlarmDataCommand::AlarmDataCommand(uint64_t target_address, uint64_t router_addr
setTimeout(200); setTimeout(200);
} }
void AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) bool AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{ {
// Check CRC of whole payload
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
return false;
}
// Move all fragments into target buffer // Move all fragments into target buffer
uint8_t offs = 0; uint8_t offs = 0;
inverter->EventLog()->clearBuffer(); inverter->EventLog()->clearBuffer();
@ -19,4 +24,5 @@ void AlarmDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fra
offs += (fragment[i].len); offs += (fragment[i].len);
} }
inverter->EventLog()->setLastUpdate(millis()); inverter->EventLog()->setLastUpdate(millis());
return true;
} }

View File

@ -6,5 +6,5 @@ class AlarmDataCommand : public MultiDataCommand {
public: public:
AlarmDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0); AlarmDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
}; };

View File

@ -36,7 +36,7 @@ public:
virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no); virtual CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0; virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) = 0;
protected: protected:
uint8_t _payload[RF_LEN]; uint8_t _payload[RF_LEN];

View File

@ -58,6 +58,25 @@ CommandAbstract* MultiDataCommand::getRequestFrameCommand(uint8_t frame_no)
return &_cmdRequestFrame; return &_cmdRequestFrame;
} }
bool MultiDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{
// All fragments are available --> Check CRC
uint16_t crc = 0xffff, crcRcv;
for (uint8_t i = 0; i < max_fragment_id; i++) {
if (i == max_fragment_id - 1) {
// Last packet
crc = crc16(fragment[i].fragment, fragment[i].len - 2, crc);
crcRcv = (fragment[i].fragment[fragment[i].len - 2] << 8)
| (fragment[i].fragment[fragment[i].len - 1]);
} else {
crc = crc16(fragment[i].fragment, fragment[i].len, crc);
}
}
return crc == crcRcv;
}
void MultiDataCommand::udpateCRC() void MultiDataCommand::udpateCRC()
{ {
uint16_t crc = crc16(&_payload[10], 14); // From data_type till password uint16_t crc = crc16(&_payload[10], 14); // From data_type till password

View File

@ -13,6 +13,8 @@ public:
CommandAbstract* getRequestFrameCommand(uint8_t frame_no); CommandAbstract* getRequestFrameCommand(uint8_t frame_no);
virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
protected: protected:
void setDataType(uint8_t data_type); void setDataType(uint8_t data_type);
uint8_t getDataType(); uint8_t getDataType();

View File

@ -9,8 +9,13 @@ RealTimeRunDataCommand::RealTimeRunDataCommand(uint64_t target_address, uint64_t
setTimeout(200); setTimeout(200);
} }
void RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) bool RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{ {
// Check CRC of whole payload
if (!MultiDataCommand::handleResponse(inverter, fragment, max_fragment_id)) {
return false;
}
// Move all fragments into target buffer // Move all fragments into target buffer
uint8_t offs = 0; uint8_t offs = 0;
inverter->Statistics()->clearBuffer(); inverter->Statistics()->clearBuffer();
@ -19,4 +24,5 @@ void RealTimeRunDataCommand::handleResponse(InverterAbstract* inverter, fragment
offs += (fragment[i].len); offs += (fragment[i].len);
} }
inverter->Statistics()->setLastUpdate(millis()); inverter->Statistics()->setLastUpdate(millis());
return true;
} }

View File

@ -6,5 +6,5 @@ class RealTimeRunDataCommand : public MultiDataCommand {
public: public:
RealTimeRunDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0); RealTimeRunDataCommand(uint64_t target_address = 0, uint64_t router_address = 0, time_t time = 0);
virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
}; };

View File

@ -20,6 +20,7 @@ uint8_t RequestFrameCommand::getFrameNo()
return _payload[9] & (~0x80); return _payload[9] & (~0x80);
} }
void RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id) bool RequestFrameCommand::handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id)
{ {
return true;
} }

View File

@ -9,5 +9,5 @@ public:
void setFrameNo(uint8_t frame_no); void setFrameNo(uint8_t frame_no);
uint8_t getFrameNo(); uint8_t getFrameNo();
virtual void handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id); virtual bool handleResponse(InverterAbstract* inverter, fragment_t fragment[], uint8_t max_fragment_id);
}; };

View File

@ -122,25 +122,9 @@ uint8_t InverterAbstract::verifyAllFragments(CommandAbstract* cmd)
} }
} }
// All fragments are available --> Check CRC if (!cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId)) {
uint16_t crc = 0xffff, crcRcv; return FRAGMENT_HANDLE_ERROR;
for (uint8_t i = 0; i < _rxFragmentMaxPacketId; i++) {
if (i == _rxFragmentMaxPacketId - 1) {
// Last packet
crc = crc16(_rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len - 2, crc);
crcRcv = (_rxFragmentBuffer[i].fragment[_rxFragmentBuffer[i].len - 2] << 8)
| (_rxFragmentBuffer[i].fragment[_rxFragmentBuffer[i].len - 1]);
} else {
crc = crc16(_rxFragmentBuffer[i].fragment, _rxFragmentBuffer[i].len, crc);
}
} }
if (crc != crcRcv) {
return FRAGMENT_CRC_ERROR;
}
cmd->handleResponse(this, _rxFragmentBuffer, _rxFragmentMaxPacketId);
return FRAGMENT_OK; return FRAGMENT_OK;
} }

View File

@ -12,7 +12,7 @@
enum { enum {
FRAGMENT_ALL_MISSING = 255, FRAGMENT_ALL_MISSING = 255,
FRAGMENT_RETRANSMIT_TIMEOUT = 254, FRAGMENT_RETRANSMIT_TIMEOUT = 254,
FRAGMENT_CRC_ERROR = 253, FRAGMENT_HANDLE_ERROR = 253,
FRAGMENT_OK = 0 FRAGMENT_OK = 0
}; };