save work

This commit is contained in:
Nanosonde 2020-06-27 22:22:37 +02:00
parent 604c1d6bdb
commit 3290634215
9 changed files with 148 additions and 66 deletions

View File

@ -29,9 +29,7 @@ class ApplicationLayer
void transportLayer(TransportLayer& layer); void transportLayer(TransportLayer& layer);
// from transport layer // from transport layer
// Note: a derived class(e.g. SecureApplicationLayer) just hides the implementation of these entry points from the transport layer // Note: without data secure feature, the application layer is just used with SecurtyControl.dataSecurity = none
// So hiding is enough here, we do not need virtual member methods here.
// Without data secure feature, the application layer is just used with SecurtyControl.dataSecurity = none
#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. * Somebody send us an APDU via multicast communiation. See 3.2 of @cite knx:3/3/4.
@ -47,7 +45,7 @@ class ApplicationLayer
* *
* @param hopType Should routing be endless or should the NetworkLayer::hopCount be used? See also ::HopCountType. * @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) {dataGroupIndication(hopType, priority, tsap, apdu, noSecurity);} virtual void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) {dataGroupIndication(hopType, priority, tsap, apdu, noSecurity);}
/** /**
* Report the status of an APDU that we sent via multicast communiation back to us. See 3.2 of @cite knx:3/3/4. * 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 * See also ApplicationLayer::dataGroupConfirm and TransportLayer::dataGroupRequest. This method is called by
@ -66,37 +64,22 @@ class ApplicationLayer
* *
* @param ack Did we want a DataLinkLayer acknowledgement? See ::AckType. * @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) {dataGroupConfirm(ack, hopType, priority, tsap, apdu, noSecurity, status);} APDU& apdu, bool status) {dataGroupConfirm(ack, hopType, priority, tsap, apdu, noSecurity, status);}
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataBroadcastIndication(hopType, priority, source, apdu, noSecurity);} virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataBroadcastIndication(hopType, priority, source, apdu, noSecurity);}
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataBroadcastConfirm(ack, hopType, priority, apdu, noSecurity, status);} virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataBroadcastConfirm(ack, hopType, priority, apdu, noSecurity, status);}
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataSystemBroadcastIndication(hopType, priority, source, apdu, noSecurity);} virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataSystemBroadcastIndication(hopType, priority, source, apdu, noSecurity);}
void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataSystemBroadcastConfirm(hopType, priority, apdu, noSecurity, status);} virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataSystemBroadcastConfirm(hopType, priority, apdu, noSecurity, status);}
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataIndividualIndication(hopType, priority, source, apdu, noSecurity);} virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataIndividualIndication(hopType, priority, source, apdu, noSecurity);}
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) {dataIndividualConfirm(ack, hopType, priority, tsap, apdu, noSecurity, status);} virtual void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) {dataIndividualConfirm(ack, hopType, priority, tsap, apdu, noSecurity, status);}
void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) {dataConnectedIndication(priority, tsap, apdu, noSecurity);} virtual void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) {dataConnectedIndication(priority, tsap, apdu, noSecurity);}
void dataConnectedConfirm(uint16_t tsap) {dataConnectedConfirm(tsap, noSecurity);} virtual void dataConnectedConfirm(uint16_t tsap) {dataConnectedConfirm(tsap, noSecurity);}
void connectIndication(uint16_t tsap); void connectIndication(uint16_t tsap);
void connectConfirm(uint16_t destination, uint16_t tsap, bool status); void connectConfirm(uint16_t destination, uint16_t tsap, bool status);
void disconnectIndication(uint16_t tsap); void disconnectIndication(uint16_t tsap);
void disconnectConfirm(Priority priority, uint16_t tsap, bool status); void disconnectConfirm(Priority priority, uint16_t tsap, bool status);
#pragma endregion #pragma endregion
// hooks that can be implemented by derived class (e.g. SecureApplicationLayer)
#pragma region hooks
void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl &secCtrl);
void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap,
APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl);
void dataConnectedConfirm(uint16_t tsap, const SecurityControl& secCtrl);
#pragma endregion
#pragma region from bau #pragma region from bau
void groupValueReadRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl); void groupValueReadRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl);
void groupValueReadResponse(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl& secCtrl, uint8_t* data, uint8_t dataLength); void groupValueReadResponse(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl& secCtrl, uint8_t* data, uint8_t dataLength);
@ -160,6 +143,22 @@ class ApplicationLayer
#pragma endregion #pragma endregion
protected: protected:
// hooks that can be implemented by derived class (e.g. SecureApplicationLayer)
#pragma region hooks
void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl &secCtrl);
void dataGroupConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap,
APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu, const SecurityControl& secCtrl);
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl, bool status);
void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl);
void dataConnectedConfirm(uint16_t tsap, const SecurityControl& secCtrl);
#pragma endregion
// to transport layer // to transport layer
virtual void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl &secCtrl); virtual void dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl &secCtrl);
virtual void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl); virtual void dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl);

View File

@ -153,15 +153,6 @@ void Bau27B0::domainAddressSerialNumberReadIndication(Priority priority, HopCoun
_appLayer.domainAddressSerialNumberReadResponse(priority, hopType, secCtrl, _rfMediumObj.rfDomainAddress(), knxSerialNumber); _appLayer.domainAddressSerialNumberReadResponse(priority, hopType, secCtrl, _rfMediumObj.rfDomainAddress(), knxSerialNumber);
} }
void Bau27B0::individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress,
uint8_t* knxSerialNumber)
{
// If the received serial number matches our serial number
// then store the received new individual address in the device object
if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6))
_deviceObj.induvidualAddress(newIndividualAddress);
}
void Bau27B0::individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) void Bau27B0::individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber)
{ {
// If the received serial number matches our serial number // If the received serial number matches our serial number

View File

@ -31,8 +31,6 @@ class Bau27B0 : public BauSystemB
void domainAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA, void domainAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA,
const uint8_t* knxSerialNumber) override; const uint8_t* knxSerialNumber) override;
void domainAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* knxSerialNumber) override; void domainAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* knxSerialNumber) override;
void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress,
uint8_t* knxSerialNumber) override;
void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) override; void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) override;
void domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA, void domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA,
const uint8_t* knxSerialNumber, bool status) override; const uint8_t* knxSerialNumber, bool status) override;

View File

@ -342,6 +342,26 @@ void BauSystemB::individualAddressWriteIndication(HopCountType hopType, const Se
_deviceObj.induvidualAddress(newaddress); _deviceObj.induvidualAddress(newaddress);
} }
void BauSystemB::individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress,
uint8_t* knxSerialNumber)
{
// If the received serial number matches our serial number
// then store the received new individual address in the device object
if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6))
_deviceObj.induvidualAddress(newIndividualAddress);
}
void BauSystemB::individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber)
{
// If the received serial number matches our serial number
// then send a response with the current RF domain address stored in the RF medium object and the serial number
if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6))
{
uint8_t emptyDomainAddress[6] = {0x00};
_appLayer.IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber);
}
}
void BauSystemB::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status) void BauSystemB::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status)
{ {
GroupObject& go = _groupObjTable.get(asap); GroupObject& go = _groupObjTable.get(asap);

View File

@ -65,6 +65,9 @@ class BauSystemB : protected BusAccessUnit
uint8_t propertyId, uint8_t* data, uint8_t length); uint8_t propertyId, uint8_t* data, uint8_t length);
void individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) override; void individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) override;
void individualAddressWriteIndication(HopCountType hopType, const SecurityControl &secCtrl, uint16_t newaddress) override; void individualAddressWriteIndication(HopCountType hopType, const SecurityControl &secCtrl, uint16_t newaddress) override;
void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress,
uint8_t* knxSerialNumber) override;
void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) override;
void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
uint8_t* data, uint8_t dataLength, bool status) override; uint8_t* data, uint8_t dataLength, bool status) override;
void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override; void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override;

View File

@ -66,6 +66,12 @@ void SecureApplicationLayer::dataGroupConfirm(AckType ack, HopCountType hopType,
if (apdu.type() == SecureService) if (apdu.type() == SecureService)
{ {
// We do not care about confirmations of our sync communication
if (isSyncService(apdu))
{
return;
}
// Will be filled in by decodeSecureApdu() // Will be filled in by decodeSecureApdu()
SecurityControl secCtrl; SecurityControl secCtrl;
@ -116,6 +122,12 @@ void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopT
if (apdu.type() == SecureService) if (apdu.type() == SecureService)
{ {
// We do not care about confirmations of our sync communication
if (isSyncService(apdu))
{
return;
}
// Will be filled in by decodeSecureApdu() // Will be filled in by decodeSecureApdu()
SecurityControl secCtrl; SecurityControl secCtrl;
@ -165,6 +177,12 @@ void SecureApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Pr
if (apdu.type() == SecureService) if (apdu.type() == SecureService)
{ {
// We do not care about confirmations of our sync communication
if (isSyncService(apdu))
{
return;
}
// Will be filled in by decodeSecureApdu() // Will be filled in by decodeSecureApdu()
SecurityControl secCtrl; SecurityControl secCtrl;
@ -215,6 +233,12 @@ void SecureApplicationLayer::dataIndividualConfirm(AckType ack, HopCountType hop
if (apdu.type() == SecureService) if (apdu.type() == SecureService)
{ {
// We do not care about confirmations of our sync communication
if (isSyncService(apdu))
{
return;
}
// Will be filled in by decodeSecureApdu() // Will be filled in by decodeSecureApdu()
SecurityControl secCtrl; SecurityControl secCtrl;
@ -271,6 +295,8 @@ void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap)
void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl) void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl)
{ {
println("dataGroupRequest");
if (secCtrl.dataSecurity != DataSecurity::none) if (secCtrl.dataSecurity != DataSecurity::none)
{ {
uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4 uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
@ -288,6 +314,8 @@ void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType,
void SecureApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl) void SecureApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl)
{ {
println("dataBroadcastRequest");
if (secCtrl.dataSecurity != DataSecurity::none) if (secCtrl.dataSecurity != DataSecurity::none)
{ {
uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4 uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
@ -305,6 +333,8 @@ void SecureApplicationLayer::dataBroadcastRequest(AckType ack, HopCountType hopT
void SecureApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl) void SecureApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, const SecurityControl& secCtrl)
{ {
println("dataSystemBroadcastRequest");
if (secCtrl.dataSecurity != DataSecurity::none) if (secCtrl.dataSecurity != DataSecurity::none)
{ {
uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4 uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
@ -322,6 +352,8 @@ void SecureApplicationLayer::dataSystemBroadcastRequest(AckType ack, HopCountTyp
void SecureApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu, const SecurityControl& secCtrl) void SecureApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t destination, APDU& apdu, const SecurityControl& secCtrl)
{ {
println("dataIndividualRequest");
if (secCtrl.dataSecurity != DataSecurity::none) if (secCtrl.dataSecurity != DataSecurity::none)
{ {
uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4 uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
@ -339,6 +371,8 @@ void SecureApplicationLayer::dataIndividualRequest(AckType ack, HopCountType hop
void SecureApplicationLayer::dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu, const SecurityControl &secCtrl) void SecureApplicationLayer::dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu, const SecurityControl &secCtrl)
{ {
println("dataConnectedRequest");
if (secCtrl.dataSecurity != DataSecurity::none) if (secCtrl.dataSecurity != DataSecurity::none)
{ {
uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4 uint16_t secureApduLength = apdu.length() + 2 + 6 + 4; // 2(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
@ -624,7 +658,10 @@ void SecureApplicationLayer::sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGro
uint8_t tpci = 0; uint8_t tpci = 0;
if (!_syncReqBroadcastOutgoing) if (!_syncReqBroadcastOutgoing)
{ {
tpci = _transportLayer->getTPCI(dstAddr); // get next TPCI sequence number for MAC calculation from TL if (isConnected())
{
tpci |= 0x40 | _transportLayer->getTpciSeqNum(); // get next TPCI sequence number for MAC calculation from TL (T_DATA_CONNECTED)
}
} }
print("sendSyncRequest: TPCI: "); print("sendSyncRequest: TPCI: ");
println(tpci, HEX); println(tpci, HEX);
@ -655,6 +692,10 @@ void SecureApplicationLayer::sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGro
Addr toAddr = _syncReqBroadcastOutgoing ? (Addr)GrpAddr(0) : (Addr)IndAddr(dstAddr); Addr toAddr = _syncReqBroadcastOutgoing ? (Addr)GrpAddr(0) : (Addr)IndAddr(dstAddr);
_pendingOutgoingSyncRequests.insertOrAssign(toAddr, challenge); _pendingOutgoingSyncRequests.insertOrAssign(toAddr, challenge);
} }
else
{
println("SyncRequest: failure during encryption");
}
} }
void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint64_t remoteNextSeqNum) void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint64_t remoteNextSeqNum)
@ -677,7 +718,10 @@ void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGr
uint8_t tpci = 0; uint8_t tpci = 0;
if (!_syncReqBroadcastIncoming) if (!_syncReqBroadcastIncoming)
{ {
tpci = _transportLayer->getTPCI(dstAddr); // get next TPCI sequence number for MAC calculation from TL if (isConnected())
{
tpci |= 0x40 | _transportLayer->getTpciSeqNum(); // get next TPCI sequence number for MAC calculation from TL (T_DATA_CONNECTED)
}
} }
print("sendSyncResponse: TPCI: "); print("sendSyncResponse: TPCI: ");
println(tpci, HEX); println(tpci, HEX);
@ -707,10 +751,16 @@ void SecureApplicationLayer::sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGr
} }
} }
} }
else
{
println("SyncResponse: failure during encryption");
}
} }
void SecureApplicationLayer::receivedSyncRequest(uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint8_t* seqNum, uint64_t challenge) void SecureApplicationLayer::receivedSyncRequest(uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint8_t* seqNum, uint64_t challenge)
{ {
println("Received SyncRequest:");
uint64_t nextRemoteSeqNum = sixBytesToUInt64(seqNum); uint64_t nextRemoteSeqNum = sixBytesToUInt64(seqNum);
uint64_t nextSeqNum = 1 + lastValidSequenceNumber(secCtrl.toolAccess, srcAddr); uint64_t nextSeqNum = 1 + lastValidSequenceNumber(secCtrl.toolAccess, srcAddr);
@ -720,19 +770,20 @@ void SecureApplicationLayer::receivedSyncRequest(uint16_t srcAddr, uint16_t dstA
nextSeqNum = nextRemoteSeqNum; nextSeqNum = nextRemoteSeqNum;
} }
// Remember challenge for securing the sync.res later
_pendingIncomingSyncRequests.insertOrAssign(IndAddr(srcAddr), challenge);
_syncReqBroadcastIncoming = (dstAddr == 0x0000) && dstAddrIsGroupAddr; _syncReqBroadcastIncoming = (dstAddr == 0x0000) && dstAddrIsGroupAddr;
// Remember challenge for securing the sync.res later
_pendingIncomingSyncRequests.insertOrAssign(_syncReqBroadcastIncoming ? (Addr) GrpAddr(0) : (Addr) IndAddr(srcAddr), challenge);
uint16_t toAddr = _syncReqBroadcastIncoming ? dstAddr : srcAddr; uint16_t toAddr = _syncReqBroadcastIncoming ? dstAddr : srcAddr;
bool toIsGroupAddress = _syncReqBroadcastIncoming; bool toIsGroupAddress = _syncReqBroadcastIncoming;
sendSyncResponse(toAddr, toIsGroupAddress, secCtrl, nextSeqNum); sendSyncResponse(toAddr, toIsGroupAddress, secCtrl, nextSeqNum);
} }
void SecureApplicationLayer::receivedSyncResponse(uint16_t remote, const SecurityControl &secCtrl, uint8_t* plainApdu) void SecureApplicationLayer::receivedSyncResponse(uint16_t remote, const SecurityControl &secCtrl, uint8_t* plainApdu)
{ {
println("Received SyncResponse:");
if (_syncReqBroadcastOutgoing) if (_syncReqBroadcastOutgoing)
{ {
if (_pendingOutgoingSyncRequests.get(GrpAddr(0)) == nullptr) if (_pendingOutgoingSyncRequests.get(GrpAddr(0)) == nullptr)
@ -1086,8 +1137,10 @@ bool SecureApplicationLayer::secure(uint8_t* buffer, uint16_t service, uint16_t
uint64_t randomNumber = getRandomNumber(); uint64_t randomNumber = getRandomNumber();
sixBytesFromUInt64(randomNumber, seq); sixBytesFromUInt64(randomNumber, seq);
Addr remote = _syncReqBroadcastIncoming ? (Addr)GrpAddr(0) : (Addr)IndAddr(dstAddr);
// Get challenge from sync.req // Get challenge from sync.req
uint64_t *challenge = _pendingIncomingSyncRequests.get(IndAddr(dstAddr)); uint64_t *challenge = _pendingIncomingSyncRequests.get(remote);
if (challenge == nullptr) if (challenge == nullptr)
{ {
println("Cannot send sync.res without corresponding sync.req"); println("Cannot send sync.res without corresponding sync.req");
@ -1095,7 +1148,7 @@ bool SecureApplicationLayer::secure(uint8_t* buffer, uint16_t service, uint16_t
} }
else else
{ {
_pendingIncomingSyncRequests.erase(IndAddr(dstAddr)); _pendingIncomingSyncRequests.erase(remote);
} }
uint8_t challengeSixBytes[6]; uint8_t challengeSixBytes[6];
sixBytesFromUInt64(*challenge, challengeSixBytes); sixBytesFromUInt64(*challenge, challengeSixBytes);
@ -1161,7 +1214,11 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
uint16_t srcAddress = plainApdu.frame().sourceAddress(); uint16_t srcAddress = plainApdu.frame().sourceAddress();
uint16_t dstAddress = plainApdu.frame().destinationAddress(); uint16_t dstAddress = plainApdu.frame().destinationAddress();
bool isDstAddrGroupAddr = plainApdu.frame().addressType() == GroupAddress; bool isDstAddrGroupAddr = plainApdu.frame().addressType() == GroupAddress;
uint8_t tpci = _transportLayer->getTPCI(dstAddress); // get next TPCI sequence number for MAC calculation from TL uint8_t tpci = 0x00;
if (isConnected())
{
tpci |= 0x40 | _transportLayer->getTpciSeqNum(); // get next TPCI sequence number for MAC calculation from TL (T_DATA_CONNECTED)
}
print("createSecureApdu: TPCI: "); print("createSecureApdu: TPCI: ");
println(tpci, HEX); println(tpci, HEX);
// Note: // Note:
@ -1179,7 +1236,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1); updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1);
println("createSecureApdu: Secure APDU: "); println("createSecureApdu: Secure APDU: ");
plainApdu.frame().apdu().printPDU(); secureApdu.frame().apdu().printPDU();
return true; return true;
} }
@ -1225,3 +1282,16 @@ void SecureApplicationLayer::loop()
// TODO: handle timeout of outgoing sync requests // TODO: handle timeout of outgoing sync requests
//_pendingOutgoingSyncRequests //_pendingOutgoingSyncRequests
} }
bool SecureApplicationLayer::isSyncService(APDU& secureApdu)
{
uint8_t scf = *(secureApdu.data()+1);
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
if ((service == SecureSyncRequest) || (service == SecureSyncResponse))
{
return true;
}
return false;
}

View File

@ -35,17 +35,17 @@ class SecureApplicationLayer : public ApplicationLayer
uint8_t getFromFailureLogByIndex(uint8_t index, uint8_t* data, uint8_t maxDataLen); uint8_t getFromFailureLogByIndex(uint8_t index, uint8_t* data, uint8_t maxDataLen);
// from transport layer // from transport layer
void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu); virtual void dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu) override;
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); APDU& apdu, bool status) override;
void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status); virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) override;
void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status); virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) override;
void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu); virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) override;
void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status); virtual void dataIndividualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, bool status) override;
void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu); virtual void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) override;
void dataConnectedConfirm(uint16_t tsap); virtual void dataConnectedConfirm(uint16_t tsap) override;
void loop(); void loop();
@ -247,6 +247,8 @@ class SecureApplicationLayer : public ApplicationLayer
uint64_t getRandomNumber(); uint64_t getRandomNumber();
bool isSyncService(APDU& secureAsdu);
void sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl); void sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl);
void sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint64_t remoteNextSeqNum); void sendSyncResponse(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint64_t remoteNextSeqNum);
void receivedSyncRequest(uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint8_t* seq, uint64_t challenge); void receivedSyncRequest(uint16_t srcAddr, uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl, uint8_t* seq, uint64_t challenge);
@ -267,9 +269,8 @@ class SecureApplicationLayer : public ApplicationLayer
bool _syncReqBroadcastOutgoing{false}; bool _syncReqBroadcastOutgoing{false};
uint32_t _lastSyncRes; uint32_t _lastSyncRes;
Map<Addr, SecurityControl, 1> _pendingDataRequests; Map<Addr, uint64_t, 1> _pendingOutgoingSyncRequests; // Store challenges for outgoing sync requests
Map<Addr, uint64_t, 1> _pendingOutgoingSyncRequests; Map<Addr, uint64_t, 1> _pendingIncomingSyncRequests; // Store challenges for incoming sync requests
Map<Addr, uint64_t, 1> _pendingIncomingSyncRequests;
SecurityInterfaceObject& _secIfObj; SecurityInterfaceObject& _secIfObj;
DeviceObject& _deviceObj; DeviceObject& _deviceObj;

View File

@ -530,11 +530,11 @@ void TransportLayer::ackTimeoutIndication()
} }
} }
uint8_t TransportLayer::getTPCI(uint16_t dstAddr) uint8_t TransportLayer::getTpciSeqNum()
{ {
// Return seqNum that would be used for sending next frame // Return seqNum that would be used for sending next frame
// together with the TPDU type. // together with the TPDU type.
return ((_seqNoSend & 0xF) << 2) | ((dstAddr == _connectionAddress) ? 0x40 : 0); return ((_seqNoSend & 0xF) << 2);
} }
void TransportLayer::loop() void TransportLayer::loop()

View File

@ -57,7 +57,7 @@ public:
// apdu must be valid until it was confirmed // apdu must be valid until it was confirmed
void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu); void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu);
uint8_t getTPCI(uint16_t dstAddr); uint8_t getTpciSeqNum();
#pragma endregion #pragma endregion
#pragma region other #pragma region other