From 281fe4ab0275a528d37af68947fa4f72b5f7c628 Mon Sep 17 00:00:00 2001 From: Nanosonde <2073569+nanosonde@users.noreply.github.com> Date: Wed, 27 May 2020 20:36:41 +0200 Subject: [PATCH] initial commit --- examples/knx-linux/CMakeLists.txt | 4 +- src/knx/application_layer.cpp | 54 ++++++++++---- src/knx/application_layer.h | 8 ++ src/knx/bau_systemB.h | 7 +- src/knx/config.h | 2 + src/knx/secure_application_layer.cpp | 106 +++++++++++++++++++++++++++ src/knx/secure_application_layer.h | 53 ++++++++++++++ 7 files changed, 216 insertions(+), 18 deletions(-) create mode 100644 src/knx/secure_application_layer.cpp create mode 100644 src/knx/secure_application_layer.h diff --git a/examples/knx-linux/CMakeLists.txt b/examples/knx-linux/CMakeLists.txt index 9660b58..c669c13 100644 --- a/examples/knx-linux/CMakeLists.txt +++ b/examples/knx-linux/CMakeLists.txt @@ -75,7 +75,9 @@ add_executable(knx-linux ../../src/knx/rf_medium_object.h ../../src/knx/rf_physical_layer.cpp ../../src/knx/rf_physical_layer.h - ../../src/knx/table_object.cpp + ../../src/knx/secure_application_layer.cpp + ../../src/knx/secure_application_layer.h + ../../src/knx/table_object.cpp ../../src/knx/table_object.h ../../src/knx/tpdu.cpp ../../src/knx/tpdu.h diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 74f99d8..abe340c 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -267,7 +267,7 @@ void ApplicationLayer::groupValueReadRequest(AckType ack, uint16_t asap, Priorit uint16_t tsap = (uint16_t)value; // first to bus then to itself - _transportLayer->dataGroupRequest(ack, hopType, priority, tsap, apdu); + dataGroupRequest(ack, hopType, priority, tsap, apdu); dataGroupIndication(hopType, priority, tsap, apdu); } @@ -290,7 +290,7 @@ void ApplicationLayer::individualAddressWriteRequest(AckType ack, HopCountType h apdu.type(IndividualAddressWrite); uint8_t* apduData = apdu.data(); pushWord(newaddress, apduData + 1); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::individualAddressReadRequest(AckType ack, HopCountType hopType) @@ -298,7 +298,7 @@ void ApplicationLayer::individualAddressReadRequest(AckType ack, HopCountType ho CemiFrame frame(1); APDU& apdu = frame.apdu(); apdu.type(IndividualAddressRead); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::individualAddressReadResponse(AckType ack, HopCountType hopType) @@ -306,7 +306,7 @@ void ApplicationLayer::individualAddressReadResponse(AckType ack, HopCountType h CemiFrame frame(1); APDU& apdu = frame.apdu(); apdu.type(IndividualAddressResponse); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::individualAddressSerialNumberReadRequest(AckType ack, HopCountType hopType, uint8_t * serialNumber) @@ -316,7 +316,7 @@ void ApplicationLayer::individualAddressSerialNumberReadRequest(AckType ack, Hop apdu.type(IndividualAddressSerialNumberRead); uint8_t* data = apdu.data() + 1; memcpy(data, serialNumber, 6); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::individualAddressSerialNumberReadResponse(AckType ack, HopCountType hopType, @@ -329,7 +329,7 @@ void ApplicationLayer::individualAddressSerialNumberReadResponse(AckType ack, Ho memcpy(data, serialNumber, 6); data += 6; pushWord(domainAddress, data); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::individualAddressSerialNumberWriteRequest(AckType ack, HopCountType hopType, uint8_t * serialNumber, @@ -342,7 +342,7 @@ void ApplicationLayer::individualAddressSerialNumberWriteRequest(AckType ack, Ho memcpy(data, serialNumber, 6); data += 6; pushWord(newaddress, data); - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); + dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::deviceDescriptorReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, @@ -423,7 +423,7 @@ void ApplicationLayer::systemNetworkParameterReadResponse(Priority priority, Hop //apdu.printPDU(); - _transportLayer->dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); + dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); } //TODO: ApplicationLayer::domainAddressSerialNumberWriteRequest() @@ -442,7 +442,7 @@ void ApplicationLayer::domainAddressSerialNumberReadResponse(Priority priority, //apdu.printPDU(); - _transportLayer->dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); + dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); } //TODO: ApplicationLayer::IndividualAddressSerialNumberWriteRequest() @@ -461,7 +461,7 @@ void ApplicationLayer::IndividualAddressSerialNumberReadResponse(Priority priori //apdu.printPDU(); - _transportLayer->dataBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); + dataBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); } void ApplicationLayer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, @@ -652,9 +652,9 @@ void ApplicationLayer::propertyDataSend(ApduType type, AckType ack, Priority pri memcpy(apduData, data, length); if (asap == _connectedTsap) - _transportLayer->dataConnectedRequest(asap, priority, apdu); + dataConnectedRequest(asap, priority, apdu); else - _transportLayer->dataIndividualRequest(ack, hopType, priority, asap, apdu); + dataIndividualRequest(ack, hopType, priority, asap, apdu); } void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap, Priority priority, HopCountType hopType, @@ -676,7 +676,7 @@ void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap, } // no need to check if there is a tsap. This is a response, so the read got trough uint16_t tsap = (uint16_t)_assocTable.translateAsap(asap); - _transportLayer->dataGroupRequest(ack, hopType, priority, tsap, apdu); + dataGroupRequest(ack, hopType, priority, tsap, apdu); dataGroupIndication(hopType, priority, tsap, apdu); } @@ -911,12 +911,34 @@ void ApplicationLayer::individualConfirm(AckType ack, HopCountType hopType, Prio void ApplicationLayer::individualSend(AckType ack, HopCountType hopType, Priority priority, uint16_t asap, APDU& apdu) { if (asap == _connectedTsap) - _transportLayer->dataConnectedRequest(asap, priority, apdu); + dataConnectedRequest(asap, priority, apdu); else - _transportLayer->dataIndividualRequest(ack, hopType, priority, asap, apdu); + dataIndividualRequest(ack, hopType, priority, asap, apdu); } bool ApplicationLayer::isConnected() { return (_connectedTsap >= 0); -} \ No newline at end of file +} + +void ApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) +{ + _transportLayer->dataGroupRequest(ack, hopType, priority, tsap, apdu); +} +void ApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) +{ + _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); +} +void ApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) +{ + _transportLayer->dataSystemBroadcastRequest(AckDontCare, hopType, SystemPriority, apdu); +} +void ApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu) +{ + _transportLayer->dataIndividualRequest(ack, hopType, priority, destination, apdu); +} +void ApplicationLayer::dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu) +{ + // apdu must be valid until it was confirmed + _transportLayer->dataConnectedRequest(tsap, priority, apdu); +} diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index 401a653..cb84197 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -139,6 +139,14 @@ class ApplicationLayer uint8_t* knxSerialNumber); #pragma endregion + 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 + 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, diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index b651150..5877747 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -8,6 +8,7 @@ #include "group_object_table_object.h" #include "application_program_object.h" #include "application_layer.h" +#include "secure_application_layer.h" #include "transport_layer.h" #include "network_layer.h" #include "data_link_layer.h" @@ -91,10 +92,14 @@ class BauSystemB : protected BusAccessUnit GroupObjectTableObject _groupObjTable; ApplicationProgramObject _appProgram; Platform& _platform; +#ifdef USE_DATASECURE + SecureApplicationLayer _appLayer; +#else ApplicationLayer _appLayer; +#endif TransportLayer _transLayer; NetworkLayer _netLayer; bool _configured = true; RestartState _restartState = Idle; uint32_t _restartDelay = 0; -}; \ No newline at end of file +}; diff --git a/src/knx/config.h b/src/knx/config.h index 2554c3b..fdc3ec9 100644 --- a/src/knx/config.h +++ b/src/knx/config.h @@ -19,3 +19,5 @@ #ifdef USE_USB #define USE_CEMI_SERVER #endif + +#define USE_DATASECURE diff --git a/src/knx/secure_application_layer.cpp b/src/knx/secure_application_layer.cpp new file mode 100644 index 0000000..47578c0 --- /dev/null +++ b/src/knx/secure_application_layer.cpp @@ -0,0 +1,106 @@ +#include "secure_application_layer.h" +#include "transport_layer.h" +#include "cemi_frame.h" +#include "association_table_object.h" +#include "apdu.h" +#include "bau.h" +#include "string.h" +#include "bits.h" +#include + +SecureApplicationLayer::SecureApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau): + ApplicationLayer(assocTable, bau) +{ +} + +void SecureApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) +{ + 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); +} + +void SecureApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) +{ + ApplicationLayer::dataBroadcastIndication(hopType, priority, source, apdu); +} + +void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) +{ + ApplicationLayer::dataBroadcastConfirm(ack, hopType, priority, apdu, status); +} + +void SecureApplicationLayer::dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) +{ + ApplicationLayer::dataSystemBroadcastIndication(hopType, priority, source, apdu); +} + +void SecureApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) +{ + ApplicationLayer::dataSystemBroadcastConfirm(hopType, priority, apdu, status); +} + +void SecureApplicationLayer::dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) +{ + 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); +} + +void SecureApplicationLayer::connectIndication(uint16_t tsap) +{ + ApplicationLayer::connectIndication(tsap); +} + +void SecureApplicationLayer::connectConfirm(uint16_t destination, uint16_t tsap, bool status) +{ + ApplicationLayer::connectConfirm(destination, tsap, status); +} + +void SecureApplicationLayer::disconnectIndication(uint16_t tsap) +{ + ApplicationLayer::disconnectIndication(tsap); +} + +void SecureApplicationLayer::disconnectConfirm(Priority priority, uint16_t tsap, bool status) +{ + ApplicationLayer::disconnectConfirm(priority, tsap, status); +} + +void SecureApplicationLayer::dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) +{ + ApplicationLayer::dataConnectedIndication(priority, tsap, apdu); +} + +void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap) +{ + ApplicationLayer::dataConnectedConfirm(tsap); +} + +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); +} diff --git a/src/knx/secure_application_layer.h b/src/knx/secure_application_layer.h new file mode 100644 index 0000000..35f4ebf --- /dev/null +++ b/src/knx/secure_application_layer.h @@ -0,0 +1,53 @@ +#pragma once + +#include "application_layer.h" +#include +#include "knx_types.h" +#include "apdu.h" + +class AssociationTableObject; +class BusAccessUnit; +/** + * 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 SecureApplicationLayer : public ApplicationLayer +{ + 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 + */ + 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); + + 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 + + private: +};