diff --git a/examples/knx-linux/CMakeLists.txt b/examples/knx-linux/CMakeLists.txt
index 24cff37..470dfaa 100644
--- a/examples/knx-linux/CMakeLists.txt
+++ b/examples/knx-linux/CMakeLists.txt
@@ -50,6 +50,7 @@ add_executable(knx-linux
../../src/knx/ip_parameter_object.cpp
../../src/knx/ip_parameter_object.h
../../src/knx/knx_ip_frame.cpp
+ ../../src/knx/knx_ip_routing_indication.cpp
../../src/knx/knx_value.cpp
../../src/knx/knx_value.h
../../src/knx/memory.cpp
diff --git a/examples/knx-linux/knx-linux.vcxproj b/examples/knx-linux/knx-linux.vcxproj
index a968974..b74baa1 100644
--- a/examples/knx-linux/knx-linux.vcxproj
+++ b/examples/knx-linux/knx-linux.vcxproj
@@ -99,6 +99,7 @@
+
@@ -152,6 +153,7 @@
+
diff --git a/examples/knx-linux/knx-linux.vcxproj.filters b/examples/knx-linux/knx-linux.vcxproj.filters
index e4f7cab..fa8dd01 100644
--- a/examples/knx-linux/knx-linux.vcxproj.filters
+++ b/examples/knx-linux/knx-linux.vcxproj.filters
@@ -173,6 +173,9 @@
Header files
+
+ Header files\knx
+
@@ -304,5 +307,8 @@
Source files\knx
+
+ Source files\knx
+
\ No newline at end of file
diff --git a/src/knx/device_object.cpp b/src/knx/device_object.cpp
index 4c310b4..3d8e6c4 100644
--- a/src/knx/device_object.cpp
+++ b/src/knx/device_object.cpp
@@ -11,6 +11,8 @@ DeviceObject::DeviceObject()
{
//Default to KNXA (0xFA)
uint8_t serialNumber[] = {0x00, 0xFA, 0x00, 0x00, 0x00, 0x00};
+ uint8_t hardwareType[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ uint8_t version[] = {0x00, 0x00, 0x03};
Property* properties[] =
{
@@ -27,7 +29,7 @@ DeviceObject::DeviceObject()
}),
new DataProperty(PID_DEVICE_CONTROL, true, PDT_BITSET8, 1, ReadLv3 | WriteLv3, (uint8_t)0),
new DataProperty(PID_ORDER_INFO, false, PDT_GENERIC_10, 1, ReadLv3 | WriteLv0),
- new DataProperty(PID_VERSION, false, PDT_VERSION, 1, ReadLv3 | WriteLv0, (uint16_t)3),
+ new DataProperty(PID_VERSION, false, PDT_VERSION, 1, ReadLv3 | WriteLv0, version),
new DataProperty(PID_ROUTING_COUNT, true, PDT_UNSIGNED_CHAR, 1, ReadLv3 | WriteLv3, (uint8_t)0),
new CallbackProperty(this, PID_PROG_MODE, true, PDT_BITSET8, 1, ReadLv3 | WriteLv3,
[](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t
@@ -66,9 +68,9 @@ DeviceObject::DeviceObject()
*data = (io->_ownAddress & 0xff);
return 1;
}),
- new DataProperty(PID_IO_LIST, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, (uint8_t)0),
- new DataProperty(PID_HARDWARE_TYPE, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3, (uint8_t)0),
- new DataProperty(PID_DEVICE_DESCRIPTOR, false, PDT_GENERIC_02, 1, ReadLv3 | WriteLv0, (uint8_t)0),
+ new DataProperty(PID_IO_LIST, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0),
+ new DataProperty(PID_HARDWARE_TYPE, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3, hardwareType),
+ new DataProperty(PID_DEVICE_DESCRIPTOR, false, PDT_GENERIC_02, 1, ReadLv3 | WriteLv0),
#ifdef USE_RF
new DataProperty(PID_RF_DOMAIN_ADDRESS_CEMI_SERVER, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3),
#endif
diff --git a/src/knx/ip_data_link_layer.cpp b/src/knx/ip_data_link_layer.cpp
index f83fd0a..2cb2ad2 100644
--- a/src/knx/ip_data_link_layer.cpp
+++ b/src/knx/ip_data_link_layer.cpp
@@ -6,7 +6,7 @@
#include "platform.h"
#include "device_object.h"
#include "address_table_object.h"
-#include "cemi_frame.h"
+#include "knx_ip_routing_indication.h"
#include
#include
@@ -14,8 +14,6 @@
#define KNXIP_HEADER_LEN 0x6
#define KNXIP_PROTOCOL_VERSION 0x10
-#define ROUTING_INDICATION 0x0530
-
#define KNXIP_MULTICAST_PORT 3671
#define MIN_LEN_CEMI 10
@@ -26,20 +24,12 @@ IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrT
bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
{
- uint16_t length = frame.totalLenght() + KNXIP_HEADER_LEN;
- uint8_t* buffer = new uint8_t[length];
- buffer[0] = KNXIP_HEADER_LEN;
- buffer[1] = KNXIP_PROTOCOL_VERSION;
- pushWord(ROUTING_INDICATION, buffer + 2);
- pushWord(length, buffer + 4);
-
- memcpy(buffer + KNXIP_HEADER_LEN, frameData(frame), frame.totalLenght());
+ KnxIpRoutingIndication packet(frame);
- bool success = sendBytes(buffer, length);
+ bool success = sendBytes(packet.data(), packet.totalLength());
// only send 50 packet per second: see KNX 3.2.6 p.6
delay(20);
dataConReceived(frame, success);
- delete[] buffer;
return success;
}
@@ -62,15 +52,13 @@ void IpDataLinkLayer::loop()
uint16_t code;
popWord(code, buffer + 2);
- if (code != ROUTING_INDICATION) // only routing indication for now
- return;
-
- if (len < MIN_LEN_CEMI)
- return;
-
- //TODO: Check correct length (additions Info + apdu length)
- CemiFrame frame(buffer + KNXIP_HEADER_LEN, len - KNXIP_HEADER_LEN);
- frameRecieved(frame);
+ switch ((KnxIpServiceType)code)
+ {
+ case RoutingIndication:
+ KnxIpRoutingIndication routingIndication(buffer, len);
+ frameRecieved(routingIndication.frame());
+ break;
+ }
}
void IpDataLinkLayer::enabled(bool value)
diff --git a/src/knx/knx_ip_frame.cpp b/src/knx/knx_ip_frame.cpp
index 7527dd2..038a817 100644
--- a/src/knx/knx_ip_frame.cpp
+++ b/src/knx/knx_ip_frame.cpp
@@ -34,20 +34,43 @@ void KnxIpFrame::protocolVersion(KnxIpVersion version)
uint16_t KnxIpFrame::serviceTypeIdentifier() const
{
- return 0;
+ return getWord(_data + 2);
}
void KnxIpFrame::serviceTypeIdentifier(uint16_t identifier)
{
+ pushWord(identifier, _data + 2);
}
uint16_t KnxIpFrame::totalLength() const
{
- return getWord(_data + 2);
+ return getWord(_data + 4);
}
void KnxIpFrame::totalLength(uint16_t length)
{
- pushWord(length, _data + 2);
+ pushWord(length, _data + 4);
+}
+#endif
+
+uint8_t* KnxIpFrame::data()
+{
+ return _data;
+}
+
+
+KnxIpFrame::~KnxIpFrame()
+{
+ if (_freeData)
+ delete _data;
+}
+
+
+KnxIpFrame::KnxIpFrame(uint16_t length)
+{
+ _data = new uint8_t[length];
+ _freeData = true;
+ headerLength(KNXIP_HEADER_LEN);
+ protocolVersion(KnxIp1_0);
+ totalLength(length);
}
-#endif
\ No newline at end of file
diff --git a/src/knx/knx_ip_frame.h b/src/knx/knx_ip_frame.h
index 728ef30..b5ab6c8 100644
--- a/src/knx/knx_ip_frame.h
+++ b/src/knx/knx_ip_frame.h
@@ -3,9 +3,12 @@
#include "cemi_frame.h"
#include "config.h"
#ifdef USE_IP
+
+#define KNXIP_HEADER_LEN 0x6
+
enum KnxIpVersion
{
- KnxIp1_0
+ KnxIp1_0 = 0x10
};
enum KnxIpServiceType
@@ -35,6 +38,8 @@ class KnxIpFrame
{
public:
KnxIpFrame(uint8_t* data, uint16_t length);
+ KnxIpFrame(uint16_t totalLength);
+ virtual ~KnxIpFrame();
uint8_t headerLength() const;
void headerLength(uint8_t length);
KnxIpVersion protocolVersion() const;
@@ -43,8 +48,10 @@ class KnxIpFrame
void serviceTypeIdentifier(uint16_t identifier);
uint16_t totalLength() const;
void totalLength(uint16_t length);
+ uint8_t* data();
- private:
+ protected:
+ bool _freeData = false;
uint8_t* _data = 0;
};
#endif
\ No newline at end of file
diff --git a/src/knx/knx_ip_routing_indication.cpp b/src/knx/knx_ip_routing_indication.cpp
new file mode 100644
index 0000000..df51576
--- /dev/null
+++ b/src/knx/knx_ip_routing_indication.cpp
@@ -0,0 +1,22 @@
+#include "knx_ip_routing_indication.h"
+#include
+
+#ifdef USE_IP
+CemiFrame& KnxIpRoutingIndication::frame()
+{
+ return _frame;
+}
+
+
+KnxIpRoutingIndication::KnxIpRoutingIndication(uint8_t* data,
+ uint16_t length) : KnxIpFrame(data, length), _frame(data + headerLength(), length - headerLength())
+{
+}
+
+KnxIpRoutingIndication::KnxIpRoutingIndication(CemiFrame frame)
+ : KnxIpFrame(frame.totalLenght() + KNXIP_HEADER_LEN), _frame(_data + headerLength(), frame.totalLenght())
+{
+ serviceTypeIdentifier(RoutingIndication);
+ memcpy(_data + KNXIP_HEADER_LEN, frame.data(), frame.totalLenght());
+}
+#endif
\ No newline at end of file
diff --git a/src/knx/knx_ip_routing_indication.h b/src/knx/knx_ip_routing_indication.h
new file mode 100644
index 0000000..3de7975
--- /dev/null
+++ b/src/knx/knx_ip_routing_indication.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "knx_ip_frame.h"
+#include "cemi_frame.h"
+#ifdef USE_IP
+
+class KnxIpRoutingIndication : public KnxIpFrame
+{
+ public:
+ KnxIpRoutingIndication(uint8_t* data, uint16_t length);
+ KnxIpRoutingIndication(CemiFrame frame);
+ CemiFrame& frame();
+ private:
+ CemiFrame _frame;
+};
+#endif
\ No newline at end of file