add object for routing indication packet

This commit is contained in:
Thomas Kunze 2019-12-22 17:31:33 +01:00
parent e788047213
commit d3d95f1185
9 changed files with 99 additions and 32 deletions

View File

@ -50,6 +50,7 @@ add_executable(knx-linux
../../src/knx/ip_parameter_object.cpp ../../src/knx/ip_parameter_object.cpp
../../src/knx/ip_parameter_object.h ../../src/knx/ip_parameter_object.h
../../src/knx/knx_ip_frame.cpp ../../src/knx/knx_ip_frame.cpp
../../src/knx/knx_ip_routing_indication.cpp
../../src/knx/knx_value.cpp ../../src/knx/knx_value.cpp
../../src/knx/knx_value.h ../../src/knx/knx_value.h
../../src/knx/memory.cpp ../../src/knx/memory.cpp

View File

@ -99,6 +99,7 @@
<ClInclude Include="..\..\src\knx\ip_data_link_layer.h" /> <ClInclude Include="..\..\src\knx\ip_data_link_layer.h" />
<ClInclude Include="..\..\src\knx\ip_parameter_object.h" /> <ClInclude Include="..\..\src\knx\ip_parameter_object.h" />
<ClInclude Include="..\..\src\knx\knx_ip_frame.h" /> <ClInclude Include="..\..\src\knx\knx_ip_frame.h" />
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h" />
<ClInclude Include="..\..\src\knx\knx_types.h" /> <ClInclude Include="..\..\src\knx\knx_types.h" />
<ClInclude Include="..\..\src\knx\knx_value.h" /> <ClInclude Include="..\..\src\knx\knx_value.h" />
<ClInclude Include="..\..\src\knx\memory.h" /> <ClInclude Include="..\..\src\knx\memory.h" />
@ -152,6 +153,7 @@
<ClCompile Include="..\..\src\knx\ip_data_link_layer.cpp" /> <ClCompile Include="..\..\src\knx\ip_data_link_layer.cpp" />
<ClCompile Include="..\..\src\knx\ip_parameter_object.cpp" /> <ClCompile Include="..\..\src\knx\ip_parameter_object.cpp" />
<ClCompile Include="..\..\src\knx\knx_ip_frame.cpp" /> <ClCompile Include="..\..\src\knx\knx_ip_frame.cpp" />
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp" />
<ClCompile Include="..\..\src\knx\knx_value.cpp" /> <ClCompile Include="..\..\src\knx\knx_value.cpp" />
<ClCompile Include="..\..\src\knx\memory.cpp" /> <ClCompile Include="..\..\src\knx\memory.cpp" />
<ClCompile Include="..\..\src\knx\network_layer.cpp" /> <ClCompile Include="..\..\src\knx\network_layer.cpp" />

View File

@ -173,6 +173,9 @@
<ClInclude Include="..\..\src\knx_facade.h"> <ClInclude Include="..\..\src\knx_facade.h">
<Filter>Header files</Filter> <Filter>Header files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\knx\knx_ip_routing_indication.h">
<Filter>Header files\knx</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
@ -304,5 +307,8 @@
<ClCompile Include="..\..\src\knx\usb_tunnel_interface.cpp"> <ClCompile Include="..\..\src\knx\usb_tunnel_interface.cpp">
<Filter>Source files\knx</Filter> <Filter>Source files\knx</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\knx\knx_ip_routing_indication.cpp">
<Filter>Source files\knx</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -11,6 +11,8 @@ DeviceObject::DeviceObject()
{ {
//Default to KNXA (0xFA) //Default to KNXA (0xFA)
uint8_t serialNumber[] = {0x00, 0xFA, 0x00, 0x00, 0x00, 0x00}; 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[] = 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_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_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 DataProperty(PID_ROUTING_COUNT, true, PDT_UNSIGNED_CHAR, 1, ReadLv3 | WriteLv3, (uint8_t)0),
new CallbackProperty<DeviceObject>(this, PID_PROG_MODE, true, PDT_BITSET8, 1, ReadLv3 | WriteLv3, new CallbackProperty<DeviceObject>(this, PID_PROG_MODE, true, PDT_BITSET8, 1, ReadLv3 | WriteLv3,
[](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t [](DeviceObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t
@ -66,9 +68,9 @@ DeviceObject::DeviceObject()
*data = (io->_ownAddress & 0xff); *data = (io->_ownAddress & 0xff);
return 1; return 1;
}), }),
new DataProperty(PID_IO_LIST, false, PDT_UNSIGNED_INT, 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, (uint8_t)0), 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, (uint8_t)0), new DataProperty(PID_DEVICE_DESCRIPTOR, false, PDT_GENERIC_02, 1, ReadLv3 | WriteLv0),
#ifdef USE_RF #ifdef USE_RF
new DataProperty(PID_RF_DOMAIN_ADDRESS_CEMI_SERVER, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3), new DataProperty(PID_RF_DOMAIN_ADDRESS_CEMI_SERVER, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv3),
#endif #endif

View File

@ -6,7 +6,7 @@
#include "platform.h" #include "platform.h"
#include "device_object.h" #include "device_object.h"
#include "address_table_object.h" #include "address_table_object.h"
#include "cemi_frame.h" #include "knx_ip_routing_indication.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -14,8 +14,6 @@
#define KNXIP_HEADER_LEN 0x6 #define KNXIP_HEADER_LEN 0x6
#define KNXIP_PROTOCOL_VERSION 0x10 #define KNXIP_PROTOCOL_VERSION 0x10
#define ROUTING_INDICATION 0x0530
#define KNXIP_MULTICAST_PORT 3671 #define KNXIP_MULTICAST_PORT 3671
#define MIN_LEN_CEMI 10 #define MIN_LEN_CEMI 10
@ -26,20 +24,12 @@ IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrT
bool IpDataLinkLayer::sendFrame(CemiFrame& frame) bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
{ {
uint16_t length = frame.totalLenght() + KNXIP_HEADER_LEN; KnxIpRoutingIndication packet(frame);
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()); bool success = sendBytes(packet.data(), packet.totalLength());
bool success = sendBytes(buffer, length);
// only send 50 packet per second: see KNX 3.2.6 p.6 // only send 50 packet per second: see KNX 3.2.6 p.6
delay(20); delay(20);
dataConReceived(frame, success); dataConReceived(frame, success);
delete[] buffer;
return success; return success;
} }
@ -62,15 +52,13 @@ void IpDataLinkLayer::loop()
uint16_t code; uint16_t code;
popWord(code, buffer + 2); popWord(code, buffer + 2);
if (code != ROUTING_INDICATION) // only routing indication for now switch ((KnxIpServiceType)code)
return; {
case RoutingIndication:
if (len < MIN_LEN_CEMI) KnxIpRoutingIndication routingIndication(buffer, len);
return; frameRecieved(routingIndication.frame());
break;
//TODO: Check correct length (additions Info + apdu length) }
CemiFrame frame(buffer + KNXIP_HEADER_LEN, len - KNXIP_HEADER_LEN);
frameRecieved(frame);
} }
void IpDataLinkLayer::enabled(bool value) void IpDataLinkLayer::enabled(bool value)

