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

View File

@ -99,6 +99,7 @@
<ClInclude Include="..\..\src\knx\ip_data_link_layer.h" />
<ClInclude Include="..\..\src\knx\ip_parameter_object.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_value.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_parameter_object.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\memory.cpp" />
<ClCompile Include="..\..\src\knx\network_layer.cpp" />

View File

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

View File

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

View File

@ -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 <stdio.h>
#include <string.h>
@ -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);
KnxIpRoutingIndication packet(frame);
memcpy(buffer + KNXIP_HEADER_LEN, frameData(frame), frame.totalLenght());
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)

View File

@ -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);
}

View File

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

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