Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Routing and new Tunneling Support #26

Merged
merged 1 commit into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions src/esp32_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,32 +99,50 @@ bool Esp32Platform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
return true;
}

int Esp32Platform::readBytesMultiCast(uint8_t * buffer, uint16_t maxLen)
int Esp32Platform::readBytesMultiCast(uint8_t * buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port)
{
int len = _udp.parsePacket();
if (len == 0)
return 0;

if (len > maxLen)
{
KNX_DEBUG_SERIAL.printf("udp buffer to small. was %d, needed %d\n", maxLen, len);
fatalError();
println("Unexpected UDP data packet length - drop packet");
for (size_t i = 0; i < len; i++)
_udp.read();
return 0;
}

_udp.read(buffer, len);
//printHex("-> ", buffer, len);
_remoteIP = _udp.remoteIP();
_remotePort = _udp.remotePort();
src_addr = htonl(_remoteIP);
src_port = _remotePort;

// print("Remote IP: ");
// print(_udp.remoteIP().toString().c_str());
// printHex("-> ", buffer, len);

return len;
}

bool Esp32Platform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len)
{
IPAddress ucastaddr(htonl(addr));
println("sendBytesUniCast endPacket fail");
if(_udp.beginPacket(ucastaddr, port) == 1) {

if(!addr)
ucastaddr = _remoteIP;

if(!port)
port = _remotePort;

if(_udp.beginPacket(ucastaddr, port) == 1)
{
_udp.write(buffer, len);
if(_udp.endPacket() == 0) println("sendBytesUniCast endPacket fail");
}
else println("sendBytesUniCast beginPacket fail");
else
println("sendBytesUniCast beginPacket fail");
return true;
}

Expand Down
6 changes: 5 additions & 1 deletion src/esp32_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,18 @@ class Esp32Platform : public ArduinoPlatform
void setupMultiCast(uint32_t addr, uint16_t port) override;
void closeMultiCast() override;
bool sendBytesMultiCast(uint8_t* buffer, uint16_t len) override;
int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen) override;
int readBytesMultiCast(uint8_t* buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port) override;

//unicast
bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len) override;

//memory
uint8_t* getEepromBuffer(uint32_t size);
void commitToEeprom();

protected: IPAddress _remoteIP;
protected: uint16_t _remotePort;

private:
WiFiUDP _udp;
int8_t _rxPin = -1;
Expand Down
114 changes: 111 additions & 3 deletions src/knx/application_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,38 @@ void ApplicationLayer::propertyDescriptionReadResponse(AckType ack, Priority pri
individualSend(ack, hopType, priority, asap, apdu, secCtrl);
}

void ApplicationLayer::propertyExtDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl,
uint16_t objectType, uint16_t objectInstance, uint16_t propertyId, uint16_t propertyIndex, uint8_t descriptionType, bool writeEnable, uint8_t type,
uint16_t maxNumberOfElements, uint8_t access)
{
CemiFrame frame(16);
APDU& apdu = frame.apdu();
apdu.type(PropertyExtDescriptionResponse);
uint8_t* data = apdu.data();

data[1] = (objectType & 0xff00) >> 8;
data[2] = (objectType & 0x00ff);

data[3] = (objectInstance & 0x0ff0) >> 4;
data[4] = (objectInstance & 0x000f) << 4 | (propertyId & 0x0f00) >> 8;
data[5] = (propertyId & 0x00ff);

data[6] = (descriptionType & 0x000f) << 4 | (propertyIndex & 0x0f00) >> 8;
data[7] = (propertyIndex & 0x00ff);
data[8] = 0; // DataPointType ??
data[9] = 0; // DataPointType ??
data[10] = 0; // DataPointType ??
data[11] = 0; // DataPointType ??

if (writeEnable)
data[12] |= 0x80;
data[12] |= (type & 0x3f);

pushWord(maxNumberOfElements & 0xfff, data + 13);
data[15] = access;
individualSend(ack, hopType, priority, asap, apdu, secCtrl);
}

void ApplicationLayer::memoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress)
{
Expand All @@ -740,6 +772,18 @@ void ApplicationLayer::memoryReadResponse(AckType ack, Priority priority, HopCou
memorySend(MemoryResponse, ack, priority, hopType, asap, secCtrl, number, memoryAddress, memoryData);
}

void ApplicationLayer::memoryRouterReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t * memoryData)
{
memoryRouterSend(MemoryRouterReadResponse, ack, priority, hopType, asap, secCtrl, number, memoryAddress, memoryData);
}

