mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	save work
This commit is contained in:
		
							parent
							
								
									604c1d6bdb
								
							
						
					
					
						commit
						3290634215
					
				@ -29,9 +29,7 @@ class ApplicationLayer
 | 
			
		||||
    void transportLayer(TransportLayer& layer);
 | 
			
		||||
 | 
			
		||||
    // from transport layer
 | 
			
		||||
    // Note: a derived class(e.g. SecureApplicationLayer) just hides the implementation of these entry points from the transport layer
 | 
			
		||||
    //       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
 | 
			
		||||
    // Note: without data secure feature, the application layer is just used with SecurtyControl.dataSecurity = none
 | 
			
		||||
#pragma region Transport - Layer - Callbacks
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.
 | 
			
		||||
     */
 | 
			
		||||
    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. 
 | 
			
		||||
     * 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.
 | 
			
		||||
     */
 | 
			
		||||
    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);}
 | 
			
		||||
    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);}
 | 
			
		||||
    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);}
 | 
			
		||||
    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);}
 | 
			
		||||
    void dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) {dataConnectedIndication(priority, tsap, apdu, noSecurity);}
 | 
			
		||||
    void dataConnectedConfirm(uint16_t tsap) {dataConnectedConfirm(tsap, noSecurity);}
 | 
			
		||||
    virtual void dataBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataBroadcastIndication(hopType, priority, source, apdu, noSecurity);}
 | 
			
		||||
    virtual void dataBroadcastConfirm(AckType ack, HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataBroadcastConfirm(ack, hopType, priority, apdu, noSecurity, status);}
 | 
			
		||||
    virtual void dataSystemBroadcastIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataSystemBroadcastIndication(hopType, priority, source, apdu, noSecurity);}
 | 
			
		||||
    virtual void dataSystemBroadcastConfirm(HopCountType hopType, Priority priority, APDU& apdu, bool status) {dataSystemBroadcastConfirm(hopType, priority, apdu, noSecurity, status);}
 | 
			
		||||
    virtual void dataIndividualIndication(HopCountType hopType, Priority priority, uint16_t source, APDU& apdu) {dataIndividualIndication(hopType, priority, source, apdu, noSecurity);}
 | 
			
		||||
    virtual 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 dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) {dataConnectedIndication(priority, tsap, apdu, noSecurity);}
 | 
			
		||||
    virtual void dataConnectedConfirm(uint16_t tsap) {dataConnectedConfirm(tsap, noSecurity);}
 | 
			
		||||
    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);
 | 
			
		||||
#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
 | 
			
		||||
    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);
 | 
			
		||||
@ -160,6 +143,22 @@ class ApplicationLayer
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
@ -153,15 +153,6 @@ void Bau27B0::domainAddressSerialNumberReadIndication(Priority priority, HopCoun
 | 
			
		||||
        _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)
 | 
			
		||||
{
 | 
			
		||||
    // If the received serial number matches our serial number
 | 
			
		||||
 | 
			
		||||
@ -31,8 +31,6 @@ class Bau27B0 : public BauSystemB
 | 
			
		||||
    void domainAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA,
 | 
			
		||||
                                                  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 domainAddressSerialNumberWriteLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, const uint8_t* rfDoA,
 | 
			
		||||
                                                    const uint8_t* knxSerialNumber, bool status) override;
 | 
			
		||||
 | 
			
		||||
@ -342,6 +342,26 @@ void BauSystemB::individualAddressWriteIndication(HopCountType hopType, const Se
 | 
			
		||||
        _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)
 | 
			
		||||
{
 | 
			
		||||
    GroupObject& go = _groupObjTable.get(asap);
 | 
			
		||||
 | 
			
		||||
@ -65,6 +65,9 @@ class BauSystemB : protected BusAccessUnit
 | 
			
		||||
                                         uint8_t propertyId, uint8_t* data, uint8_t length);
 | 
			
		||||
    void individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl) 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,
 | 
			
		||||
                                     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;
 | 
			
		||||
 | 
			
		||||