View File

@ -34,20 +34,43 @@ void KnxIpFrame::protocolVersion(KnxIpVersion version)
uint16_t KnxIpFrame::serviceTypeIdentifier() const uint16_t KnxIpFrame::serviceTypeIdentifier() const
{ {
return 0; return getWord(_data + 2);
} }
void KnxIpFrame::serviceTypeIdentifier(uint16_t identifier) void KnxIpFrame::serviceTypeIdentifier(uint16_t identifier)
{ {
pushWord(identifier, _data + 2);
} }
uint16_t KnxIpFrame::totalLength() const uint16_t KnxIpFrame::totalLength() const
{ {
return getWord(_data + 2); return getWord(_data + 4);
} }
void KnxIpFrame::totalLength(uint16_t length) void KnxIpFrame::totalLength(uint16_t length)
{ {
pushWord(length, _data + 2); pushWord(length, _data + 4);
} }
#endif #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);
}

View File

@ -3,9 +3,12 @@
#include "cemi_frame.h" #include "cemi_frame.h"
#include "config.h" #include "config.h"
#ifdef USE_IP #ifdef USE_IP
#define KNXIP_HEADER_LEN 0x6
enum KnxIpVersion enum KnxIpVersion
{ {
KnxIp1_0 KnxIp1_0 = 0x10
}; };
enum KnxIpServiceType enum KnxIpServiceType
@ -35,6 +38,8 @@ class KnxIpFrame
{ {
public: public:
KnxIpFrame(uint8_t* data, uint16_t length); KnxIpFrame(uint8_t* data, uint16_t length);
KnxIpFrame(uint16_t totalLength);
virtual ~KnxIpFrame();
uint8_t headerLength() const; uint8_t headerLength() const;
void headerLength(uint8_t length); void headerLength(uint8_t length);
KnxIpVersion protocolVersion() const; KnxIpVersion protocolVersion() const;
@ -43,8 +48,10 @@ class KnxIpFrame
void serviceTypeIdentifier(uint16_t identifier); void serviceTypeIdentifier(uint16_t identifier);
uint16_t totalLength() const; uint16_t totalLength() const;
void totalLength(uint16_t length); void totalLength(uint16_t length);
uint8_t* data();
private: protected:
bool _freeData = false;
uint8_t* _data = 0; uint8_t* _data = 0;
}; };
#endif #endif

View File

@ -0,0 +1,22 @@
#include "knx_ip_routing_indication.h"
#include <cstring>
#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

View File

@ -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