From 8cfd67662f14aa52af03822ab5c32ea3afe28e08 Mon Sep 17 00:00:00 2001 From: nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Sun, 5 Jul 2020 12:11:44 +0200 Subject: [PATCH] Bugfixes for property startIndex 0 and PID_IO_LIST (#75) * Bugfix for property entry 0 and PID_IO_LIST * Remove unsused method * Fix comment and add missing size adjustment in other method * Callback properties must return valid data on startIndex 0. The return value must contain the actual element count within the property. --- src/knx/application_program_object.cpp | 8 ++++-- src/knx/bau07B0.cpp | 14 +++++------ src/knx/bau27B0.cpp | 14 +++++------ src/knx/bau57B0.cpp | 16 ++++++------ src/knx/bau_systemB.cpp | 10 ++++++-- src/knx/device_object.cpp | 20 +++++++++++++-- src/knx/ip_parameter_object.cpp | 34 +++++++++++++++++++++++--- src/knx/property.cpp | 12 ++++----- src/knx/table_object.cpp | 12 +++++++-- 9 files changed, 101 insertions(+), 39 deletions(-) diff --git a/src/knx/application_program_object.cpp b/src/knx/application_program_object.cpp index cf52368..4f3993d 100644 --- a/src/knx/application_program_object.cpp +++ b/src/knx/application_program_object.cpp @@ -13,8 +13,12 @@ ApplicationProgramObject::ApplicationProgramObject(Memory& memory) new DataProperty(PID_PROG_VERSION, true, PDT_GENERIC_05, 1, ReadLv3 | WriteLv3), new CallbackProperty(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) + if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } data[0] = 0; return 1; @@ -42,4 +46,4 @@ uint16_t ApplicationProgramObject::getWord(uint32_t addr) uint32_t ApplicationProgramObject::getInt(uint32_t addr) { return ::getInt(TableObject::data() + addr); -} \ No newline at end of file +} diff --git a/src/knx/bau07B0.cpp b/src/knx/bau07B0.cpp index 06c394a..3d2f2a0 100644 --- a/src/knx/bau07B0.cpp +++ b/src/knx/bau07B0.cpp @@ -28,13 +28,13 @@ Bau07B0::Bau07B0(Platform& platform) // This differs from BAU to BAU with different medium types. // See PID_IO_LIST Property* prop = _deviceObj.property(PID_IO_LIST); - prop->write(1, OT_DEVICE); - prop->write(2, OT_ADDR_TABLE); - prop->write(3, OT_ASSOC_TABLE); - prop->write(4, OT_GRP_OBJ_TABLE); - prop->write(5, OT_APPLICATION_PROG); + prop->write(1, (uint16_t) OT_DEVICE); + prop->write(2, (uint16_t) OT_ADDR_TABLE); + prop->write(3, (uint16_t) OT_ASSOC_TABLE); + prop->write(4, (uint16_t) OT_GRP_OBJ_TABLE); + prop->write(5, (uint16_t) OT_APPLICATION_PROG); #ifdef USE_CEMI_SERVER - prop->write(6, OT_CEMI_SERVER); + prop->write(6, (uint16_t) OT_CEMI_SERVER); #endif } @@ -103,4 +103,4 @@ void Bau07B0::loop() #endif } -#endif \ No newline at end of file +#endif diff --git a/src/knx/bau27B0.cpp b/src/knx/bau27B0.cpp index a938dba..5161336 100644 --- a/src/knx/bau27B0.cpp +++ b/src/knx/bau27B0.cpp @@ -35,14 +35,14 @@ Bau27B0::Bau27B0(Platform& platform) // This differs from BAU to BAU with different medium types. // See PID_IO_LIST Property* prop = _deviceObj.property(PID_IO_LIST); - prop->write(1, OT_DEVICE); - prop->write(2, OT_ADDR_TABLE); - prop->write(3, OT_ASSOC_TABLE); - prop->write(4, OT_GRP_OBJ_TABLE); - prop->write(5, OT_APPLICATION_PROG); - prop->write(6, OT_RF_MEDIUM); + prop->write(1, (uint16_t) OT_DEVICE); + prop->write(2, (uint16_t) OT_ADDR_TABLE); + prop->write(3, (uint16_t) OT_ASSOC_TABLE); + prop->write(4, (uint16_t) OT_GRP_OBJ_TABLE); + prop->write(5, (uint16_t) OT_APPLICATION_PROG); + prop->write(6, (uint16_t) OT_RF_MEDIUM); #ifdef USE_CEMI_SERVER - prop->write(7, OT_CEMI_SERVER); + prop->write(7, (uint16_t) OT_CEMI_SERVER); #endif } diff --git a/src/knx/bau57B0.cpp b/src/knx/bau57B0.cpp index 94145c7..67b9a22 100644 --- a/src/knx/bau57B0.cpp +++ b/src/knx/bau57B0.cpp @@ -32,14 +32,14 @@ Bau57B0::Bau57B0(Platform& platform) // This differs from BAU to BAU with different medium types. // See PID_IO_LIST Property* prop = _deviceObj.property(PID_IO_LIST); - prop->write(1, OT_DEVICE); - prop->write(2, OT_ADDR_TABLE); - prop->write(3, OT_ASSOC_TABLE); - prop->write(4, OT_GRP_OBJ_TABLE); - prop->write(5, OT_APPLICATION_PROG); - prop->write(6, OT_IP_PARAMETER); + prop->write(1, (uint16_t) OT_DEVICE); + prop->write(2, (uint16_t) OT_ADDR_TABLE); + prop->write(3, (uint16_t) OT_ASSOC_TABLE); + prop->write(4, (uint16_t) OT_GRP_OBJ_TABLE); + prop->write(5, (uint16_t) OT_APPLICATION_PROG); + prop->write(6, (uint16_t) OT_IP_PARAMETER); #ifdef USE_CEMI_SERVER - prop->write(7, OT_CEMI_SERVER); + prop->write(7, (uint16_t) OT_CEMI_SERVER); #endif } @@ -96,4 +96,4 @@ DataLinkLayer& Bau57B0::dataLinkLayer() return _dlLayer; } -#endif \ No newline at end of file +#endif diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index 3340fc5..0b2ed88 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -227,7 +227,10 @@ void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hop if (obj) { uint8_t elementSize = obj->propertySize((PropertyID)propertyId); - size = elementSize * numberOfElements; + if (startIndex > 0) + size = elementSize * numberOfElements; + else + size = sizeof(uint16_t); // size of property array entry 0 which contains the current number of elements } else elementCount = 0; @@ -439,7 +442,10 @@ void BauSystemB::propertyValueRead(ObjectType objectType, uint8_t objectInstance if (obj) { uint8_t elementSize = obj->propertySize((PropertyID)propertyId); - size = elementSize * numberOfElements; + if (startIndex > 0) + size = elementSize * numberOfElements; + else + size = sizeof(uint16_t); // size of property array entry 0 which contains the current number of elements *data = new uint8_t [size]; obj->readProperty((PropertyID)propertyId, startIndex, elementCount, *data); } diff --git a/src/knx/device_object.cpp b/src/knx/device_object.cpp index 888fabd..464ae4a 100644 --- a/src/knx/device_object.cpp +++ b/src/knx/device_object.cpp @@ -21,7 +21,11 @@ DeviceObject::DeviceObject() [](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } pushByteArray(io->propertyData(PID_SERIAL_NUMBER), 2, data); return 1; @@ -34,8 +38,12 @@ DeviceObject::DeviceObject() [](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; - + } + *data = io->_prgMode; return 1; }, @@ -52,7 +60,11 @@ DeviceObject::DeviceObject() [](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } *data = ((io->_ownAddress >> 8) & 0xff); @@ -62,12 +74,16 @@ DeviceObject::DeviceObject() [](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } *data = (io->_ownAddress & 0xff); return 1; }), - new DataProperty(PID_IO_LIST, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0), + new DataProperty(PID_IO_LIST, false, PDT_UNSIGNED_INT, 8, ReadLv3 | WriteLv0), new DataProperty(PID_HARDWARE_TYPE, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3, hardwareType), new DataProperty(PID_DEVICE_DESCRIPTOR, false, PDT_GENERIC_02, 1, ReadLv3 | WriteLv0), #ifdef USE_RF diff --git a/src/knx/ip_parameter_object.cpp b/src/knx/ip_parameter_object.cpp index f1ab75e..8366faf 100644 --- a/src/knx/ip_parameter_object.cpp +++ b/src/knx/ip_parameter_object.cpp @@ -20,7 +20,11 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } // TODO: get property of deviceobject and use it pushWord(io->_deviceObject.induvidualAddress(), data); return 1; @@ -36,8 +40,12 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; - + } + pushInt(io->_platform.currentIpAddress(), data); return 1; }), @@ -45,8 +53,12 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; - + } + pushInt(io->_platform.currentSubnetMask(), data); return 1; }), @@ -54,7 +66,11 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } pushInt(io->_platform.currentDefaultGateway(), data); return 1; @@ -66,7 +82,11 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } io->_platform.macAddress(data); return 1; @@ -75,7 +95,11 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } pushInt(DEFAULT_MULTICAST_ADDR, data); return 1; @@ -86,7 +110,11 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf [](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } pushWord(0x1, data); return 1; @@ -96,4 +124,4 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf initializeProperties(sizeof(properties), properties); } -#endif \ No newline at end of file +#endif diff --git a/src/knx/property.cpp b/src/knx/property.cpp index a42989f..e9900e1 100644 --- a/src/knx/property.cpp +++ b/src/knx/property.cpp @@ -36,26 +36,25 @@ uint8_t Property::ElementSize() const case PDT_CONTROL: // is actually 10 if written, but this is always handled with a callback case PDT_GENERIC_01: case PDT_UNSIGNED_CHAR: + case PDT_BITSET8: + case PDT_BINARY_INFORMATION: // only 1 bit really + case PDT_ENUM8: + case PDT_SCALING: return 1; case PDT_GENERIC_02: case PDT_INT: case PDT_KNX_FLOAT: case PDT_UNSIGNED_INT: case PDT_VERSION: - return 2; - case PDT_ALARM_INFO: - case PDT_BINARY_INFORMATION: case PDT_BITSET16: - case PDT_BITSET8: + return 2; case PDT_DATE: - case PDT_ENUM8: case PDT_ESCAPE: case PDT_FUNCTION: case PDT_GENERIC_03: case PDT_NE_FL: case PDT_NE_VL: case PDT_POLL_GROUP_SETTING: - case PDT_SCALING: case PDT_TIME: case PDT_UTF8: return 3; @@ -68,6 +67,7 @@ uint8_t Property::ElementSize() const case PDT_SHORT_CHAR_BLOCK: return 5; case PDT_GENERIC_06: + case PDT_ALARM_INFO: return 6; case PDT_GENERIC_07: return 7; diff --git a/src/knx/table_object.cpp b/src/knx/table_object.cpp index 1363df8..d1be31c 100644 --- a/src/knx/table_object.cpp +++ b/src/knx/table_object.cpp @@ -238,8 +238,12 @@ void TableObject::initializeProperties(size_t propertiesSize, Property** propert { new CallbackProperty(this, PID_LOAD_STATE_CONTROL, true, PDT_CONTROL, 1, ReadLv3 | WriteLv3, [](TableObject* obj, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { - if (start == 0) + if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } data[0] = obj->_state; return 1; @@ -250,8 +254,12 @@ void TableObject::initializeProperties(size_t propertiesSize, Property** propert }), new CallbackProperty(this, PID_TABLE_REFERENCE, false, PDT_UNSIGNED_LONG, 1, ReadLv3 | WriteLv0, [](TableObject* obj, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t { - if (start == 0) + if(start == 0) + { + uint16_t currentNoOfElements = 1; + pushWord(currentNoOfElements, data); return 1; + } if (obj->_state == LS_UNLOADED) pushInt(0, data);