diff --git a/src/knx/data_link_layer.cpp b/src/knx/data_link_layer.cpp index d2413dc8..8f51650c 100644 --- a/src/knx/data_link_layer.cpp +++ b/src/knx/data_link_layer.cpp @@ -48,6 +48,12 @@ void DataLinkLayer::dataIndicationToTunnel(CemiFrame& frame) { println("default dataIndicationToTunnel"); } + +bool DataLinkLayer::isTunnelAddress(uint16_t addr) +{ + println("default IsTunnelAddress"); + return false; +} #endif void DataLinkLayer::dataRequestFromTunnel(CemiFrame& frame) @@ -210,7 +216,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA #endif tmpFrame.confirm(ConfirmNoError); - if(frame.sourceAddress() == _deviceObject.individualAddress() && mediumType() == DptMedium::KNX_TP1) // quick fix only send to tunnel if we are the tpuart data link layer + if(frame.sourceAddress() == _deviceObject.individualAddress() && _networkLayerEntity.getEntityIndex() == 1) // only send to tunnel if we are the secondary interface _cemiServer->dataIndicationToTunnel(tmpFrame); #endif diff --git a/src/knx/data_link_layer.h b/src/knx/data_link_layer.h index 554c98ce..a1da31e9 100644 --- a/src/knx/data_link_layer.h +++ b/src/knx/data_link_layer.h @@ -36,6 +36,7 @@ class DataLinkLayer virtual void dataRequestToTunnel(CemiFrame& frame); virtual void dataConfirmationToTunnel(CemiFrame& frame); virtual void dataIndicationToTunnel(CemiFrame& frame); + virtual bool isTunnelAddress(uint16_t addr); #endif #endif diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp index cfdfadfe..6b64bd49 100644 --- a/src/knx/ip_data_link_layer.cpp +++ b/src/knx/ip_data_link_layer.cpp @@ -215,6 +215,18 @@ void IpDataLinkLayer::sendFrameToTunnel(KnxIpTunnelConnection *tunnel, CemiFrame _platform.sendBytesUniCast(tunnel->IpAddress, tunnel->PortData, req.data(), req.totalLength()); } + +bool IpDataLinkLayer::isTunnelAddress(uint16_t addr) +{ + if(addr == 0) + return false; // 0.0.0 is not a valid tunnel address and is used as default value + + for(int i = 0; i < KNX_TUNNELING; i++) + if(tunnels[i].IndividualAddress == addr) + return true; + + return false; +} #endif void IpDataLinkLayer::loop() diff --git a/src/knx/ip_data_link_layer.h b/src/knx/ip_data_link_layer.h index 20396615..efd465c2 100644 --- a/src/knx/ip_data_link_layer.h +++ b/src/knx/ip_data_link_layer.h @@ -24,6 +24,7 @@ class IpDataLinkLayer : public DataLinkLayer void dataRequestToTunnel(CemiFrame& frame) override; void dataConfirmationToTunnel(CemiFrame& frame) override; void dataIndicationToTunnel(CemiFrame& frame) override; + bool isTunnelAddress(uint16_t addr) override; #endif private: diff --git a/src/knx/network_layer_coupler.cpp b/src/knx/network_layer_coupler.cpp index 46eff4a6..edaa9cc4 100644 --- a/src/knx/network_layer_coupler.cpp +++ b/src/knx/network_layer_coupler.cpp @@ -1,4 +1,5 @@ #include "network_layer_coupler.h" +#include "data_link_layer.h" #include "device_object.h" #include "router_object.h" #include "tpdu.h" @@ -348,8 +349,9 @@ void NetworkLayerCoupler::routeDataIndividual(AckType ack, uint16_t destination, // if destination is not within our scope then send via primary interface, else via secondary interface uint8_t destIfidx = (Z != netaddr) ? kPrimaryIfIndex : kSecondaryIfIndex; #ifdef KNX_TUNNELING - if(isTunnelAddress(destination)) - destIfidx = kSecondaryIfIndex; + if(destIfidx == kPrimaryIfIndex) + if(isTunnelAddress(destination)) + destIfidx = kSecondaryIfIndex; #endif //print("NetworkLayerCoupler::routeDataIndividual local to s or p: "); //println(destIfidx); @@ -587,10 +589,6 @@ void NetworkLayerCoupler::dataSystemBroadcastRequest(AckType ack, HopCountType h bool NetworkLayerCoupler::isTunnelAddress(uint16_t destination) { - _netLayerEntities[kSecondaryIfIndex].dataLinkLayer().mediumType(); - // FIXME - if((destination / 0x100) == 0xFF) - return true; - - return false; + // tunnels are managed within the IpDataLinkLayer - kPrimaryIfIndex + return _netLayerEntities[kPrimaryIfIndex].dataLinkLayer().isTunnelAddress(destination); } \ No newline at end of file diff --git a/src/knx/network_layer_entity.cpp b/src/knx/network_layer_entity.cpp index 7a7b2152..389f765c 100644 --- a/src/knx/network_layer_entity.cpp +++ b/src/knx/network_layer_entity.cpp @@ -18,6 +18,11 @@ DataLinkLayer& NetworkLayerEntity::dataLinkLayer() return *_dataLinkLayer; } +NetworkLayer& NetworkLayerEntity::networkLayer() +{ + return _netLayer; +} + DptMedium NetworkLayerEntity::mediumType() const { return _dataLinkLayer->mediumType(); diff --git a/src/knx/network_layer_entity.h b/src/knx/network_layer_entity.h index b35c0829..22599e4e 100644 --- a/src/knx/network_layer_entity.h +++ b/src/knx/network_layer_entity.h @@ -17,6 +17,7 @@ class NetworkLayerEntity void dataLinkLayer(DataLinkLayer& layer); DataLinkLayer& dataLinkLayer(); + NetworkLayer& networkLayer(); DptMedium mediumType() const; uint8_t getEntityIndex(); diff --git a/src/knx/tpuart_data_link_layer.cpp b/src/knx/tpuart_data_link_layer.cpp index 9aeaf5e7..5ea43f99 100644 --- a/src/knx/tpuart_data_link_layer.cpp +++ b/src/knx/tpuart_data_link_layer.cpp @@ -702,6 +702,12 @@ void TpUartDataLinkLayer::addFrameTxQueue(CemiFrame& frame) } } +bool TpUartDataLinkLayer::isTunnelAddress(uint16_t addr) +{ + println("TpDataLinkLayer::isTunnelAddress"); + return false; +} + bool TpUartDataLinkLayer::isTxQueueEmpty() { if (_tx_queue.front == NULL) diff --git a/src/knx/tpuart_data_link_layer.h b/src/knx/tpuart_data_link_layer.h index 8070f4fc..7a0e9cad 100644 --- a/src/knx/tpuart_data_link_layer.h +++ b/src/knx/tpuart_data_link_layer.h @@ -31,7 +31,7 @@ class TpUartDataLinkLayer : public DataLinkLayer bool enabled() const; void setFrameRepetition(uint8_t nack, uint8_t busy); DptMedium mediumType() const override; - + bool isTunnelAddress(uint16_t addr) override; private: bool _enabled = false; uint8_t* _sendBuffer = 0;