Skip to content

Commit

Permalink
wip: search extended
Browse files Browse the repository at this point in the history
  • Loading branch information
thewhobox committed Feb 13, 2024
1 parent a37e294 commit 371357a
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/knx/ip_data_link_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "knx_ip_routing_indication.h"
#include "knx_ip_search_request.h"
#include "knx_ip_search_response.h"
#include "knx_ip_search_request_extended.h"
#include "knx_ip_search_response_extended.h"
#include "knx_facade.h"
#ifdef KNX_TUNNELING
#include "knx_ip_connect_request.h"
Expand Down Expand Up @@ -320,7 +322,7 @@ void IpDataLinkLayer::loop()
}
case SearchRequestExt:
{
// FIXME, implement (not needed atm)
loopHandleSearchRequestExtended(buffer, len);
break;
}
#ifdef KNX_TUNNELING
Expand Down Expand Up @@ -381,6 +383,68 @@ void IpDataLinkLayer::loop()
}
}

void IpDataLinkLayer::loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t length)
{
KnxIpSearchRequestExtended searchRequest(buffer, length);

if(searchRequest.srpByProgMode)
if(!knx.progMode()) return;

if(searchRequest.srpByMacAddr)
{
const uint8_t *x = _ipParameters.propertyData(PID_MAC_ADDRESS);
for(int i = 0; i<6;i++)
if(searchRequest.srpMacAddr[i] != x[i])
return;
}

#define LEN_SERVICE_FAMILIES 2
#if MASK_VERSION == 0x091A
#ifdef KNX_TUNNELING
#define LEN_SERVICE_DIB (2 + 4 * LEN_SERVICE_FAMILIES)
#else
#define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
#endif
#else
#ifdef KNX_TUNNELING
#define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
#else
#define LEN_SERVICE_DIB (2 + 2 * LEN_SERVICE_FAMILIES)
#endif
#endif

//defaults: “Device Information DIB”, “Extended Device Information DIB” and “Supported Services DIB”.
int dipLength = LEN_DEVICE_INFORMATION_DIB + LEN_SERVICE_DIB + LEN_EXTENDED_DEVICE_INFORMATION_DIB;

if(searchRequest.srpByService)
{
//FIXME not implemented
return;
}

if(searchRequest.srpRequestDIBs)
{
//FIXME not implemented
//dipLength += XX
return;
}

KnxIpSearchResponseExtended searchResponse(_ipParameters, _deviceObject, dipLength);

searchResponse.setDeviceInfo(_ipParameters, _deviceObject);
searchResponse.setSupportedServices();
searchResponse.setExtendedDeviceInfo();

if(searchRequest.srpRequestDIBs)
{
//FIXME not implemented
//searchResponse.setXXXX
return;
}

_platform.sendBytesUniCast(searchRequest.hpai().ipAddress(), searchRequest.hpai().ipPortNumber(), searchResponse.data(), searchResponse.totalLength());
}

#ifdef KNX_TUNNELING
void IpDataLinkLayer::loopHandleConnectRequest(uint8_t* buffer, uint16_t length)
{
Expand Down
1 change: 1 addition & 0 deletions src/knx/ip_data_link_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class IpDataLinkLayer : public DataLinkLayer
void loopHandleDeviceConfigurationRequest(uint8_t* buffer, uint16_t length);
void loopHandleTunnelingRequest(uint8_t* buffer, uint16_t length);
#endif
void loopHandleSearchRequestExtended(uint8_t* buffer, uint16_t length);
bool sendBytes(uint8_t* buffer, uint16_t length);
bool isSendLimitReached();

Expand Down
3 changes: 3 additions & 0 deletions src/knx/knx_ip_dib.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ enum DescriptionTypeCode : uint8_t
IP_CONFIG = 0x03,
IP_CUR_CONFIG = 0x04,
KNX_ADDRESSES = 0x05,
MANUFACTURER_DATA = 0x06,
TUNNELING_INFO = 0x07,
EXTENDED_DEVICE_INFO = 0x08,
MFR_DATA = 0xFE
};

Expand Down
42 changes: 42 additions & 0 deletions src/knx/knx_ip_extended_device_information_dib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "knx_ip_extended_device_information_dib.h"
#include "bits.h"

#ifdef USE_IP
KnxIpExtendedDeviceInformationDIB::KnxIpExtendedDeviceInformationDIB(uint8_t* data) : KnxIpDIB(data)
{}

uint8_t KnxIpExtendedDeviceInformationDIB::status() const
{
return _data[2];
}


