diff --git a/doc/references.bib b/doc/references.bib index 12dc68d..56bd9c9 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -6,6 +6,14 @@ note = "v01.01.02" } +@manual{knx:3/5/1, + organization = "KNX Association", + title = "KNX System Specifications Chapter 3/5/1 Resources", + year = 2013, + month = 12, + note = "v01.09.03" +} + @manual{knx:3/7/3, organization = "KNX Association", title = "KNX System Specifications Chapter 3/7/3 Standardized Identifier Tables", diff --git a/src/knx/address_table_object.cpp b/src/knx/address_table_object.cpp index bd5dae7..c5ea3ec 100644 --- a/src/knx/address_table_object.cpp +++ b/src/knx/address_table_object.cpp @@ -32,7 +32,7 @@ uint16_t AddressTableObject::entryCount() return ntohs(_groupAddresses[0]); } -uint16_t AddressTableObject::getGa(uint16_t tsap) +uint16_t AddressTableObject::getGroupAddress(uint16_t tsap) { if (loadState() != LS_LOADED || tsap > entryCount() ) return 0; @@ -46,7 +46,7 @@ uint16_t AddressTableObject::getTsap(uint16_t addr) for (uint16_t i = 1; i <= size; i++) if (ntohs(_groupAddresses[i]) == addr) return i; - return 1; + return 0; } #pragma region SaveRestore @@ -60,7 +60,7 @@ uint8_t* AddressTableObject::restore(uint8_t* buffer) { buffer = TableObject::restore(buffer); - _groupAddresses = (uint16_t*)_data; + _groupAddresses = (uint16_t*)data(); return buffer; } @@ -82,7 +82,7 @@ void AddressTableObject::beforeStateChange(LoadState& newState) if (newState != LS_LOADED) return; - _groupAddresses = (uint16_t*)_data; + _groupAddresses = (uint16_t*)data(); } static PropertyDescription _propertyDescriptions[] = diff --git a/src/knx/address_table_object.h b/src/knx/address_table_object.h index 0d2ef03..a89971f 100644 --- a/src/knx/address_table_object.h +++ b/src/knx/address_table_object.h @@ -1,18 +1,53 @@ #pragma once #include "table_object.h" - +/** + * @brief This class represents the group address table. It provides a mapping between tranport layer + * service access points (TSAP) and group addresses. The TSAP can be imagined as an index to the array + * of group adresses. + * + * See section 4.10 of @cite knx:3/5/1 for further details. + * It implements realisation type 7 (see section 4.10.7 of @cite knx:3/5/1). + */ class AddressTableObject: public TableObject { public: + /** + * @brief The contructor. + * @param platform This parameter is only passed to the custructor of TableObject an not used by this class. + */ AddressTableObject(Platform& platform); void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t *data); + uint8_t *save(uint8_t *buffer); + uint8_t *restore(uint8_t *buffer); + /** + * @brief returns the number of group addresses of the object. + */ uint16_t entryCount(); - uint16_t getGa(uint16_t tsap); - uint16_t getTsap(uint16_t ga); - uint8_t* save(uint8_t* buffer); - uint8_t* restore(uint8_t* buffer); - bool contains(uint16_t addr); + /** + * @brief Get the group address mapped to a TSAP. + * + * @param tsap The TSAP of which to get the group address for. + * + * @return the groupAddress if found or zero if no group address was found. + */ + uint16_t getGroupAddress(uint16_t tsap); + /** + * @brief Get the TSAP mapped to a group address. + * + * @param groupAddress the group address of whicht to get the TSAP for. + * + * @return the TSAP if found or zero if no tsap was found. + */ + uint16_t getTsap(uint16_t groupAddress); + /** + * @brief Check if the address table contains a group address. + * + * @param groupAddress the group address to check + * + * @return true if the address table contains the group address, false otherwise + */ + bool contains(uint16_t groupAddress); protected: virtual void beforeStateChange(LoadState& newState); uint8_t propertyCount(); diff --git a/src/knx/application_program_object.cpp b/src/knx/application_program_object.cpp index 23e76fe..7269ff4 100644 --- a/src/knx/application_program_object.cpp +++ b/src/knx/application_program_object.cpp @@ -56,22 +56,22 @@ uint8_t ApplicationProgramObject::propertySize(PropertyID id) uint8_t * ApplicationProgramObject::data(uint32_t addr) { - return _data + addr; + return TableObject::data() + addr; } uint8_t ApplicationProgramObject::getByte(uint32_t addr) { - return *(_data + addr); + return *(TableObject::data() + addr); } uint16_t ApplicationProgramObject::getWord(uint32_t addr) { - return ::getWord(_data + addr); + return ::getWord(TableObject::data() + addr); } uint32_t ApplicationProgramObject::getInt(uint32_t addr) { - return ::getInt(_data + addr); + return ::getInt(TableObject::data() + addr); } uint8_t* ApplicationProgramObject::save(uint8_t* buffer) diff --git a/src/knx/association_table_object.cpp b/src/knx/association_table_object.cpp index 6f68180..3c76674 100644 --- a/src/knx/association_table_object.cpp +++ b/src/knx/association_table_object.cpp @@ -45,7 +45,7 @@ uint8_t* AssociationTableObject::save(uint8_t* buffer) uint8_t* AssociationTableObject::restore(uint8_t* buffer) { buffer = TableObject::restore(buffer); - _tableData = (uint16_t*)_data; + _tableData = (uint16_t*)data(); return buffer; } @@ -66,7 +66,7 @@ void AssociationTableObject::beforeStateChange(LoadState& newState) if (newState != LS_LOADED) return; - _tableData = (uint16_t*)_data; + _tableData = (uint16_t*)data(); } static PropertyDescription _propertyDescriptions[] = diff --git a/src/knx/group_object_table_object.cpp b/src/knx/group_object_table_object.cpp index 4eb8e1a..a24bd92 100644 --- a/src/knx/group_object_table_object.cpp +++ b/src/knx/group_object_table_object.cpp @@ -52,7 +52,7 @@ uint8_t* GroupObjectTableObject::restore(uint8_t* buffer) { buffer = TableObject::restore(buffer); - _tableData = (uint16_t*)_data; + _tableData = (uint16_t*)data(); initGroupObjects(); return buffer; @@ -95,12 +95,12 @@ void GroupObjectTableObject::beforeStateChange(LoadState& newState) if (newState != LS_LOADED) return; - _tableData = (uint16_t*)_data; + _tableData = (uint16_t*)data(); if (!initGroupObjects()) { newState = LS_ERROR; - TableObject::_errorCode = E_SOFTWARE_FAULT; + TableObject::errorCode(E_SOFTWARE_FAULT); } } diff --git a/src/knx/table_object.cpp b/src/knx/table_object.cpp index e14571f..c9aaa1b 100644 --- a/src/knx/table_object.cpp +++ b/src/knx/table_object.cpp @@ -24,6 +24,8 @@ void TableObject::readProperty(PropertyID id, uint32_t start, uint32_t& count, u case PID_ERROR_CODE: data[0] = _errorCode; break; + default: + InterfaceObject::readProperty(id, start, count, data); } } @@ -38,6 +40,8 @@ void TableObject::writeProperty(PropertyID id, uint8_t start, uint8_t* data, uin //case PID_MCB_TABLE: // TODO // break; + default: + InterfaceObject::writeProperty(id, start, data, count); } } @@ -53,8 +57,9 @@ uint8_t TableObject::propertySize(PropertyID id) return 1; case PID_OBJECT_TYPE: return 2; + default: + return InterfaceObject::propertySize(id); } - return 0; } TableObject::~TableObject() @@ -157,6 +162,9 @@ void TableObject::loadEvent(uint8_t* data) case LS_ERROR: loadEventError(data); break; + default: + /* do nothing */ + break; } } @@ -262,4 +270,19 @@ void TableObject::additionalLoadControls(uint8_t* data) loadState(LS_ERROR); _errorCode = E_MAX_TABLE_LENGTH_EXEEDED; } +} + +uint8_t* TableObject::data() +{ + return _data; +} + +uint32_t TableObject::size() +{ + return _size; +} + +void TableObject::errorCode(ErrorCode errorCode) +{ + _errorCode = errorCode; } \ No newline at end of file diff --git a/src/knx/table_object.h b/src/knx/table_object.h index 5384e4e..9a4a6ad 100644 --- a/src/knx/table_object.h +++ b/src/knx/table_object.h @@ -3,23 +3,53 @@ #include "interface_object.h" #include "platform.h" +/** + * @brief This class provides common functionality for interface objects that are configured by ETS with MemorWrite. + */ class TableObject: public InterfaceObject { public: + /** + * @brief The constuctor. + * @param platform the Platform on which the software runs. The class uses the memory management features of Platform. + */ TableObject(Platform& platform); virtual void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data); virtual void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count); virtual uint8_t propertySize(PropertyID id); + /** + * @brief The destructor. + */ virtual ~TableObject(); + /** + * @brief This method returns the ::LoadState of the interface object. + */ LoadState loadState(); virtual uint8_t* save(uint8_t* buffer); virtual uint8_t* restore(uint8_t* buffer); protected: + /** + * @brief This method is called before the interface object enters a new ::Loadstate. + * If there is a error changing the state newState should be set to ::LS_ERROR and errorCode() + * to a reason for the failure. + */ virtual void beforeStateChange(LoadState& newState) {} - uint8_t* _data = 0; - uint32_t _size = 0; - ErrorCode _errorCode = E_NO_FAULT; -private: + + /** + * @brief returns the internal data of the interface object. This pointer belongs to the TableObject class and + * must not be freed. + */ + uint8_t* data(); + /** + * @brief returns the size of the internal data of the interface object int byte. + */ + uint32_t size(); + /** + * @brief Set the reason for a state change failure. + */ + void errorCode(ErrorCode errorCode); + + private: uint32_t tableReference(); bool allocTable(uint32_t size, bool doFill, uint8_t fillByte); void loadEvent(uint8_t* data); @@ -31,4 +61,7 @@ private: void loadState(LoadState newState); LoadState _state = LS_UNLOADED; Platform& _platform; + uint8_t *_data = 0; + uint32_t _size = 0; + ErrorCode _errorCode = E_NO_FAULT; }; diff --git a/src/knx/transport_layer.cpp b/src/knx/transport_layer.cpp index 6c495f1..4686716 100644 --- a/src/knx/transport_layer.cpp +++ b/src/knx/transport_layer.cpp @@ -356,6 +356,9 @@ void TransportLayer::dataIndividualConfirm(AckType ack, uint16_t destination, Ho void TransportLayer::dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu) { uint16_t tsap = _groupAddressTable.getTsap(destination); + if (tsap == 0) + return; + _applicationLayer.dataGroupIndication(hopType, priority, tsap, tpdu.apdu()); } @@ -386,7 +389,7 @@ void TransportLayer::dataSystemBroadcastConfirm(AckType ack, HopCountType hopTyp void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) { - uint16_t groupAdress = _groupAddressTable.getGa(tsap); + uint16_t groupAdress = _groupAddressTable.getGroupAddress(tsap); TPDU& tpdu = apdu.frame().tpdu(); _networkLayer->dataGroupRequest(ack, groupAdress, hopType, priority, tpdu); }