diff --git a/src/knx/application_layer.cpp b/src/knx/application_layer.cpp index 7899662..4dcb993 100644 --- a/src/knx/application_layer.cpp +++ b/src/knx/application_layer.cpp @@ -77,157 +77,99 @@ void ApplicationLayer::dataGroupConfirm(AckType ack, HopCountType hopType, Prior } } -void ApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, SystemBroadcast broadcastType) +void ApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) { uint8_t* data = apdu.data(); - - if (broadcastType == Broadcast) + switch (apdu.type()) { - // APCI on Broadcast - switch (apdu.type()) + case IndividualAddressWrite: { - case IndividualAddressWrite: - { - uint16_t newAddress; - popWord(newAddress, data + 1); - _bau.individualAddressWriteIndication(hopType, newAddress); - break; - } - case IndividualAddressRead: - _bau.individualAddressReadIndication(hopType); - break; - case IndividualAddressResponse: - _bau.individualAddressReadAppLayerConfirm(hopType, apdu.frame().sourceAddress()); - break; - case IndividualAddressSerialNumberRead: - { - uint8_t* knxSerialNumber = &data[1]; - _bau.individualAddressSerialNumberReadIndication(priority, hopType, knxSerialNumber); - break; - } - case IndividualAddressSerialNumberResponse: - { - uint16_t domainAddress; - popWord(domainAddress, data + 7); - _bau.individualAddressSerialNumberReadAppLayerConfirm(hopType, data + 1, apdu.frame().sourceAddress(), - domainAddress); - break; - } - case IndividualAddressSerialNumberWrite: - { - uint8_t* knxSerialNumber = &data[1]; - uint16_t newIndividualAddress; - popWord(newIndividualAddress, &data[7]); - _bau.individualAddressSerialNumberWriteIndication(priority, hopType, newIndividualAddress, knxSerialNumber); - break; - } -#if !((MEDIUM_TYPE == 5) || (MEDIUM_TYPE == 0)) - default: - print("Broadcast-indication: unhandled APDU-Type: "); - println(apdu.type()); - break; + uint16_t newAddress; + popWord(newAddress, data + 1); + _bau.individualAddressWriteIndication(hopType, newAddress); + break; } - } - else if (broadcastType == SysBroadcast) - { - // APCI on SystemBroadcast - switch (apdu.type()) + case IndividualAddressRead: + _bau.individualAddressReadIndication(hopType); + break; + case IndividualAddressResponse: + _bau.individualAddressReadAppLayerConfirm(hopType, apdu.frame().sourceAddress()); + break; + case IndividualAddressSerialNumberRead: { -#endif - // TODO: testInfo could be of any length - case SystemNetworkParameterRead: - { - uint16_t objectType; - uint16_t propertyId; - uint8_t testInfo[2]; - popWord(objectType, data + 1); - popWord(propertyId, data + 3); - popByte(testInfo[0], data + 4); - popByte(testInfo[1], data + 5); - propertyId = (propertyId >> 4) & 0x0FFF;; - testInfo[0] &= 0x0F; - _bau.systemNetworkParameterReadIndication(priority, hopType, objectType, propertyId, testInfo, sizeof(testInfo)); - break; - } - case DomainAddressSerialNumberWrite: - { - const uint8_t* knxSerialNumber = &data[1]; - const uint8_t* domainAddress = &data[7]; - _bau.domainAddressSerialNumberWriteIndication(priority, hopType, domainAddress, knxSerialNumber); - break; - } - case DomainAddressSerialNumberRead: - { - const uint8_t* knxSerialNumber = &data[1]; - _bau.domainAddressSerialNumberReadIndication(priority, hopType, knxSerialNumber); - break; - } -#if !((MEDIUM_TYPE == 5) || (MEDIUM_TYPE == 0)) - default: - if (broadcastType == SysBroadcast) - { - print("System"); - } -#endif - print("Broadcast-indication: unhandled APDU-Type: "); - println(apdu.type()); - break; + uint8_t* knxSerialNumber = &data[1]; + _bau.individualAddressSerialNumberReadIndication(priority, hopType, knxSerialNumber); + break; } + case IndividualAddressSerialNumberResponse: + { + uint16_t domainAddress; + popWord(domainAddress, data + 7); + _bau.individualAddressSerialNumberReadAppLayerConfirm(hopType, data + 1, apdu.frame().sourceAddress(), + domainAddress); + break; + } + case IndividualAddressSerialNumberWrite: + { + uint8_t* knxSerialNumber = &data[1]; + uint16_t newIndividualAddress; + popWord(newIndividualAddress, &data[7]); + _bau.individualAddressSerialNumberWriteIndication(priority, hopType, newIndividualAddress, knxSerialNumber); + break; + } + default: + print("Broadcast-indication: unhandled APDU-Type: "); + println(apdu.type()); } } -void ApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status, SystemBroadcast broadcastType) +void ApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) { uint8_t* data = apdu.data(); - - if (broadcastType == Broadcast) + switch (apdu.type()) { - // APCI on Broadcast - switch (apdu.type()) + case IndividualAddressWrite: { - case IndividualAddressWrite: - { - uint16_t newAddress; - popWord(newAddress, data + 1); - _bau.individualAddressWriteLocalConfirm(ack, hopType, newAddress, status); - break; - } - case IndividualAddressRead: - _bau.individualAddressReadLocalConfirm(ack, hopType, status); - break; - case IndividualAddressResponse: - _bau.individualAddressReadResponseConfirm(ack, hopType, status); - break; - case IndividualAddressSerialNumberRead: - _bau.individualAddressSerialNumberReadLocalConfirm(ack, hopType, data + 1, status); - break; - case IndividualAddressSerialNumberResponse: - { - uint16_t domainAddress; - popWord(domainAddress, data + 7); - _bau.individualAddressSerialNumberReadResponseConfirm(ack, hopType, data + 1, domainAddress, status); - break; - } - case IndividualAddressSerialNumberWrite: - { - uint16_t newAddress; - popWord(newAddress, data + 7); - _bau.individualAddressSerialNumberWriteLocalConfirm(ack, hopType, data + 1, newAddress, status); - break; - } -#if !((MEDIUM_TYPE == 5) || (MEDIUM_TYPE == 0)) - default: - print("Broadcast-confirm: unhandled APDU-Type: "); - println(apdu.type()); - break; + uint16_t newAddress; + popWord(newAddress, data + 1); + _bau.individualAddressWriteLocalConfirm(ack, hopType, newAddress, status); + break; } - } - else if (broadcastType == SysBroadcast) - { - // APCI on SystemBroadcast - switch (apdu.type()) + case IndividualAddressRead: + _bau.individualAddressReadLocalConfirm(ack, hopType, status); + break; + case IndividualAddressResponse: + _bau.individualAddressReadResponseConfirm(ack, hopType, status); + break; + case IndividualAddressSerialNumberRead: + _bau.individualAddressSerialNumberReadLocalConfirm(ack, hopType, data + 1, status); + break; + case IndividualAddressSerialNumberResponse: { -#endif + uint16_t domainAddress; + popWord(domainAddress, data + 7); + _bau.individualAddressSerialNumberReadResponseConfirm(ack, hopType, data + 1, domainAddress, status); + break; + } + case IndividualAddressSerialNumberWrite: + { + uint16_t newAddress; + popWord(newAddress, data + 7); + _bau.individualAddressSerialNumberWriteLocalConfirm(ack, hopType, data + 1, newAddress, status); + break; + } + default: + print("Broadcast-confirm: unhandled APDU-Type: "); + println(apdu.type()); + } +} + +void ApplicationLayer::dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) +{ + const uint8_t* data = apdu.data(); + switch (apdu.type()) + { + // TODO: testInfo could be of any length case SystemNetworkParameterRead: { uint16_t objectType; @@ -239,33 +181,66 @@ void ApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, P popByte(testInfo[1], data + 5); propertyId = (propertyId >> 4) & 0x0FFF;; testInfo[0] &= 0x0F; - //TODO: _bau.systemNetworkParameterReadLocalConfirm(priority, hopType, objectType, propertyId, testInfo, sizeof(testInfo), status); + _bau.systemNetworkParameterReadIndication(priority, hopType, objectType, propertyId, testInfo, sizeof(testInfo)); break; } case DomainAddressSerialNumberWrite: { const uint8_t* knxSerialNumber = &data[1]; const uint8_t* domainAddress = &data[7]; - //TODO: _bau.domainAddressSerialNumberWriteLocalConfirm(priority, hopType, domainAddress, knxSerialNumber, status); + _bau.domainAddressSerialNumberWriteIndication(priority, hopType, domainAddress, knxSerialNumber); break; } case DomainAddressSerialNumberRead: { const uint8_t* knxSerialNumber = &data[1]; - //TODO: _bau.domainAddressSerialNumberReadLocalConfirm(priority, hopType, knxSerialNumber, status); + _bau.domainAddressSerialNumberReadIndication(priority, hopType, knxSerialNumber); break; } default: -#if !((MEDIUM_TYPE == 5) || (MEDIUM_TYPE == 0)) - if (broadcastType == SysBroadcast) - { - print("System"); - } -#endif - print("Broadcast-confirm: unhandled APDU-Type: "); + print("SystemBroadcast-indication: unhandled APDU-Type: "); println(apdu.type()); break; + } +} + +void ApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) +{ + const uint8_t* data = apdu.data(); + switch (apdu.type()) + { + // TODO: testInfo could be of any length + case SystemNetworkParameterRead: + { + uint16_t objectType; + uint16_t propertyId; + uint8_t testInfo[2]; + popWord(objectType, data + 1); + popWord(propertyId, data + 3); + popByte(testInfo[0], data + 4); + popByte(testInfo[1], data + 5); + propertyId = (propertyId >> 4) & 0x0FFF;; + testInfo[0] &= 0x0F; + _bau.systemNetworkParameterReadLocalConfirm(priority, hopType, objectType, propertyId, testInfo, sizeof(testInfo), status); + break; } + case DomainAddressSerialNumberWrite: + { + const uint8_t* knxSerialNumber = &data[1]; + const uint8_t* domainAddress = &data[7]; + _bau.domainAddressSerialNumberWriteLocalConfirm(priority, hopType, domainAddress, knxSerialNumber, status); + break; + } + case DomainAddressSerialNumberRead: + { + const uint8_t* knxSerialNumber = &data[1]; + _bau.domainAddressSerialNumberReadLocalConfirm(priority, hopType, knxSerialNumber, status); + break; + } + default: + print("SystemBroadcast-confirm: unhandled APDU-Type: "); + println(apdu.type()); + break; } } @@ -1014,11 +989,11 @@ void ApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Prior } void ApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) { - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu, Broadcast); + _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) { - _transportLayer->dataBroadcastRequest(ack, hopType, SystemPriority, apdu, SysBroadcast); + _transportLayer->dataSystemBroadcastRequest(ack, hopType, SystemPriority, apdu); } void ApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu) { diff --git a/src/knx/application_layer.h b/src/knx/application_layer.h index 1b66f72..28d7307 100644 --- a/src/knx/application_layer.h +++ b/src/knx/application_layer.h @@ -65,8 +65,10 @@ class ApplicationLayer */ virtual void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); - virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, SystemBroadcast broadcastType); - virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status, SystemBroadcast broadcastType); + 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); diff --git a/src/knx/bau.cpp b/src/knx/bau.cpp index f28c94f..b09f513 100644 --- a/src/knx/bau.cpp +++ b/src/knx/bau.cpp @@ -264,6 +264,20 @@ void BusAccessUnit::domainAddressSerialNumberReadIndication(Priority priority, H { } +void BusAccessUnit::systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, uint16_t objectType, + uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength, bool status) +{ +} + +void BusAccessUnit::domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* rfDoA, + const uint8_t* knxSerialNumber, bool status) +{ +} + +void BusAccessUnit::domainAddressSerialNumberReadLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* knxSerialNumber, bool status) +{ +} + void BusAccessUnit::propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t& numberOfElements, uint16_t startIndex, uint8_t** data, uint32_t& length) diff --git a/src/knx/bau.h b/src/knx/bau.h index 444c61f..d2d9c80 100644 --- a/src/knx/bau.h +++ b/src/knx/bau.h @@ -123,6 +123,14 @@ class BusAccessUnit virtual void domainAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const uint8_t* knxSerialNumber); + virtual void systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, uint16_t objectType, + uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength, bool status); + + virtual void domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* rfDoA, + const uint8_t* knxSerialNumber, bool status); + + virtual void domainAddressSerialNumberReadLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* knxSerialNumber, bool status); + virtual void propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t& numberOfElements, uint16_t startIndex, uint8_t** data, uint32_t& length); diff --git a/src/knx/bau27B0.cpp b/src/knx/bau27B0.cpp index 60f1b16..3b99847 100644 --- a/src/knx/bau27B0.cpp +++ b/src/knx/bau27B0.cpp @@ -170,4 +170,14 @@ void Bau27B0::individualAddressSerialNumberReadIndication(Priority priority, Hop _appLayer.IndividualAddressSerialNumberReadResponse(priority, hopType, _rfMediumObj.rfDomainAddress(), knxSerialNumber); } +void Bau27B0::domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* rfDoA, + const uint8_t* knxSerialNumber, bool status) +{ +} + +void Bau27B0::domainAddressSerialNumberReadLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* knxSerialNumber, bool status) +{ +} + + #endif // #ifdef USE_RF diff --git a/src/knx/bau27B0.h b/src/knx/bau27B0.h index 8b270b6..678a659 100644 --- a/src/knx/bau27B0.h +++ b/src/knx/bau27B0.h @@ -34,5 +34,8 @@ class Bau27B0 : public BauSystemB void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, uint16_t newIndividualAddress, uint8_t* knxSerialNumber) override; void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, uint8_t* knxSerialNumber) override; + void domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* rfDoA, + const uint8_t* knxSerialNumber, bool status) override; + void domainAddressSerialNumberReadLocalConfirm(Priority priority, HopCountType hopType, const uint8_t* knxSerialNumber, bool status) override; }; -#endif \ No newline at end of file +#endif diff --git a/src/knx/bau_systemB.cpp b/src/knx/bau_systemB.cpp index f3cc234..1a80920 100644 --- a/src/knx/bau_systemB.cpp +++ b/src/knx/bau_systemB.cpp @@ -419,6 +419,11 @@ void BauSystemB::systemNetworkParameterReadIndication(Priority priority, HopCoun } } +void BauSystemB::systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, uint16_t objectType, + uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength, bool status) +{ +} + void BauSystemB::propertyValueRead(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t &numberOfElements, uint16_t startIndex, uint8_t **data, uint32_t &length) diff --git a/src/knx/bau_systemB.h b/src/knx/bau_systemB.h index 69c91de..94bbac1 100644 --- a/src/knx/bau_systemB.h +++ b/src/knx/bau_systemB.h @@ -74,6 +74,8 @@ class BauSystemB : protected BusAccessUnit uint8_t* data, uint8_t dataLength) override; void systemNetworkParameterReadIndication(Priority priority, HopCountType hopType, uint16_t objectType, uint16_t propertyId, uint8_t* testInfo, uint16_t testinfoLength) override; + void systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, uint16_t objectType, + uint16_t propertyId, uint8_t* testInfo, uint16_t testInfoLength, bool status) override; void connectConfirm(uint16_t tsap) override; virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0; diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index fb371a6..a8421e8 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -41,16 +41,11 @@ void DataLinkLayer::dataRequest(AckType ack, AddressType addrType, uint16_t dest sendTelegram(npdu, ack, destinationAddr, addrType, format, priority, Broadcast); } -void DataLinkLayer::broadcastRequest(AckType ack, FrameFormat format, Priority priority, NPDU& npdu, SystemBroadcast broadcastType) +void DataLinkLayer::systemBroadcastRequest(AckType ack, FrameFormat format, Priority priority, NPDU& npdu) { // System Broadcast requests will always be transmitted as broadcast with KNX serial number for open media (e.g. RF medium) // See 3.2.5 p.22 -#if (MEDIUM_TYPE == 5)||(MEDIUM_TYPE == 0) - (void)broadcastType; // not used on TP/IP, always normal broadcast - sendTelegram(npdu, ack, 0, GroupAddress, format, priority, Broadcast); -#else - sendTelegram(npdu, ack, 0, GroupAddress, format, priority, broadcastType); -#endif + sendTelegram(npdu, ack, 0, GroupAddress, format, priority, SysBroadcast); } void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success) @@ -65,7 +60,7 @@ void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success) FrameFormat type = frame.frameType(); Priority priority = frame.priority(); NPDU& npdu = frame.npdu(); - SystemBroadcast broadcastType = frame.systemBroadcast(); + SystemBroadcast systemBroadcast = frame.systemBroadcast(); #ifdef USE_CEMI_SERVER // if the confirmation was caused by a tunnel request then @@ -78,13 +73,10 @@ void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success) #endif if (addrType == GroupAddress && destination == 0) - { - _networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success, broadcastType); - } - else if (addrType == InduvidualAddress && destination == 0) - { - _networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success, broadcastType); - } + if (systemBroadcast == SysBroadcast) + _networkLayer.systemBroadcastConfirm(ack, type, priority, source, npdu, success); + else + _networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success); else _networkLayer.dataConfirm(ack, addrType, destination, type, priority, source, npdu, success); @@ -101,7 +93,7 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) Priority priority = frame.priority(); NPDU& npdu = frame.npdu(); uint16_t ownAddr = _deviceObject.induvidualAddress(); - SystemBroadcast broadcastType = frame.systemBroadcast(); + SystemBroadcast systemBroadcast = frame.systemBroadcast(); #ifdef USE_CEMI_SERVER // Do not send our own message back to the tunnel @@ -116,11 +108,10 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) if (addrType == GroupAddress && destination == 0) { - _networkLayer.broadcastIndication(ack, type, npdu, priority, source, broadcastType); - } - else if (addrType == InduvidualAddress && destination == 0) - { - _networkLayer.broadcastIndication(ack, type, npdu, priority, source, broadcastType); + if (systemBroadcast == SysBroadcast) + _networkLayer.systemBroadcastIndication(ack, type, npdu, priority, source); + else + _networkLayer.broadcastIndication(ack, type, npdu, priority, source); } else { @@ -140,7 +131,7 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) } } -bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationAddr, AddressType addrType, FrameFormat format, Priority priority, SystemBroadcast broadcastType) +bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationAddr, AddressType addrType, FrameFormat format, Priority priority, SystemBroadcast systemBroadcast) { CemiFrame& frame = npdu.frame(); frame.messageCode(L_data_ind); @@ -149,7 +140,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA frame.addressType(addrType); frame.priority(priority); frame.repetition(RepititionAllowed); - frame.systemBroadcast(broadcastType); + frame.systemBroadcast(systemBroadcast); if (npdu.octetCount() <= 15) frame.frameType(StandardFrame); diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index 769c267..28ba679 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -24,7 +24,7 @@ class DataLinkLayer // from network layer void dataRequest(AckType ack, AddressType addrType, uint16_t destinationAddr, FrameFormat format, Priority priority, NPDU& npdu); - void broadcastRequest(AckType ack, FrameFormat format, Priority priority, NPDU& npdu, SystemBroadcast broadcastType); + void systemBroadcastRequest(AckType ack, FrameFormat format, Priority priority, NPDU& npdu); virtual void loop() = 0; virtual void enabled(bool value) = 0; virtual bool enabled() const = 0; @@ -32,7 +32,7 @@ class DataLinkLayer protected: void frameRecieved(CemiFrame& frame); void dataConReceived(CemiFrame& frame, bool success); - bool sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAddr, AddressType addrType, FrameFormat format, Priority priority, SystemBroadcast broadcastType); + bool sendTelegram(NPDU& npdu, AckType ack, uint16_t destinationAddr, AddressType addrType, FrameFormat format, Priority priority, SystemBroadcast systemBroadcast); virtual bool sendFrame(CemiFrame& frame) = 0; uint8_t* frameData(CemiFrame& frame); DeviceObject& _deviceObject; diff --git a/src/knx/network_layer.cpp b/src/knx/network_layer.cpp index df53a17..869c4fc 100644 --- a/src/knx/network_layer.cpp +++ b/src/knx/network_layer.cpp @@ -43,10 +43,8 @@ void NetworkLayer::dataIndication(AckType ack, AddressType addrType, uint16_t de _transportLayer.dataGroupIndication(destination, hopType, priority, source, npdu.tpdu()); return; } - - // assert: programming error - // should never be reached! - // destination == 0 && (addrType == InduvidualAddress || ddrType == GroupAddress) + // destination == 0 + _transportLayer.dataBroadcastIndication(hopType, priority, source, npdu.tpdu()); } void NetworkLayer::dataConfirm(AckType ack, AddressType addressType, uint16_t destination, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status) @@ -63,22 +61,32 @@ void NetworkLayer::dataConfirm(AckType ack, AddressType addressType, uint16_t de _transportLayer.dataGroupConfirm(ack, source, destination, hopType, priority, npdu.tpdu(), status); return; } - - // assert: programming error - // should never be reached! - // destination == 0 && (addrType == InduvidualAddress || ddrType == GroupAddress) + // destination == 0 + _transportLayer.dataBroadcastConfirm(ack, hopType, priority, npdu.tpdu(), status); } -void NetworkLayer::broadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source, SystemBroadcast broadcastType) +void NetworkLayer::broadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source) { HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter; - _transportLayer.dataBroadcastIndication(hopType, priority, source, npdu.tpdu(), broadcastType); + _transportLayer.dataBroadcastIndication(hopType, priority, source, npdu.tpdu()); } -void NetworkLayer::broadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status, SystemBroadcast broadcastType) +void NetworkLayer::broadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status) { HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter; - _transportLayer.dataBroadcastConfirm(ack, hopType, priority, npdu.tpdu(), status, broadcastType); + _transportLayer.dataBroadcastConfirm(ack, hopType, priority, npdu.tpdu(), status); +} + +void NetworkLayer::systemBroadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source) +{ + HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter; + _transportLayer.dataSystemBroadcastIndication(hopType, priority, source, npdu.tpdu()); +} + +void NetworkLayer::systemBroadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status) +{ + HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter; + _transportLayer.dataSystemBroadcastConfirm(ack, hopType, npdu.tpdu(), priority, status); } void NetworkLayer::dataIndividualRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu) @@ -110,7 +118,12 @@ void NetworkLayer::dataGroupRequest(AckType ack, uint16_t destination, HopCountT sendDataRequest(tpdu, hopType, ack, destination, priority, GroupAddress); } -void NetworkLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, SystemBroadcast broadcastType) +void NetworkLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu) +{ + sendDataRequest(tpdu, hopType, ack, 0, priority, GroupAddress); +} + +void NetworkLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu) { NPDU& npdu = tpdu.frame().npdu(); @@ -121,5 +134,5 @@ void NetworkLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Prior FrameFormat frameFormat = npdu.octetCount() > 15 ? ExtendedFrame : StandardFrame; - _dataLinkLayer->broadcastRequest(ack, frameFormat, priority, npdu, broadcastType); + _dataLinkLayer->systemBroadcastRequest(ack, frameFormat, priority, npdu); } diff --git a/src/knx/network_layer.h b/src/knx/network_layer.h index 17441dd..0b1f88e 100644 --- a/src/knx/network_layer.h +++ b/src/knx/network_layer.h @@ -21,14 +21,17 @@ class NetworkLayer void dataConfirm(AckType ack, AddressType addressType, uint16_t destination, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status); void broadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, - Priority priority, uint16_t source, SystemBroadcast broadcastType); - void broadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status, - SystemBroadcast broadcastType); + Priority priority, uint16_t source); + void broadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status); + void systemBroadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, + Priority priority, uint16_t source); + void systemBroadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status); // from transport layer void dataIndividualRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu); void dataGroupRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu); - void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, SystemBroadcast broadcastType); + void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu); + void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu); private: void sendDataRequest(TPDU& tpdu, HopCountType hopType, AckType ack, uint16_t destination, Priority priority, AddressType addrType); diff --git a/src/knx/secure_application_layer.cpp b/src/knx/secure_application_layer.cpp index 9370958..6dde69a 100644 --- a/src/knx/secure_application_layer.cpp +++ b/src/knx/secure_application_layer.cpp @@ -55,7 +55,7 @@ void SecureApplicationLayer::dataGroupConfirm(AckType ack, HopCountType hopType, } } -void SecureApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, SystemBroadcast broadcastType) +void SecureApplicationLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) { if (apdu.type() == SecureService) { @@ -64,13 +64,13 @@ void SecureApplicationLayer::dataBroadcastIndication(HopCountType hopType, Prior } else { - ApplicationLayer::dataBroadcastIndication(hopType, priority, source, apdu, broadcastType); + ApplicationLayer::dataBroadcastIndication(hopType, priority, source, apdu); } } -void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status, SystemBroadcast broadcastType) +void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) { - ApplicationLayer::dataBroadcastConfirm(ack, hopType, priority, apdu, status, broadcastType); + ApplicationLayer::dataBroadcastConfirm(ack, hopType, priority, apdu, status); } void SecureApplicationLayer::dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) @@ -375,7 +375,7 @@ void SecureApplicationLayer::block0(uint8_t* buffer, uint8_t* seqNum, uint16_t i pBuf = pushByte(payloadLength, pBuf); // Payload length } -void SecureApplicationLayer::blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr) +void SecureApplicationLayer::blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr) { uint8_t* pBuf = buffer; pBuf = pushByteArray(seqNum, 6, pBuf); @@ -442,7 +442,7 @@ bool SecureApplicationLayer::decrypt(uint8_t* plainApdu, uint16_t srcAddr, uint1 // Clear block counter0 buffer uint8_t ctr0[16] = {0x00}; // Create first block for block counter 0 - blockCtr0(ctr0, seqNum, srcAddr, dstAddr, false); + blockCtr0(ctr0, seqNum, srcAddr, dstAddr); uint32_t mac; pBuf = popInt(mac, pBuf); @@ -547,7 +547,7 @@ void SecureApplicationLayer::encrypt(uint8_t* buffer, uint16_t srcAddr, uint16_t // Clear block counter0 buffer uint8_t ctr0[16] = {0x00}; // Create first block for block counter 0 - blockCtr0(ctr0, seqNum, srcAddr, dstAddr, false); + blockCtr0(ctr0, seqNum, srcAddr, dstAddr); if (authOnly) { diff --git a/src/knx/secure_application_layer.h b/src/knx/secure_application_layer.h index 374189b..94805c4 100644 --- a/src/knx/secure_application_layer.h +++ b/src/knx/secure_application_layer.h @@ -28,8 +28,8 @@ class SecureApplicationLayer : public ApplicationLayer 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, SystemBroadcast broadcastType) override; - virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status, SystemBroadcast broadcastType) 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 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; @@ -52,7 +52,7 @@ class SecureApplicationLayer : public ApplicationLayer uint32_t calcConfAuthMac(uint8_t* associatedData, uint16_t associatedDataLength, uint8_t* apdu, uint8_t apduLength, uint8_t* key, uint8_t* iv); void block0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, uint8_t extFrameFormat, uint8_t tpci, uint8_t apci, uint8_t payloadLength); - void blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr); + void blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_t indSrcAddr, uint16_t dstAddr); uint64_t lastValidSequenceNumber(bool toolAcces, uint16_t srcAddr); diff --git a/src/knx/security_interface_object.cpp b/src/knx/security_interface_object.cpp index 5f414d4..b860818 100644 --- a/src/knx/security_interface_object.cpp +++ b/src/knx/security_interface_object.cpp @@ -76,7 +76,7 @@ const uint8_t* SecurityInterfaceObject::restore(const uint8_t* buffer) uint16_t SecurityInterfaceObject::saveSize() { //return 2 + InterfaceObject::saveSize(); - return 0; + return InterfaceObject::saveSize(); } #endif diff --git a/src/knx/transport_layer.cpp b/src/knx/transport_layer.cpp index aab3550..84d726b 100644 --- a/src/knx/transport_layer.cpp +++ b/src/knx/transport_layer.cpp @@ -373,14 +373,24 @@ void TransportLayer::dataGroupConfirm(AckType ack, uint16_t source, uint16_t des _applicationLayer.dataGroupConfirm(ack, hopType, priority, destination, tpdu.apdu(), status); } -void TransportLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu, SystemBroadcast broadcastType) +void TransportLayer::dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu) { - _applicationLayer.dataBroadcastIndication(hopType, priority, source, tpdu.apdu(), broadcastType); + _applicationLayer.dataBroadcastIndication(hopType, priority, source, tpdu.apdu()); } -void TransportLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, bool status, SystemBroadcast broadcastType) +void TransportLayer::dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, bool status) { - _applicationLayer.dataBroadcastConfirm(ack, hopType, priority, tpdu.apdu(), status, broadcastType); + _applicationLayer.dataBroadcastConfirm(ack, hopType, priority, tpdu.apdu(), status); +} + +void TransportLayer::dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu) +{ + _applicationLayer.dataSystemBroadcastIndication(hopType, priority, source, tpdu.apdu()); +} + +void TransportLayer::dataSystemBroadcastConfirm(AckType ack, HopCountType hopType, TPDU& tpdu, Priority priority, bool status) +{ + _applicationLayer.dataSystemBroadcastConfirm(hopType, priority, tpdu.apdu(), status); } void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) @@ -390,10 +400,16 @@ void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priorit _networkLayer->dataGroupRequest(ack, groupAdress, hopType, priority, tpdu); } -void TransportLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, SystemBroadcast broadcastType) +void TransportLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) { TPDU& tpdu = apdu.frame().tpdu(); - _networkLayer->dataBroadcastRequest(ack, hopType, priority, tpdu, broadcastType); + _networkLayer->dataBroadcastRequest(ack, hopType, priority, tpdu); +} + +void TransportLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu) +{ + TPDU& tpdu = apdu.frame().tpdu(); + return _networkLayer->dataSystemBroadcastRequest(ack, hopType, priority, tpdu); } void TransportLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu) @@ -514,7 +530,12 @@ void TransportLayer::ackTimeoutIndication() } } - +uint8_t TransportLayer::getTPCI(uint16_t dstAddress) +{ + // Return seqNum that would be used for sending next frame + // together with the TPDU type. + return ((_seqNoSend & 0xF) << 2) | ((dstAddress == _connectionAddress) ? 0x40 : 0); +} void TransportLayer::loop() { diff --git a/src/knx/transport_layer.h b/src/knx/transport_layer.h index 00b11a9..dccea14 100644 --- a/src/knx/transport_layer.h +++ b/src/knx/transport_layer.h @@ -24,8 +24,10 @@ public: 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); void dataGroupConfirm(AckType ack, uint16_t source, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu, bool status); - void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu, SystemBroadcast broadcastType); - void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu, bool status, SystemBroadcast broadcastType); + void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu); + 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); #pragma endregion #pragma region from application layer @@ -46,13 +48,16 @@ public: * @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, SystemBroadcast broadcastType); + void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); + void dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu); void dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu); void connectRequest(uint16_t destination, Priority priority); void disconnectRequest(uint16_t tsap, Priority priority); // apdu must be valid until it was confirmed void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu); + + uint8_t getTPCI(uint16_t tsap); #pragma endregion #pragma region other