void KnxIpExtendedDeviceInformationDIB::status(uint8_t value)
{
_data[2] = value;
}


uint16_t KnxIpExtendedDeviceInformationDIB::localMaxApdu() const
{
return getWord(_data + 4);
}


void KnxIpExtendedDeviceInformationDIB::localMaxApdu(uint16_t value)
{
pushWord(value, _data + 4);
}


uint16_t KnxIpExtendedDeviceInformationDIB::deviceDescriptor() const
{
return getWord(_data + 6);
}


void KnxIpExtendedDeviceInformationDIB::deviceDescriptor(uint16_t value)
{
pushWord(value, _data + 6);
}
#endif
19 changes: 19 additions & 0 deletions src/knx/knx_ip_extended_device_information_dib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include "knx_ip_dib.h"

#ifdef USE_IP
#define LEN_EXTENDED_DEVICE_INFORMATION_DIB 8

class KnxIpExtendedDeviceInformationDIB : public KnxIpDIB
{
public:
KnxIpExtendedDeviceInformationDIB(uint8_t* data);
uint8_t status() const;
void status(uint8_t value);
uint16_t localMaxApdu() const;
void localMaxApdu(uint16_t value);
uint16_t deviceDescriptor() const;
void deviceDescriptor(uint16_t value);
};

#endif
38 changes: 38 additions & 0 deletions src/knx/knx_ip_search_request_extended.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "knx_ip_search_request_extended.h"
#ifdef USE_IP
KnxIpSearchRequestExtended::KnxIpSearchRequestExtended(uint8_t* data, uint16_t length)
: KnxIpFrame(data, length), _hpai(data + LEN_KNXIP_HEADER)
{
if(length == LEN_KNXIP_HEADER + LEN_IPHPAI) return; //we dont have SRPs

int currentPos = LEN_KNXIP_HEADER + LEN_IPHPAI;
while(currentPos < length)
{
switch(data[currentPos+1])
{
case 0x01:
srpByProgMode = true;
break;

case 0x02:
srpByMacAddr = true;
srpMacAddr = data + 2;
break;

case 0x03:
srpByService = true;
break;

case 0x04:
srpRequestDIBs = true;
break;
}
currentPos += data[currentPos];
};
}

IpHostProtocolAddressInformation& KnxIpSearchRequestExtended::hpai()
{
return _hpai;
}
#endif
19 changes: 19 additions & 0 deletions src/knx/knx_ip_search_request_extended.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "knx_ip_frame.h"
#include "ip_host_protocol_address_information.h"
#ifdef USE_IP
class KnxIpSearchRequestExtended : public KnxIpFrame
{
public:
KnxIpSearchRequestExtended(uint8_t* data, uint16_t length);
IpHostProtocolAddressInformation& hpai();
bool srpByProgMode = false;
bool srpByMacAddr = false;
bool srpByService = false;
bool srpRequestDIBs = false;
uint8_t *srpMacAddr = nullptr;
private:
IpHostProtocolAddressInformation _hpai;
};
#endif
101 changes: 101 additions & 0 deletions src/knx/knx_ip_search_response_extended.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "knx_ip_search_response_extended.h"
#ifdef USE_IP

#define LEN_SERVICE_FAMILIES 2
#if MASK_VERSION == 0x091A
#ifdef KNX_TUNNELING
#define LEN_SERVICE_DIB (2 + 4 * LEN_SERVICE_FAMILIES)
#else
#define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
#endif
#else
#ifdef KNX_TUNNELING
#define LEN_SERVICE_DIB (2 + 3 * LEN_SERVICE_FAMILIES)
#else
#define LEN_SERVICE_DIB (2 + 2 * LEN_SERVICE_FAMILIES)
#endif
#endif

KnxIpSearchResponseExtended::KnxIpSearchResponseExtended(IpParameterObject& parameters, DeviceObject& deviceObject, int dibLength)
: KnxIpFrame(LEN_KNXIP_HEADER + LEN_IPHPAI + dibLength),
_controlEndpoint(_data + LEN_KNXIP_HEADER)
{
serviceTypeIdentifier(SearchResponse);

_controlEndpoint.length(LEN_IPHPAI);
_controlEndpoint.code(IPV4_UDP);
_controlEndpoint.ipAddress(parameters.propertyValue<uint32_t>(PID_CURRENT_IP_ADDRESS));
_controlEndpoint.ipPortNumber(KNXIP_MULTICAST_PORT);

currentPos = LEN_KNXIP_HEADER + LEN_IPHPAI;
}

