From ff9426fdc36ab8aa5ea2a503dfc3df114d19ecd0 Mon Sep 17 00:00:00 2001 From: Nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Sun, 31 May 2020 18:44:59 +0200 Subject: [PATCH] save work --- examples/knx-linux/CMakeLists.txt | 3 +- src/knx/application_layer.cpp | 20 +++++ src/knx/application_layer.h | 30 +++---- src/knx/bau_systemB.cpp | 30 ++++++- src/knx/bau_systemB.h | 4 + src/knx/function_property.h | 47 +++++++++++ src/knx/interface_object.cpp | 22 +++++ src/knx/interface_object.h | 33 +++++++- src/knx/knx_types.h | 3 + src/knx/property.cpp | 20 +++++ src/knx/property.h | 4 +- src/knx/secure_application_layer.cpp | 115 +++++++++++++++++++++++++-- src/knx/secure_application_layer.h | 40 +++++----- 13 files changed, 325 insertions(+), 46 deletions(-) create mode 100644 src/knx/function_property.h diff --git a/examples/knx-linux/CMakeLists.txt b/examples/knx-linux/CMakeLists.txt index ba97c10..9f3e364 100644 --- a/examples/knx-linux/CMakeLists.txt +++ b/examples/knx-linux/CMakeLists.txt @@ -42,7 +42,8 @@ add_executable(knx-linux ../../src/knx/dpt.h ../../src/knx/dptconvert.cpp ../../src/knx/dptconvert.h - ../../src/knx/group_object.cpp + ../../src/knx/function_property.h + ../../src/knx/group_object.cpp ../../src/knx/group_object.h ../../src/knx/group_object_table_object.cpp ../../src/knx/group_object_table_object.h diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 844c6c6..99f06b6 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -552,6 +552,26 @@ void ApplicationLayer::propertyValueWriteRequest(AckType ack, Priority priority, startIndex, data, length); } +void ApplicationLayer::functionPropertyStateResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t objectIndex, uint8_t propertyId, uint8_t returnCode, uint8_t* resultData, uint8_t resultLength) +{ + CemiFrame frame(3 + resultLength + 1); + APDU& apdu = frame.apdu(); + apdu.type(FunctionPropertyStateResponse); + uint8_t* data = apdu.data() + 1; + + data[0] = objectIndex; + data[1] = propertyId; + data[2] = returnCode; + if (resultLength > 0) + memcpy(&data[3], resultData, resultLength); + + if (asap == _connectedTsap) + dataConnectedRequest(asap, priority, apdu); + else + dataIndividualRequest(ack, hopType, priority, asap, apdu); +} + void ApplicationLayer::propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex) { diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index cb84197..ba35f2c 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -44,7 +44,7 @@ class ApplicationLayer * * @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); + virtual 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 @@ -63,20 +63,20 @@ class ApplicationLayer * * @param ack Did we want a DataLinkLayer acknowledgement? See ::AckType. */ - void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, + virtual void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, 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); - void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status); - void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); - void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); - void connectIndication(uint16_t tsap); - void connectConfirm(uint16_t destination, uint16_t tsap, bool status); - void disconnectIndication(uint16_t tsap); - void disconnectConfirm(Priority priority, uint16_t tsap, bool status); - void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu); - void dataConnectedConfirm(uint16_t tsap); + virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); + virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status); + virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); + virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status); + virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); + virtual void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); + virtual void connectIndication(uint16_t tsap); + virtual void connectConfirm(uint16_t destination, uint16_t tsap, bool status); + virtual void disconnectIndication(uint16_t tsap); + virtual void disconnectConfirm(Priority priority, uint16_t tsap, bool status); + virtual void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu); + virtual void dataConnectedConfirm(uint16_t tsap); #pragma endregion #pragma region from bau @@ -105,6 +105,8 @@ class ApplicationLayer 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 functionPropertyStateResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, + uint8_t objectIndex, uint8_t propertyId, uint8_t returnCode, 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, diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index 8f44ef1..390c97f 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -240,6 +240,34 @@ void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hop startIndex, data, size); } +void BauSystemB::functionPropertyCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t* data, uint8_t length) +{ + uint8_t returnCode = 0xFF; + uint8_t resultLength = 0; + uint8_t resultData[32]; + + InterfaceObject* obj = getInterfaceObject(objectIndex); + if(obj) + returnCode = obj->command((PropertyID)propertyId, data, length, resultData, resultLength); + + _appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, objectIndex, propertyId, returnCode, resultData, resultLength); +} + +void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t* data, uint8_t length) +{ + uint8_t returnCode = 0xFF; + uint8_t resultLength = 0; + uint8_t resultData[32]; + + InterfaceObject* obj = getInterfaceObject(objectIndex); + if(obj) + returnCode = obj->state((PropertyID)propertyId, data, length, resultData, resultLength); + + _appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, objectIndex, propertyId, returnCode, resultData, resultLength); +} + void BauSystemB::individualAddressReadIndication(HopCountType hopType) { if (_deviceObj.progMode()) @@ -433,4 +461,4 @@ void BauSystemB::propertyValueWrite(ObjectType objectType, uint8_t objectInstanc Memory& BauSystemB::memory() { return _memory; -} \ No newline at end of file +} diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index 5877747..a984088 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -57,6 +57,10 @@ class BauSystemB : protected BusAccessUnit uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length) override; void propertyValueReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex) override; + void functionPropertyCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t* data, uint8_t length); + void functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex, + uint8_t propertyId, uint8_t* data, uint8_t length); void individualAddressReadIndication(HopCountType hopType) override; void individualAddressWriteIndication(HopCountType hopType, uint16_t newaddress) override; void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, diff --git a/src/knx/function_property.h b/src/knx/function_property.h new file mode 100644 index 0000000..97be948 --- /dev/null +++ b/src/knx/function_property.h @@ -0,0 +1,47 @@ +#pragma once + +#include "property.h" + +class InterfaceObject; + +template class FunctionProperty : public Property +{ + public: + FunctionProperty(T* io, PropertyID id, uint8_t access, + uint8_t (*commandCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&), + uint8_t (*stateCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&)) + : Property(id, false, PDT_FUNCTION, 1, access), _interfaceObject(io), _commandCallback(commandCallback), _stateCallback(stateCallback) + /* max_elements is set to 1, see 3.3.7 Application Layer p.68 */ + {} + + virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) const override + { + return 0; + } + + virtual uint8_t write(uint16_t start, uint8_t count, const uint8_t* data) override + { + return 0; + } + + virtual uint8_t command(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength) override + { + if (length == 0 || _commandCallback == nullptr ) + return 0xFF; + + return _commandCallback(_interfaceObject, data, length, resultData, resultLength); + } + + virtual uint8_t state(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength) override + { + if (length == 0 || _stateCallback == nullptr ) + return 0xFF; + + return _stateCallback(_interfaceObject, data, length, resultData, resultLength); + } + + private: + T* _interfaceObject = nullptr; + uint8_t (*_commandCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&) = nullptr; + uint8_t (*_stateCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&) = nullptr; +}; diff --git a/src/knx/interface_object.cpp b/src/knx/interface_object.cpp index 20276f6..1eaaf16 100644 --- a/src/knx/interface_object.cpp +++ b/src/knx/interface_object.cpp @@ -137,6 +137,28 @@ uint8_t InterfaceObject::propertySize(PropertyID id) return prop->ElementSize(); } +uint8_t InterfaceObject::command(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength) +{ + Property* prop = property(id); + if (prop == nullptr) + { + return 0xFF; + } + + return prop->command(data, length, resultData, resultLength); +} + +uint8_t InterfaceObject::state(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t resultLength) +{ + Property* prop = property(id); + if (prop == nullptr) + { + return 0xFF; + } + + return prop->state(data, length, resultData, resultLength); +} + uint8_t InterfaceObject::propertyDescriptionCount() { return 0; diff --git a/src/knx/interface_object.h b/src/knx/interface_object.h index 03f93e9..fedac54 100644 --- a/src/knx/interface_object.h +++ b/src/knx/interface_object.h @@ -49,6 +49,9 @@ enum ObjectType /** File Server Object */ OT_FILE_SERVER = 13, + /** Security Interface Object */ + OT_SECURITY = 17, + /** RF Medium Object */ OT_RF_MEDIUM = 19 }; @@ -98,6 +101,34 @@ class InterfaceObject : public SaveRestore * @returns the size in byte or 0 if the interface object does not have the property */ virtual uint8_t propertySize(PropertyID id); + /** + * Call command of a function property of the interface object. Property type must be PDT_FUNCTION + * + * @param id id of the property to call + * + * @param[in] length The size of the data buffer + * + * @param[in] data The argument data for the function + * + * @param[out] resultLength The size of the result data buffer + * + * @param[out] resultData The result data for the function + */ + virtual uint8_t command(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t &resultLength); + /** + * Get state of a function property of the interface object. Property type must be PDT_FUNCTION + * + * @param id id of the property to call + * + * @param[in] length The size of the data buffer + * + * @param[in] data The argument data for the function + * + * @param[out] resultLength The size of the result data buffer + * + * @param[out] resultData The result data for the function + */ + virtual uint8_t state(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t resultLength); /** * Read the Description of a property of the interface object. The output parameters are only valid if nuberOfElements is not zero. * @@ -170,4 +201,4 @@ class InterfaceObject : public SaveRestore Property** _properties = nullptr; uint8_t _propertyCount = 0; -}; \ No newline at end of file +}; diff --git a/src/knx/knx_types.h b/src/knx/knx_types.h index 7d46976..83b0b41 100644 --- a/src/knx/knx_types.h +++ b/src/knx/knx_types.h @@ -138,6 +138,9 @@ enum ApduType UserMemoryWrite = 0x2C2, UserManufacturerInfoRead = 0x2C5, UserManufacturerInfoResponse = 0x2C6, + FunctionPropertyCommand = 0x2C7, + FunctionPropertyState = 0x2C8, + FunctionPropertyStateResponse = 0x2C9, DeviceDescriptorRead = 0x300, DeviceDescriptorResponse = 0x340, Restart = 0x380, diff --git a/src/knx/property.cpp b/src/knx/property.cpp index a5077dd..3bdcb1d 100644 --- a/src/knx/property.cpp +++ b/src/knx/property.cpp @@ -203,3 +203,23 @@ uint8_t Property::write(uint16_t position, uint16_t value) pushWord(value, data); return write(position, 1, data); } + +uint8_t Property::command(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength) +{ + (void)data; + (void)length; + (void)resultData; + resultLength = 0; + + return 0xFF; +} + +uint8_t Property::state(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t &resultLength) +{ + (void)data; + (void)length; + (void)resultData; + resultLength = 0; + + return 0xFF; +} diff --git a/src/knx/property.h b/src/knx/property.h index 11ac4ef..aa08ac5 100644 --- a/src/knx/property.h +++ b/src/knx/property.h @@ -238,6 +238,8 @@ class Property : public SaveRestore uint8_t ElementSize() const; virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) const = 0; virtual uint8_t write(uint16_t start, uint8_t count, const uint8_t* data) = 0; + virtual uint8_t command(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength); + virtual uint8_t state(uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength); uint8_t read(uint8_t& value) const; uint8_t read(uint16_t& value) const; uint8_t read(uint32_t& value) const; @@ -253,4 +255,4 @@ class Property : public SaveRestore PropertyDataType _type; uint16_t _maxElements; uint8_t _access; -}; \ No newline at end of file +}; diff --git a/src/knx/secure_application_layer.cpp b/src/knx/secure_application_layer.cpp index 81fd7e9..14e587c 100644 --- a/src/knx/secure_application_layer.cpp +++ b/src/knx/secure_application_layer.cpp @@ -23,19 +23,49 @@ SecureApplicationLayer::SecureApplicationLayer(AssociationTableObject& assocTabl { } +/* from transport layer */ + void SecureApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) { - ApplicationLayer::dataGroupIndication(hopType, priority, tsap, apdu); + if (apdu.type() == SecureService) + { + // Decrypt secure APDU + + // Process decrypted inner APDU + ApplicationLayer::dataGroupIndication(hopType, priority, tsap, apdu); + } + else + { + ApplicationLayer::dataGroupIndication(hopType, priority, tsap, apdu); + } } void SecureApplicationLayer::dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) { - ApplicationLayer::dataGroupConfirm(ack, hopType, priority, tsap, apdu, status); + if (apdu.type() == SecureService) + { + // Decrypt secure APDU + + // Process decrypted inner APDU + ApplicationLayer::dataGroupConfirm(ack, hopType, priority, tsap, apdu, status); + } + else + { + ApplicationLayer::dataGroupConfirm(ack, hopType, priority, tsap, apdu, status); + } } void SecureApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) { - ApplicationLayer::dataBroadcastIndication(hopType, priority, source, apdu); + if (apdu.type() == SecureService) + { + // Secure APDU is not allowed in Broadcast + println("Secure APDU in Broadcast not allowed!"); + } + else + { + ApplicationLayer::dataBroadcastIndication(hopType, priority, source, apdu); + } } void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) @@ -45,7 +75,15 @@ void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopT void SecureApplicationLayer::dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) { - ApplicationLayer::dataSystemBroadcastIndication(hopType, priority, source, apdu); + if (apdu.type() == SecureService) + { + // Secure APDU is not allowed in Broadcast + println("Secure APDU in SystemBroadcast not allowed!"); + } + else + { + ApplicationLayer::dataSystemBroadcastIndication(hopType, priority, source, apdu); + } } void SecureApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) @@ -55,12 +93,32 @@ void SecureApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Pr void SecureApplicationLayer::dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) { - ApplicationLayer::dataIndividualIndication(hopType, priority, tsap, apdu); + if (apdu.type() == SecureService) + { + // Decrypt secure APDU + + // Process decrypted inner APDU + ApplicationLayer::dataIndividualIndication(hopType, priority, tsap, apdu); + } + else + { + ApplicationLayer::dataIndividualIndication(hopType, priority, tsap, apdu); + } } void SecureApplicationLayer::dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) { - ApplicationLayer::dataIndividualConfirm(ack, hopType, priority, tsap, apdu, status); + if (apdu.type() == SecureService) + { + // Decrypt secure APDU + + // Process decrypted inner APDU + ApplicationLayer::dataIndividualConfirm(ack, hopType, priority, tsap, apdu, status); + } + else + { + ApplicationLayer::dataIndividualConfirm(ack, hopType, priority, tsap, apdu, status); + } } void SecureApplicationLayer::connectIndication(uint16_t tsap) @@ -85,7 +143,40 @@ void SecureApplicationLayer::disconnectConfirm(Priority priority, uint16_t tsap, void SecureApplicationLayer::dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) { - ApplicationLayer::dataConnectedIndication(priority, tsap, apdu); + if (apdu.type() == SecureService) + { + // Decrypt secure APDU + + println("Secure APDU: "); + apdu.printPDU(); + + uint16_t plainApduLength = apdu.length() - 1 - 6 - 4; // secureAdsuLength - sizeof(scf) - sizeof(seqNum) - sizeof(mac) + CemiFrame plainFrame(plainApduLength); + + uint16_t srcAddress = apdu.frame().sourceAddress(); + uint16_t dstAddress = apdu.frame().destinationAddress(); + uint8_t tpci = apdu.frame().data()[TPDU_LPDU_DIFF]; // FIXME: when cEMI class is refactored, there might be additional info fields in cEMI [fixed TPDU_LPDU_DIFF] + print("Secure Debug: TPCI: "); + println(tpci, HEX); + + // FIXME: when cEMI class is refactored, there might be additional info fields in cEMI (fixed APDU_LPDU_DIFF) + if (decrypt(plainFrame.data()+APDU_LPDU_DIFF, srcAddress, dstAddress, tpci, apdu.data(), apdu.length())) + { + println("Plain APDU: "); + plainFrame.apdu().printPDU(); + + // Process decrypted inner APDU + ApplicationLayer::dataConnectedIndication(priority, tsap, plainFrame.apdu()); + } + else + { + println("Decryption failed!"); + } + } + else + { + ApplicationLayer::dataConnectedIndication(priority, tsap, apdu); + } } void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap) @@ -93,28 +184,36 @@ void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap) ApplicationLayer::dataConnectedConfirm(tsap); } +/* to transport layer */ + void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) { ApplicationLayer::dataGroupRequest(ack, hopType, priority, tsap, apdu); } + void SecureApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) { ApplicationLayer::dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } + void SecureApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) { ApplicationLayer::dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); } + void SecureApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu) { ApplicationLayer::dataIndividualRequest(ack, hopType, priority, destination, apdu); } + void SecureApplicationLayer::dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu) { // apdu must be valid until it was confirmed ApplicationLayer::dataConnectedRequest(tsap, priority, apdu); } +/* encryption/decryption stuff */ + class TpTelegram { public: @@ -325,7 +424,7 @@ bool SecureApplicationLayer::decrypt(uint8_t* plainApdu, uint16_t srcAddr, uint1 pBuf = popByte(scf, secureAsdu); bool toolAccess = ((scf & 0x80) == 0x80); - bool systemBroadcast = ((scf & 0x08) == 0x08); + // bool systemBroadcast = ((scf & 0x08) == 0x08); // not used for decryption uint8_t sai = (scf >> 4) & 0x07; // sai can only be 0x0 (CCM auth only) or 0x1 (CCM with auth+conf), other values are reserved bool authOnly = ( sai == 0); uint8_t service = (scf & 0x07); // only 0x0 (S-A_Data-PDU), 0x2 (S-A_Sync_Req-PDU) or 0x3 (S-A_Sync_Rsp-PDU) are valid values diff --git a/src/knx/secure_application_layer.h b/src/knx/secure_application_layer.h index 10c990d..22e04f7 100644 --- a/src/knx/secure_application_layer.h +++ b/src/knx/secure_application_layer.h @@ -25,29 +25,29 @@ class SecureApplicationLayer : public ApplicationLayer SecureApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau); // from transport layer - void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); - void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, - 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); - void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status); - void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); - void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); - void connectIndication(uint16_t tsap); - void connectConfirm(uint16_t destination, uint16_t tsap, bool status); - void disconnectIndication(uint16_t tsap); - void disconnectConfirm(Priority priority, uint16_t tsap, bool status); - void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu); - void dataConnectedConfirm(uint16_t tsap); + virtual void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) override; + virtual void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, + APDU& apdu, bool status) override; + virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override; + virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) override; + virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override; + virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) override; + virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override; + virtual void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) override; + virtual void connectIndication(uint16_t tsap) override; + virtual void connectConfirm(uint16_t destination, uint16_t tsap, bool status) override; + virtual void disconnectIndication(uint16_t tsap) override; + virtual void disconnectConfirm(Priority priority, uint16_t tsap, bool status) override; + virtual void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) override; + virtual void dataConnectedConfirm(uint16_t tsap) override; protected: // to transport layer - virtual void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); - virtual void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); - virtual void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); - virtual void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu); - virtual void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu); // apdu must be valid until it was confirmed + virtual void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) override; + virtual void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) override; + virtual void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) override; + virtual void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu) override; + virtual void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu) override; // apdu must be valid until it was confirmed private: uint32_t calcAuthOnlyMac(uint8_t* apdu, uint8_t apduLength, uint8_t* key, uint8_t* iv, uint8_t* ctr0);