@ -66,6 +66,12 @@ void SecureApplicationLayer::dataGroupConfirm(AckType ack, HopCountType hopType,
 | 
			
		||||
 | 
			
		||||
    if (apdu.type() == SecureService)
 | 
			
		||||
    {
 | 
			
		||||
        // We do not care about confirmations of our sync communication
 | 
			
		||||
        if (isSyncService(apdu))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Will be filled in by decodeSecureApdu()
 | 
			
		||||
        SecurityControl secCtrl;
 | 
			
		||||
 | 
			
		||||
@ -116,6 +122,12 @@ void SecureApplicationLayer::dataBroadcastConfirm(AckType ack, HopCountType hopT
 | 
			
		||||
 | 
			
		||||
    if (apdu.type() == SecureService)
 | 
			
		||||
    {
 | 
			
		||||
        // We do not care about confirmations of our sync communication
 | 
			
		||||
        if (isSyncService(apdu))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Will be filled in by decodeSecureApdu()
 | 
			
		||||
        SecurityControl secCtrl;
 | 
			
		||||
 | 
			
		||||
@ -165,6 +177,12 @@ void SecureApplicationLayer::dataSystemBroadcastConfirm(HopCountType hopType, Pr
 | 
			
		||||
 | 
			
		||||
    if (apdu.type() == SecureService)
 | 
			
		||||
    {
 | 
			
		||||
        // We do not care about confirmations of our sync communication
 | 
			
		||||
        if (isSyncService(apdu))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Will be filled in by decodeSecureApdu()
 | 
			
		||||
        SecurityControl secCtrl;
 | 
			
		||||
 | 
			
		||||
@ -215,6 +233,12 @@ void SecureApplicationLayer::dataIndividualConfirm(AckType ack, HopCountType hop
 | 
			
		||||
 | 
			
		||||
    if (apdu.type() == SecureService)
 | 
			
		||||
    {
 | 
			
		||||
        // We do not care about confirmations of our sync communication
 | 
			
		||||
        if (isSyncService(apdu))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Will be filled in by decodeSecureApdu()
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    println("dataGroupRequest");
 | 
			
		||||
 | 
			
		||||
    if (secCtrl.dataSecurity != DataSecurity::none)
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    println("dataBroadcastRequest");
 | 
			
		||||
 | 
			
		||||
    if (secCtrl.dataSecurity != DataSecurity::none)
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    println("dataSystemBroadcastRequest");
 | 
			
		||||
 | 
			
		||||
    if (secCtrl.dataSecurity != DataSecurity::none)
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    println("dataIndividualRequest");
 | 
			
		||||
 | 
			
		||||
    if (secCtrl.dataSecurity != DataSecurity::none)
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
{
 | 
			
		||||
    println("dataConnectedRequest");
 | 
			
		||||
 | 
			
		||||
    if (secCtrl.dataSecurity != DataSecurity::none)
 | 
			
		||||
    {
 | 
			
		||||
        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;
 | 
			
		||||
    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: ");
 | 
			
		||||
    println(tpci, HEX);
 | 
			
		||||
@ -655,6 +692,10 @@ void SecureApplicationLayer::sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGro
 | 
			
		||||
        Addr toAddr = _syncReqBroadcastOutgoing ? (Addr)GrpAddr(0) : (Addr)IndAddr(dstAddr);
 | 
			
		||||
        _pendingOutgoingSyncRequests.insertOrAssign(toAddr, challenge);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        println("SyncRequest: failure during encryption");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    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: ");
 | 
			
		||||
    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)
 | 
			
		||||
{
 | 
			
		||||
    println("Received SyncRequest:");
 | 
			
		||||
 | 
			
		||||
    uint64_t nextRemoteSeqNum = sixBytesToUInt64(seqNum);
 | 
			
		||||
    uint64_t nextSeqNum = 1 + lastValidSequenceNumber(secCtrl.toolAccess, srcAddr);
 | 
			
		||||
 | 
			
		||||
@ -720,19 +770,20 @@ void SecureApplicationLayer::receivedSyncRequest(uint16_t srcAddr, uint16_t dstA
 | 
			
		||||
        nextSeqNum = nextRemoteSeqNum;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Remember challenge for securing the sync.res later
 | 
			
		||||
    _pendingIncomingSyncRequests.insertOrAssign(IndAddr(srcAddr), challenge);
 | 
			
		||||
 | 
			
		||||
    _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;
 | 
			
		||||
    bool toIsGroupAddress = _syncReqBroadcastIncoming;
 | 
			
		||||
 | 
			
		||||
    sendSyncResponse(toAddr, toIsGroupAddress, secCtrl, nextSeqNum);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SecureApplicationLayer::receivedSyncResponse(uint16_t remote, const SecurityControl &secCtrl, uint8_t* plainApdu)
 | 
			
		||||
{
 | 
			
		||||
    println("Received SyncResponse:");
 | 
			
		||||
 | 
			
		||||
    if (_syncReqBroadcastOutgoing)
 | 
			
		||||
    {
 | 
			
		||||
        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();
 | 
			
		||||
        sixBytesFromUInt64(randomNumber, seq);
 | 
			
		||||
 | 
			
		||||
        Addr remote = _syncReqBroadcastIncoming ? (Addr)GrpAddr(0) : (Addr)IndAddr(dstAddr);
 | 
			
		||||
 | 
			
		||||
        // Get challenge from sync.req
 | 
			
		||||
        uint64_t *challenge = _pendingIncomingSyncRequests.get(IndAddr(dstAddr));
 | 
			
		||||
        uint64_t *challenge = _pendingIncomingSyncRequests.get(remote);
 | 
			
		||||
        if (challenge == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            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
 | 
			
		||||
        {
 | 
			
		||||
            _pendingIncomingSyncRequests.erase(IndAddr(dstAddr));
 | 
			
		||||
            _pendingIncomingSyncRequests.erase(remote);
 | 
			
		||||
        }
 | 
			
		||||
        uint8_t challengeSixBytes[6];
 | 
			
		||||
        sixBytesFromUInt64(*challenge, challengeSixBytes);
 | 
			
		||||
@ -1161,7 +1214,11 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
 | 
			
		||||
    uint16_t srcAddress = plainApdu.frame().sourceAddress();
 | 
			
		||||
    uint16_t dstAddress = plainApdu.frame().destinationAddress();
 | 
			
		||||
    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: ");
 | 
			
		||||
    println(tpci, HEX);
 | 
			
		||||
    // Note:
 | 
			
		||||
@ -1179,7 +1236,7 @@ bool SecureApplicationLayer::createSecureApdu(APDU& plainApdu, APDU& secureApdu,
 | 
			
		||||
        updateSequenceNumber(secCtrl.toolAccess, nextSequenceNumber(secCtrl.toolAccess) + 1);
 | 
			
		||||
 | 
			
		||||
        println("createSecureApdu: Secure APDU: ");
 | 
			
		||||
        plainApdu.frame().apdu().printPDU();
 | 
			
		||||
        secureApdu.frame().apdu().printPDU();
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@ -1225,3 +1282,16 @@ void SecureApplicationLayer::loop()
 | 
			
		||||
    // TODO: handle timeout of outgoing sync requests
 | 
			
		||||
    //_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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -35,17 +35,17 @@ class SecureApplicationLayer :  public ApplicationLayer
 | 
			
		||||
    uint8_t getFromFailureLogByIndex(uint8_t index, uint8_t* data, uint8_t maxDataLen);
 | 
			
		||||
 | 
			
		||||
    // 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 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 dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu) override;
 | 
			
		||||
    virtual void dataConnectedConfirm(uint16_t tsap) override;
 | 
			
		||||
 | 
			
		||||
    void loop();
 | 
			
		||||
 | 
			
		||||
@ -247,6 +247,8 @@ class SecureApplicationLayer :  public ApplicationLayer
 | 
			
		||||
 | 
			
		||||
    uint64_t getRandomNumber();
 | 
			
		||||
 | 
			
		||||
    bool isSyncService(APDU& secureAsdu);
 | 
			
		||||
 | 
			
		||||
    void sendSyncRequest(uint16_t dstAddr, bool dstAddrIsGroupAddr, const SecurityControl &secCtrl);
 | 
			
		||||
    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);
 | 
			
		||||
@ -267,9 +269,8 @@ class SecureApplicationLayer :  public ApplicationLayer
 | 
			
		||||
    bool _syncReqBroadcastOutgoing{false};
 | 
			
		||||
    uint32_t _lastSyncRes;
 | 
			
		||||
 | 
			
		||||
    Map<Addr, SecurityControl, 1> _pendingDataRequests;
 | 
			
		||||
    Map<Addr, uint64_t, 1> _pendingOutgoingSyncRequests;
 | 
			
		||||
    Map<Addr, uint64_t, 1> _pendingIncomingSyncRequests;
 | 
			
		||||
    Map<Addr, uint64_t, 1> _pendingOutgoingSyncRequests; // Store challenges for outgoing sync requests
 | 
			
		||||
    Map<Addr, uint64_t, 1> _pendingIncomingSyncRequests; // Store challenges for incoming sync requests
 | 
			
		||||
 | 
			
		||||
    SecurityInterfaceObject& _secIfObj;
 | 
			
		||||
    DeviceObject& _deviceObj;
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
    // together with the TPDU type.
 | 
			
		||||
    return ((_seqNoSend & 0xF) << 2) | ((dstAddr == _connectionAddress) ? 0x40 : 0);
 | 
			
		||||
    return ((_seqNoSend & 0xF) << 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TransportLayer::loop()
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,7 @@ public:
 | 
			
		||||
    // apdu must be valid until it was confirmed
 | 
			
		||||
    void dataConnectedRequest(uint16_t tsap, Priority priority, APDU& apdu);
 | 
			
		||||
 | 
			
		||||
    uint8_t getTPCI(uint16_t dstAddr);
 | 
			
		||||
    uint8_t getTpciSeqNum();
 | 
			
		||||
#pragma endregion
 | 
			
		||||
 | 
			
		||||
#pragma region other
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user