void KnxIpSearchResponseExtended::setDeviceInfo(IpParameterObject& parameters, DeviceObject& deviceObject)
{
KnxIpDeviceInformationDIB _deviceInfo(_data + currentPos);
_deviceInfo.length(LEN_DEVICE_INFORMATION_DIB);
_deviceInfo.code(DEVICE_INFO);
#if MASK_VERSION == 0x57B0
_deviceInfo.medium(0x20); //MediumType is IP (for IP-Only Devices)
#else
_deviceInfo.medium(0x02); //MediumType is TP
#endif
_deviceInfo.status(deviceObject.progMode());
_deviceInfo.individualAddress(parameters.propertyValue<uint16_t>(PID_KNX_INDIVIDUAL_ADDRESS));
_deviceInfo.projectInstallationIdentifier(parameters.propertyValue<uint16_t>(PID_PROJECT_INSTALLATION_ID));
_deviceInfo.serialNumber(deviceObject.propertyData(PID_SERIAL_NUMBER));
_deviceInfo.routingMulticastAddress(parameters.propertyValue<uint32_t>(PID_ROUTING_MULTICAST_ADDRESS));
//_deviceInfo.routingMulticastAddress(0);

uint8_t mac_address[LEN_MAC_ADDRESS] = {0};
Property* prop = parameters.property(PID_MAC_ADDRESS);
prop->read(mac_address);
_deviceInfo.macAddress(mac_address);

uint8_t friendlyName[LEN_FRIENDLY_NAME] = {0};
prop = parameters.property(PID_FRIENDLY_NAME);
prop->read(1, LEN_FRIENDLY_NAME, friendlyName);
_deviceInfo.friendlyName(friendlyName);

currentPos += LEN_DEVICE_INFORMATION_DIB;
}

void KnxIpSearchResponseExtended::setSupportedServices()
{
KnxIpSupportedServiceDIB _supportedServices(_data + currentPos);
_supportedServices.length(LEN_SERVICE_DIB);
_supportedServices.code(SUPP_SVC_FAMILIES);
_supportedServices.serviceVersion(Core, 1);
_supportedServices.serviceVersion(DeviceManagement, 1);
#ifdef KNX_TUNNELING
_supportedServices.serviceVersion(Tunnelling, 1);
#endif
#if MASK_VERSION == 0x091A
_supportedServices.serviceVersion(Routing, 1);
#endif
currentPos += LEN_SERVICE_DIB;
}

void KnxIpSearchResponseExtended::setExtendedDeviceInfo()
{
KnxIpExtendedDeviceInformationDIB _extended(_data + currentPos);
_extended.length(LEN_EXTENDED_DEVICE_INFORMATION_DIB);
_extended.code(EXTENDED_DEVICE_INFO);
_extended.status(0x01); //FIXME dont know encoding PID_MEDIUM_STATUS=51 RouterObject
_extended.localMaxApdu(254); //FIXME is this correct?
_extended.deviceDescriptor(MASK_VERSION);

currentPos += LEN_EXTENDED_DEVICE_INFORMATION_DIB;
}

IpHostProtocolAddressInformation& KnxIpSearchResponseExtended::controlEndpoint()
{
return _controlEndpoint;
}


uint8_t *KnxIpSearchResponseExtended::DIBs()
{
return _data + LEN_KNXIP_HEADER + LEN_IPHPAI;
}
#endif
30 changes: 30 additions & 0 deletions src/knx/knx_ip_search_response_extended.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include "knx_ip_frame.h"
#include "ip_host_protocol_address_information.h"
#include "knx_ip_device_information_dib.h"
#include "knx_ip_extended_device_information_dib.h"
#include "knx_ip_supported_service_dib.h"
#include "ip_parameter_object.h"
#ifdef USE_IP

class KnxIpSearchResponseExtended : public KnxIpFrame
{
public:
KnxIpSearchResponseExtended(IpParameterObject& parameters, DeviceObject& deviceObj, int dibLength);
IpHostProtocolAddressInformation& controlEndpoint();
void setDeviceInfo(IpParameterObject& parameters, DeviceObject& deviceObject);
void setSupportedServices();
//setIpConfig
//setIpCurrentConfig
//setAddresses
//setManuData
//setTunnelingInfo
void setExtendedDeviceInfo();
uint8_t *DIBs();
private:
IpHostProtocolAddressInformation _controlEndpoint;
int currentPos = 0;
};

#endif

0 comments on commit 371357a

Please sign in to comment.