void ApplicationLayer::memoryRoutingTableReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t * memoryData)
{
memoryRoutingTableSend(RoutingTableReadResponse, ack, priority, hopType, asap, secCtrl, number, memoryAddress, memoryData);
}

void ApplicationLayer::memoryExtReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, ReturnCodes code,
uint8_t number, uint32_t memoryAddress, uint8_t * memoryData)
{
Expand Down Expand Up @@ -962,6 +1006,34 @@ void ApplicationLayer::memorySend(ApduType type, AckType ack, Priority priority,
individualSend(ack, hopType, priority, asap, apdu, secCtrl);
}

void ApplicationLayer::memoryRouterSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t * memoryData)
{
CemiFrame frame(4 + number);
APDU& apdu = frame.apdu();
apdu.type(type);
uint8_t* data = apdu.data();
data[1] |= (number & 0xf);
pushWord(memoryAddress & 0xffff, data + 2);
if (number > 0)
memcpy(data + 4, memoryData, number);
individualSend(ack, hopType, priority, asap, apdu, secCtrl);
}

void ApplicationLayer::memoryRoutingTableSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t * memoryData)
{
CemiFrame frame(4 + number);
APDU& apdu = frame.apdu();
apdu.type(type);
uint8_t* data = apdu.data();
data[1] |= (number & 0xf);
pushWord(memoryAddress & 0xffff, data + 2);
if (number > 0)
memcpy(data + 4, memoryData, number);
individualSend(ack, hopType, priority, asap, apdu, secCtrl);
}

void ApplicationLayer::userMemorySend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint32_t memoryAddress, uint8_t * memoryData)
{
Expand Down Expand Up @@ -1084,6 +1156,17 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior
case PropertyDescriptionRead:
_bau.propertyDescriptionReadIndication(priority, hopType, tsap, secCtrl, data[1], data[2], data[3]);
break;
case PropertyExtDescriptionRead:
{
ObjectType objectType = (ObjectType)(((data[1] & 0xff) << 8) | (data[2] & 0xff));
uint16_t objectInstance = ((data[3] & 0xff) << 4) | ((data[4] & 0xf0) >> 4);
uint16_t propertyId = ((data[4] & 0x0f) << 8) | (data[5] & 0xff);
uint8_t descriptionType = (data[6] & 0xf0) >> 4;
uint16_t propertyIndex = ((data[7] & 0x0f) << 8) | (data[8] & 0xff);

_bau.propertyExtDescriptionReadIndication(priority, hopType, tsap, secCtrl, objectType, objectInstance, propertyId, descriptionType, propertyIndex);
break;
}
case PropertyDescriptionResponse:
_bau.propertyDescriptionReadAppLayerConfirm(priority, hopType, tsap, secCtrl, data[1], data[2], data[3],
(data[4] & 0x80) > 0, data[4] & 0x3f, getWord(data + 5) & 0xfff, data[7]);
Expand All @@ -1097,8 +1180,30 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior
case MemoryWrite:
_bau.memoryWriteIndication(priority, hopType, tsap, secCtrl, data[0] & 0x3f, getWord(data + 1), data + 3);
break;
case MemoryExtRead:
{

// EC
case MemoryRouterWrite:
print("MemoryRouterWrite: ");
_bau.memoryRouterWriteIndication(priority, hopType, tsap, secCtrl, data[1], getWord(data + 2), data + 4);
break;
case MemoryRouterReadResponse:
_bau.memoryRouterReadAppLayerConfirm(priority, hopType, tsap, secCtrl, data[1], getWord(data + 2), data + 4);
break;
case RoutingTableOpen:
println("Received OpenRoutingTable APDU, doing nothing");
break;
case RoutingTableRead:
_bau.memoryRoutingTableReadIndication(priority, hopType, tsap, secCtrl, data[1], getWord(data + 2));
break;
case RoutingTableReadResponse:
_bau.memoryRoutingTableReadAppLayerConfirm(priority, hopType, tsap, secCtrl, data[1], getWord(data + 2), data + 4);
break;
case RoutingTableWrite:
_bau.memoryRoutingTableWriteIndication(priority, hopType, tsap, secCtrl, data[1], getWord(data + 2), data + 4);
break;
// end EC

case MemoryExtRead: {
uint8_t number = data[1];
uint32_t memoryAddress = ((data[2] & 0xff) << 16) | ((data[3] & 0xff) << 8) | (data[4] & 0xff);
_bau.memoryExtReadIndication(priority, hopType, tsap, secCtrl, number, memoryAddress);
Expand Down Expand Up @@ -1162,7 +1267,7 @@ void ApplicationLayer::individualIndication(HopCountType hopType, Priority prior
}
default:
print("Individual-indication: unhandled APDU-Type: ");
println(apdu.type());
apdu.printPDU();
}
}

Expand Down Expand Up @@ -1210,6 +1315,9 @@ void ApplicationLayer::individualConfirm(AckType ack, HopCountType hopType, Prio
case PropertyDescriptionRead:
_bau.propertyDescriptionReadLocalConfirm(ack, priority, hopType, tsap, secCtrl, data[1], data[2], data[3], status);
break;
case PropertyExtDescriptionRead:
_bau.propertyExtDescriptionReadLocalConfirm(ack, priority, hopType, tsap, secCtrl, data[1], data[2], data[3], status);
break;
case PropertyDescriptionResponse:
_bau.propertyDescriptionReadResponseConfirm(ack, priority, hopType, tsap, secCtrl, data[1], data[2], data[3],
(data[4] & 0x80) > 0, data[4] & 0x3f, getWord(data + 5) & 0xfff, data[7], status);
Expand Down
13 changes: 13 additions & 0 deletions src/knx/application_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,17 @@ class ApplicationLayer
void propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl,
uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type,
uint16_t maxNumberOfElements, uint8_t access);
void propertyExtDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl,
uint16_t objectType, uint16_t objectInstance, uint16_t propertyId, uint16_t propertyIndex, uint8_t descriptionType, bool writeEnable, uint8_t type,
uint16_t maxNumberOfElements, uint8_t access);
void memoryReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress);
void memoryReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* data);
void memoryRouterReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* data);
void memoryRoutingTableReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* data);
void memoryExtReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, ReturnCodes code, uint8_t number,
uint32_t memoryAddress, uint8_t* data);
void memoryExtWriteResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, ReturnCodes code, uint8_t number,
Expand Down Expand Up @@ -195,6 +202,12 @@ class ApplicationLayer
uint16_t objectType, uint8_t objectInstance, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length);
void memorySend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* memoryData);
// Added EC
void memoryRouterSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* memoryData);
void memoryRoutingTableSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl, uint8_t number,
uint16_t memoryAddress, uint8_t* memoryData);
//
void userMemorySend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl& secCtrl,
uint8_t number, uint32_t memoryAddress, uint8_t* memoryData);
void groupValueSend(ApduType type, AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl& secCtrl, uint8_t* data, uint8_t& dataLength);
Expand Down
4 changes: 4 additions & 0 deletions src/knx/application_program_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
#include <cstring>

