mirror of
https://github.com/thelsing/knx.git
synced 2025-09-18 17:52:44 +02:00
improve crc calculation
* removed TableObject::crc16Citt method and use the one in bits.h * do not save crc in flash, instead calculate on-the-fly in CallbackProperty when state==LS_LOADED * use DataProperty to store PID_PROG_VERSION * WARNING: segmentSize calculation for crc calculation is currently not correct. Need to somehow access size of data in class that inherits from TableObject (e.g. ApplicationObject or RouterObject)
This commit is contained in:
parent
83bb83bd56
commit
1cadc320a5
@ -11,16 +11,7 @@ ApplicationProgramObject::ApplicationProgramObject(Memory& memory)
|
||||
Property* properties[] =
|
||||
{
|
||||
new DataProperty(PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, (uint16_t)OT_APPLICATION_PROG),
|
||||
new CallbackProperty<ApplicationProgramObject>(this, PID_PROG_VERSION, true, PDT_GENERIC_05, 1, ReadLv3 | WriteLv3,
|
||||
[](ApplicationProgramObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t {
|
||||
pushByteArray(io->_programVersion, 5, data);
|
||||
return 1;
|
||||
},
|
||||
[](ApplicationProgramObject* io, uint16_t start, uint8_t count, const uint8_t* data) -> uint8_t
|
||||
{
|
||||
memcpy(io->_programVersion, data, 5);
|
||||
return 1;
|
||||
}),
|
||||
new DataProperty(PID_PROG_VERSION, true, PDT_GENERIC_05, 1, ReadLv3 | WriteLv3),
|
||||
new CallbackProperty<ApplicationProgramObject>(this, PID_PEI_TYPE, false, PDT_UNSIGNED_CHAR, 1, ReadLv3 | WriteLv0,
|
||||
[](ApplicationProgramObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t {
|
||||
if(start == 0)
|
||||
@ -40,6 +31,7 @@ ApplicationProgramObject::ApplicationProgramObject(Memory& memory)
|
||||
|
||||
uint8_t* ApplicationProgramObject::save(uint8_t* buffer)
|
||||
{
|
||||
property(PID_PROG_VERSION)->read(_programVersion);
|
||||
buffer = pushByteArray(_programVersion, 5, buffer);
|
||||
|
||||
return TableObject::save(buffer);
|
||||
@ -48,6 +40,7 @@ uint8_t* ApplicationProgramObject::save(uint8_t* buffer)
|
||||
const uint8_t* ApplicationProgramObject::restore(const uint8_t* buffer)
|
||||
{
|
||||
buffer = popByteArray(_programVersion, 5, buffer);
|
||||
property(PID_PROG_VERSION)->write(_programVersion);
|
||||
|
||||
return TableObject::restore(buffer);
|
||||
}
|
||||
|
@ -31,8 +31,6 @@ uint8_t* TableObject::save(uint8_t* buffer)
|
||||
{
|
||||
buffer = pushByte(_state, buffer);
|
||||
|
||||
buffer = pushWord(_crc, buffer);
|
||||
|
||||
if (_data)
|
||||
buffer = pushInt(_memory.toRelative(_data), buffer);
|
||||
else
|
||||
@ -48,8 +46,6 @@ const uint8_t* TableObject::restore(const uint8_t* buffer)
|
||||
buffer = popByte(state, buffer);
|
||||
_state = (LoadState)state;
|
||||
|
||||
buffer = popWord(_crc, buffer);
|
||||
|
||||
uint32_t relativeAddress = 0;
|
||||
buffer = popInt(relativeAddress, buffer);
|
||||
|
||||
@ -137,7 +133,6 @@ void TableObject::loadEventLoading(const uint8_t* data)
|
||||
case LE_START_LOADING:
|
||||
break;
|
||||
case LE_LOAD_COMPLETED:
|
||||
_crc = Crc16Citt(_data, saveSize() - 4 - 1 - 2); // remove 4 (memory) + 1 (state) + 2 (crc) bytes
|
||||
loadState(LS_LOADED);
|
||||
break;
|
||||
case LE_UNLOAD:
|
||||
@ -234,7 +229,7 @@ void TableObject::errorCode(ErrorCode errorCode)
|
||||
|
||||
uint16_t TableObject::saveSize()
|
||||
{
|
||||
return 5 + InterfaceObject::saveSize() + sizeof(_crc);
|
||||
return 5 + InterfaceObject::saveSize();
|
||||
}
|
||||
|
||||
void TableObject::initializeProperties(size_t propertiesSize, Property** properties)
|
||||
@ -272,14 +267,19 @@ void TableObject::initializeProperties(size_t propertiesSize, Property** propert
|
||||
pushInt(obj->tableReference(), data);
|
||||
return 1;
|
||||
}),
|
||||
new CallbackProperty<TableObject>(this, PID_MCB_TABLE, false, PDT_GENERIC_08, 1, ReadLv3 | WriteLv0,
|
||||
new CallbackProperty<TableObject>(this, PID_MCB_TABLE, false, PDT_GENERIC_08, 1, ReadLv3 | WriteLv0,
|
||||
[](TableObject* obj, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t {
|
||||
uint16_t size = obj->saveSize() - 5 - 2; // need to remove 5+2 extra bytes which were added in saveSize()
|
||||
if (obj->_state != LS_LOADED)
|
||||
return 0; // need to check return code for invalid
|
||||
|
||||
data = pushInt(size, data); // Segment Size (2 bytes)
|
||||
data = pushByte(0, data); // CRC Control Byte: CRC always valid (1 byte)
|
||||
data = pushByte(0xFF, data); // ReadAccess/WriteAccess (1 byte)
|
||||
data = pushWord(obj->_crc, data); // CRC checksum according to CRC16-CCITT spec (2 bytes)
|
||||
uint32_t segmentSize = obj->saveSize();
|
||||
uint16_t crc16 = crc16Ccitt(obj->data(), segmentSize);
|
||||
|
||||
pushInt(segmentSize, data); // Segment size
|
||||
pushByte(0x00, data + 4); // CRC control byte -> 0: always valid
|
||||
pushByte(0xFF, data + 5); // Read access 4 bits + Write access 4 bits (unknown: value taken from real coupler device)
|
||||
pushWord(crc16, data + 6); // CRC-16 CCITT of filter table
|
||||
|
||||
return 1;
|
||||
}),
|
||||
new DataProperty(PID_ERROR_CODE, false, PDT_ENUM8, 1, ReadLv3 | WriteLv0, (uint8_t)E_NO_FAULT)
|
||||
@ -299,20 +299,4 @@ void TableObject::initializeProperties(size_t propertiesSize, Property** propert
|
||||
memcpy(allProperties + propertyCount, ownProperties, sizeof(ownProperties));
|
||||
|
||||
InterfaceObject::initializeProperties(sizeof(allProperties), allProperties);
|
||||
}
|
||||
|
||||
uint16_t TableObject::Crc16Citt(uint8_t* data, uint16_t length)
|
||||
{
|
||||
uint16_t initialValue = 0x1D0F;
|
||||
uint16_t Table[] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
|
||||
if (data == nullptr)
|
||||
return 0;
|
||||
if (length == 0)
|
||||
return 0;
|
||||
uint16_t crc = initialValue;
|
||||
for (int i = 0; i <= length; i++)
|
||||
{
|
||||
crc = (uint16_t)((crc << 8) ^ Table[((crc >> 8) ^ (0xff & data[i]))]);
|
||||
}
|
||||
return crc;
|
||||
}
|
@ -47,7 +47,6 @@ class TableObject: public InterfaceObject
|
||||
void errorCode(ErrorCode errorCode);
|
||||
|
||||
void initializeProperties(size_t propertiesSize, Property** properties) override;
|
||||
static uint16_t Crc16Citt(uint8_t* data, uint16_t length);
|
||||
|
||||
private:
|
||||
uint32_t tableReference();
|
||||
@ -69,5 +68,4 @@ class TableObject: public InterfaceObject
|
||||
LoadState _state = LS_UNLOADED;
|
||||
Memory& _memory;
|
||||
uint8_t *_data = 0;
|
||||
uint16_t _crc = 0;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user