Skip to content

Commit

Permalink
rp2040_ip_routing_fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Ing-Dom committed Feb 10, 2024
1 parent d368000 commit f50bb3a
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 13 deletions.
29 changes: 18 additions & 11 deletions src/knx/cemi_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
/*
cEMI Frame Format
+---------+--------+--------+--------+--------+---------+---------+--------+---------+
| Header | Msg |Add.Info| Ctrl 1 | Ctrl 2 | Source | Dest. | Data | APDU |
| | Code | Length | | | Address | Address | Length | |
+--------+--------+--------+--------+---------+---------+--------+---------+
| _data |
+--------+--------+--------+--------+---------+---------+--------+---------+
| LPDU |
+--------+--------+--------+--------+---------+---------+--------+---------+
| NPDU |
+---------+--------+--------+--------+--------+---------+---------+--------+---------+
6 bytes 1 byte 1 byte 1 byte 1 byte 2 bytes 2 bytes 1 byte 2 bytes
| Header | Msg |Add.Info| Ctrl 1 | Ctrl 2 | Source | Dest. | Data | TPDU |
| | Code | Length | | | Address | Address | Length | APDU |
+---------+--------+--------+--------+--------+---------+---------+--------+---------+
6 bytes 1 byte 1 byte 1 byte 1 byte 2 bytes 2 bytes 1 byte n bytes
Header = See below the structure of a cEMI header
Message Code = See below. On Appendix A is the list of all existing EMI and cEMI codes
Expand Down Expand Up @@ -85,11 +91,11 @@ CemiFrame::CemiFrame(uint8_t apduLength)
_apdu(_data + APDU_LPDU_DIFF, *this)
{
_ctrl1 = _data + CEMI_HEADER_SIZE;
_length = 0;

memset(_data, 0, apduLength + APDU_LPDU_DIFF);
_ctrl1[0] |= Broadcast;
_npdu.octetCount(apduLength);
_length = _npdu.length() + NPDU_LPDU_DIFF;
}

CemiFrame::CemiFrame(const CemiFrame & other)
Expand All @@ -116,6 +122,7 @@ CemiFrame& CemiFrame::operator=(CemiFrame other)
return *this;
}


MessageCode CemiFrame::messageCode() const
{
return (MessageCode)_data[0];
Expand All @@ -128,12 +135,7 @@ void CemiFrame::messageCode(MessageCode msgCode)

uint16_t CemiFrame::totalLenght() const
{
if(messageCode() != L_data_con && messageCode() != L_data_ind && messageCode() != L_data_req)
return _length; // we dont have an npu on any other messagecode

uint16_t tmp =
_npdu.length() + NPDU_LPDU_DIFF;
return tmp;
return _length;
}

uint16_t CemiFrame::telegramLengthtTP() const
Expand Down Expand Up @@ -375,8 +377,13 @@ bool CemiFrame::valid() const
{
print("length issue, length: ");
print(_length);
print(" addInfoLen: ");
print(addInfoLen);
print(" apduLen: ");
print(apduLen);
print(" expected length: ");
println(addInfoLen + apduLen + NPDU_LPDU_DIFF + 2);
printHex("Frame: ", _data, _length, true);

return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/knx/data_link_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA
#endif
tmpFrame.confirm(ConfirmNoError);

if(frame.sourceAddress() == _deviceObject.individualAddress())
if(frame.sourceAddress() == _deviceObject.individualAddress() && mediumType() == DptMedium::KNX_TP1) // quick fix only send to tunnel if we are the tpuart data link layer
_cemiServer->dataIndicationToTunnel(tmpFrame);
#endif

Expand Down
25 changes: 24 additions & 1 deletion src/knx/ip_data_link_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,30 @@ void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length)
}

bool hasDoublePA = false;
const uint8_t *addresses = _ipParameters.propertyData(PID_ADDITIONAL_INDIVIDUAL_ADDRESSES);

// read current elements in PID_ADDITIONAL_INDIVIDUAL_ADDRESSES
uint8_t count = 1;
uint16_t propval = 0;
_ipParameters.readProperty(PID_ADDITIONAL_INDIVIDUAL_ADDRESSES, 0, count, (uint8_t*)&propval);
const uint8_t *addresses;
if(propval == KNX_TUNNELING)
{
addresses = _ipParameters.propertyData(PID_ADDITIONAL_INDIVIDUAL_ADDRESSES);
}
else // no tunnel PA configured, that means device is unconfigured and has 15.15.0
{
uint8_t addrbuffer[KNX_TUNNELING*2];
addresses = (uint8_t*)addrbuffer;
for(int i = 0; i < KNX_TUNNELING; i++)
{
addrbuffer[i*2+1] = i+1;
addrbuffer[i*2] = _deviceObject.individualAddress() / 0x0100;
}
#ifdef KNX_LOG_TUNNELING
println("no Tunnel-PAs configured, using own subnet");
#endif
}

for(int i = 0; i < KNX_TUNNELING; i++)
{
uint16_t pa = 0;
Expand Down
14 changes: 14 additions & 0 deletions src/knx/network_layer_coupler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ 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;
#endif
//print("NetworkLayerCoupler::routeDataIndividual local to s or p: ");
//println(destIfidx);
_netLayerEntities[destIfidx].sendDataRequest(npdu, ack, destination, source, priority, AddressType::IndividualAddress, Broadcast);
Expand Down Expand Up @@ -580,3 +584,13 @@ void NetworkLayerCoupler::dataSystemBroadcastRequest(AckType ack, HopCountType h
println(broadcastType);
_netLayerEntities[kSecondaryIfIndex].sendDataRequest(tmpFrame.npdu(), ack, 0, _deviceObj.individualAddress(), priority, GroupAddress, broadcastType);
}

bool NetworkLayerCoupler::isTunnelAddress(uint16_t destination)
{
_netLayerEntities[kSecondaryIfIndex].dataLinkLayer().mediumType();
// FIXME
if((destination / 0x100) == 0xFF)
return true;

return false;
}
3 changes: 3 additions & 0 deletions src/knx/network_layer_coupler.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class NetworkLayerCoupler : public NetworkLayer

void evaluateCouplerType();
bool isGroupAddressInFilterTable(uint16_t groupAddress);
#ifdef KNX_TUNNELING
bool isTunnelAddress(uint16_t destination);
#endif

// Support a maximum of two physical interfaces for couplers
NetworkLayerEntity _netLayerEntities[2];
Expand Down

0 comments on commit f50bb3a

Please sign in to comment.