ApplicationProgramObject::ApplicationProgramObject(Memory& memory)
#if MASK_VERSION == 0x091A
: TableObject(memory, 0x0100, 0x0100)
#else
: TableObject(memory)
#endif
{
Property* properties[] =
{
Expand Down
25 changes: 25 additions & 0 deletions src/knx/bau.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,19 @@ void BusAccessUnit::propertyDescriptionReadLocalConfirm(AckType ack, Priority pr
{
}

void BusAccessUnit::propertyExtDescriptionReadLocalConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint16_t objectIndex, uint8_t propertyId, uint16_t propertyIndex, bool status)
{
}

void BusAccessUnit::propertyDescriptionReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex)
{
}

void BusAccessUnit::propertyExtDescriptionReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl,
uint16_t objectType, uint16_t objectInstance, uint16_t propertyId, uint8_t descriptionType, uint16_t propertyIndex)
{
}

void BusAccessUnit::propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type, uint16_t maxNumberOfElements, uint8_t access)
{
}
Expand Down Expand Up @@ -191,6 +200,22 @@ void BusAccessUnit::memoryWriteIndication(Priority priority, HopCountType hopTyp
{
}

void BusAccessUnit::memoryRouterWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint16_t memoryAddress, uint8_t* data)
{
}
void BusAccessUnit::memoryRouterReadAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint16_t memoryAddress, uint8_t* data)
{
}
void BusAccessUnit::memoryRoutingTableReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint16_t memoryAddress)
{
}
void BusAccessUnit::memoryRoutingTableReadAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint16_t memoryAddress, uint8_t* data)
{
}
void BusAccessUnit::memoryRoutingTableWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint16_t memoryAddress, uint8_t *data)
{
}

void BusAccessUnit::memoryExtReadLocalConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint32_t memoryAddress, bool status)
{
}
Expand Down
Loading
Loading