diff --git a/.gitignore b/.gitignore index e269708..6ca63f1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ flash.bin build dist *.egg-info +doxyoutput # Visual Studio 2015 cache/options directory .vs/ diff --git a/doc/references.bib b/doc/references.bib index 56bd9c9..f63d9e8 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -1,3 +1,19 @@ +@manual{knx:3/3/4, + organization = "KNX Association", + title = "KNX System Specifications Chapter 3/3/7 Application Layer", + year = 2013, + month = 11, + note = "v01.02.02" +} + +@manual{knx:3/3/7, + organization = "KNX Association", + title = "KNX System Specifications Chapter 3/3/7 Application Layer", + year = 2013, + month = 12, + note = "v01.06.02" +} + @manual{knx:3/4/1, organization = "KNX Association", title = "KNX System Specifications Chapter 3/4/1 Application Interface Layer", @@ -20,4 +36,4 @@ year = 2013, month = 12, note = "v01.03.01" -} \ No newline at end of file +} diff --git a/src/knx/address_table_object.h b/src/knx/address_table_object.h index 8756af5..c589843 100644 --- a/src/knx/address_table_object.h +++ b/src/knx/address_table_object.h @@ -14,6 +14,7 @@ class AddressTableObject: public TableObject public: /** * The contructor. + * * @param platform This parameter is only passed to the custructor of TableObject an not used by this class. */ AddressTableObject(Platform& platform); diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index 8276934..46311a4 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -7,18 +7,64 @@ class AssociationTableObject; class BusAccessUnit; class TransportLayer; - +/** + * This is an implementation of the application layer as specified in @cite knx:3/5/1. + * It provides methods for the BusAccessUnit to do different things and translates this + * call to an APDU and calls the correct method of the TransportLayer. + * It also takes calls from TransportLayer, decodes the submitted APDU and calls the coresponding + * methods of the BusAccessUnit class. + */ class ApplicationLayer { -public: + public: + /** + * The constructor. + * @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses. + * @param bau methods are called here depending of the content of the APDU + */ ApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau); + /** + * Assigns the TransportLayer to which encoded APDU are submitted to. + */ void transportLayer(TransportLayer& layer); // from transport layer -#pragma region Transport-Layer-Callbacks +#pragma region Transport - Layer - Callbacks + /** + * Somebody send us an APDU via multicast communiation. See 3.2 of @cite knx:3/3/4. + * See also ApplicationLayer::dataGroupConfirm and TransportLayer::dataGroupRequest. + * This method is called by the TransportLayer. + * + * @param tsap used the find the correct GroupObject with the help of the AssociationTableObject. + * See 3.1.1 of @cite knx:3/3/7 + * + * @param apdu The submitted APDU. + * + * @param priority The ::Priority of the received request. + * + * @param hopType Should routing be endless or should the NetworkLayer::hopCount be used? See also ::HopCountType. + */ void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); + /** + * Report the status of an APDU that we sent via multicast communiation back to us. See 3.2 of @cite knx:3/3/4. + * See also ApplicationLayer::dataGroupConfirm and TransportLayer::dataGroupRequest. This method is called by + * the TransportLayer. + * + * @param tsap used the find the correct GroupObject with the help of the AssociationTableObject. + * See 3.1.1 of @cite knx:3/3/7 + * + * @param apdu The submitted APDU. + * + * @param priority The ::Priority of the received request. + * + * @param hopType Should routing be endless or should the NetworkLayer::hopCount be used? See also ::HopCountType. + * + * @param status Was the request successful? + * + * @param ack Did we want a DataLinkLayer acknowledgement? See ::AckType. + */ void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, - APDU& apdu, bool status); + APDU& apdu, bool status); void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status); void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); @@ -33,6 +79,7 @@ public: void dataConnectedConfirm(uint16_t tsap); #pragma endregion +#pragma region from bau void groupValueReadRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType); void groupValueReadResponse(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, uint8_t* data, uint8_t dataLength); void groupValueWriteRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, uint8_t* data, uint8_t dataLength); @@ -41,52 +88,54 @@ public: void individualAddressReadResponse(AckType ack, HopCountType hopType); void individualAddressSerialNumberReadRequest(AckType ack, HopCountType hopType, uint8_t* serialNumber); void individualAddressSerialNumberReadResponse(AckType ack, HopCountType hopType, uint8_t* serialNumber, - uint16_t domainAddress); + uint16_t domainAddress); void individualAddressSerialNumberWriteRequest(AckType ack, HopCountType hopType, uint8_t* serialNumber, - uint16_t newaddress); + uint16_t newaddress); void deviceDescriptorReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t descriptorType); + uint8_t descriptorType); void deviceDescriptorReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t descriptorType, uint8_t* deviceDescriptor); + uint8_t descriptorType, uint8_t* deviceDescriptor); void restartRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap); void propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex); - void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, - uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length); - void propertyValueWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, - uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length); - void propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex); - void propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type, - uint16_t maxNumberOfElements, uint8_t access); - void memoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint16_t memoryAddress); - void memoryReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint16_t memoryAddress, uint8_t* data); - void memoryWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint16_t memoryAddress, uint8_t* data); - void userMemoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint32_t memoryAddress); - void userMemoryReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint32_t memoryAddress, uint8_t* memoryData); - void userMemoryWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint32_t memoryAddress, uint8_t* memoryData); - void userManufacturerInfoReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap); - void userManufacturerInfoReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t* info); - void authorizeRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint32_t key); - void authorizeResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level); - void keyWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level, uint32_t key); - void keyWriteResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level); -private: - void propertyDataSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t * data, - uint8_t length); + uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex); + void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length); + void propertyValueWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length); + void propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex); + void propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type, + uint16_t maxNumberOfElements, uint8_t access); + void memoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint16_t memoryAddress); + void memoryReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint16_t memoryAddress, uint8_t* data); + void memoryWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint16_t memoryAddress, uint8_t* data); + void userMemoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint32_t memoryAddress); + void userMemoryReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint32_t memoryAddress, uint8_t* memoryData); + void userMemoryWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, + uint32_t memoryAddress, uint8_t* memoryData); + void userManufacturerInfoReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap); + void userManufacturerInfoReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t* info); + void authorizeRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint32_t key); + void authorizeResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level); + void keyWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level, uint32_t key); + void keyWriteResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level); +#pragma endregion + + private: + void propertyDataSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, + uint8_t length); void memorySend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, - uint16_t memoryAddress, uint8_t * memoryData); + uint16_t memoryAddress, uint8_t* memoryData); void userMemorySend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, - uint8_t number, uint32_t memoryAddress, uint8_t* memoryData); + uint8_t number, uint32_t memoryAddress, uint8_t* memoryData); void groupValueSend(ApduType type, AckType ack, uint16_t asap, Priority priority, HopCountType hopType, uint8_t* data, uint8_t& dataLength); void individualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); void individualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); diff --git a/src/knx/knx_types.h b/src/knx/knx_types.h index 97527fc..e4cd2c5 100644 --- a/src/knx/knx_types.h +++ b/src/knx/knx_types.h @@ -8,16 +8,16 @@ enum FrameFormat enum Priority { - LowPriority = 0xC, - NormalPriority = 0x4, - UrgentPriority = 0x8, - SystemPriority = 0x0 + LowPriority = 0xC, //!< Normal priority of group communication. + NormalPriority = 0x4, //!< More important telegrams like central functions + UrgentPriority = 0x8, //!< Used for alarms. + SystemPriority = 0x0 //!< Mainly used by ETS for device programming. }; enum AckType { - AckDontCare = 0, - AckRequested = 0x2, + AckDontCare = 0, //!< We don't care about DataLinkLayer acknowledgement. + AckRequested = 0x2, //!< We want a DataLinkLayer acknowledgement. }; enum AddressType @@ -53,8 +53,8 @@ enum Confirm enum HopCountType { - UnlimitedRouting, - NetworkLayerParameter + UnlimitedRouting, //!< NPDU::hopCount is set to 7. This means that the frame never expires. This could be a problem if your bus contains a circle. + NetworkLayerParameter //!< use NetworkLayer::hopCount as NPDU::hopCount }; enum TpduType diff --git a/src/knx/transport_layer.h b/src/knx/transport_layer.h index d4c3957..57d69c5 100644 --- a/src/knx/transport_layer.h +++ b/src/knx/transport_layer.h @@ -19,7 +19,7 @@ public: TransportLayer(ApplicationLayer& layer, AddressTableObject& gat, Platform& platform); void networkLayer(NetworkLayer& layer); - // from network layer +#pragma region from network layer void dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu); void dataIndividualConfirm(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu, bool status); void dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu); @@ -28,8 +28,25 @@ public: void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, bool status); void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu); void dataSystemBroadcastConfirm(AckType ack, HopCountType hopType, TPDU& tpdu, Priority priority, bool status); - - // fromp application layer +#pragma endregion + +#pragma region from application layer + /** + * Request to send an APDU that via multicast. See 3.2 of @cite knx:3/3/4. + * See also ApplicationLayer::dataGroupConfirm and ApplicationLayer::dataGroupIndication. + * This method is called by the ApplicationLayer. + * + * @param tsap used the find the correct GroupObject with the help of the AssociationTableObject. + * See 3.1.1 of @cite knx:3/3/7 + * + * @param apdu The submitted APDU. + * + * @param priority The ::Priority of the request. + * + * @param hopType Should routing be endless or should the NetworkLayer::hopCount be used? See also ::HopCountType. + * + * @param ack Did we want a DataLinkLayer acknowledgement? See ::AckType. + */ void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); @@ -39,11 +56,14 @@ public: void disconnectRequest(uint16_t tsap, Priority priority); // apdu must be valid until it was confirmed void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu); - - // other +#pragma endregion + +#pragma region other void connectionTimeoutIndication(); void ackTimeoutIndication(); void loop(); +#pragma endregion + private: #pragma region States Priority _savedPriority = LowPriority;