mirror of
https://github.com/thelsing/knx.git
synced 2025-07-25 13:47:29 +02:00
164 lines
6.4 KiB
C++
164 lines
6.4 KiB
C++
#include "network_layer_device.h"
|
|
#include "device_object.h"
|
|
#include "tpdu.h"
|
|
#include "cemi_frame.h"
|
|
#include "bits.h"
|
|
#include "util/logger.h"
|
|
|
|
#define LOGGER Logger::logger("NetworkLayerDevice")
|
|
|
|
NetworkLayerDevice::NetworkLayerDevice(DeviceObject& deviceObj, TransportLayer& layer) :
|
|
NetworkLayer(deviceObj, layer),
|
|
_netLayerEntities { {*this, kInterfaceIndex} }
|
|
{
|
|
}
|
|
|
|
NetworkLayerEntity& NetworkLayerDevice::getInterface()
|
|
{
|
|
return _netLayerEntities[kInterfaceIndex];
|
|
}
|
|
|
|
void NetworkLayerDevice::dataIndividualRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu)
|
|
{
|
|
NPDU& npdu = tpdu.frame().npdu();
|
|
|
|
if (hopType == UnlimitedRouting)
|
|
npdu.hopCount(7);
|
|
else
|
|
npdu.hopCount(hopCount());
|
|
|
|
//if (tpdu.apdu().length() > 0)
|
|
//{
|
|
// print.print("-> NL ");
|
|
// tpdu.apdu().printPDU();
|
|
//}
|
|
LOGGER.info("dataIndividualRequest %S", npdu.toString());
|
|
_netLayerEntities[kInterfaceIndex].sendDataRequest(npdu, ack, destination, _deviceObj.individualAddress(), priority, IndividualAddress, Broadcast);
|
|
}
|
|
|
|
void NetworkLayerDevice::dataGroupRequest(AckType ack, uint16_t destination, HopCountType hopType, Priority priority, TPDU& tpdu)
|
|
{
|
|
NPDU& npdu = tpdu.frame().npdu();
|
|
|
|
if (hopType == UnlimitedRouting)
|
|
npdu.hopCount(7);
|
|
else
|
|
npdu.hopCount(hopCount());
|
|
|
|
LOGGER.info("dataGroupRequest %S", npdu.toString());
|
|
_netLayerEntities[kInterfaceIndex].sendDataRequest(npdu, ack, destination, _deviceObj.individualAddress(), priority, GroupAddress, Broadcast);
|
|
}
|
|
|
|
void NetworkLayerDevice::dataBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu)
|
|
{
|
|
NPDU& npdu = tpdu.frame().npdu();
|
|
|
|
if (hopType == UnlimitedRouting)
|
|
npdu.hopCount(7);
|
|
else
|
|
npdu.hopCount(hopCount());
|
|
|
|
LOGGER.info("dataBroadcastRequest %S", npdu.toString());
|
|
_netLayerEntities[kInterfaceIndex].sendDataRequest(npdu, ack, 0, _deviceObj.individualAddress(), priority, GroupAddress, Broadcast);
|
|
}
|
|
|
|
void NetworkLayerDevice::dataSystemBroadcastRequest(AckType ack, HopCountType hopType, Priority priority, TPDU& tpdu)
|
|
{
|
|
// for closed media like TP1 and IP
|
|
bool isClosedMedium = (_netLayerEntities[kInterfaceIndex].mediumType() == DptMedium::KNX_TP1) || (_netLayerEntities[kInterfaceIndex].mediumType() == DptMedium::KNX_IP);
|
|
SystemBroadcast broadcastType = (isClosedMedium && isApciSystemBroadcast(tpdu.apdu()) ? Broadcast : SysBroadcast);
|
|
|
|
NPDU& npdu = tpdu.frame().npdu();
|
|
|
|
if (hopType == UnlimitedRouting)
|
|
npdu.hopCount(7);
|
|
else
|
|
npdu.hopCount(hopCount());
|
|
|
|
LOGGER.info("dataSystemBroadcastRequest %S", npdu.toString());
|
|
_netLayerEntities[kInterfaceIndex].sendDataRequest(npdu, ack, 0, _deviceObj.individualAddress(), priority, GroupAddress, broadcastType);
|
|
}
|
|
|
|
void NetworkLayerDevice::dataIndication(AckType ack, AddressType addrType, uint16_t destination, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("dataIndication %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
|
|
if (addrType == IndividualAddress)
|
|
{
|
|
if (destination != _deviceObj.individualAddress())
|
|
return;
|
|
|
|
_transportLayer.dataIndividualIndication(destination, hopType, priority, source, npdu.tpdu());
|
|
return;
|
|
}
|
|
|
|
// group-address type
|
|
if (destination != 0)
|
|
{
|
|
_transportLayer.dataGroupIndication(destination, hopType, priority, source, npdu.tpdu());
|
|
return;
|
|
}
|
|
}
|
|
|
|
void NetworkLayerDevice::dataConfirm(AckType ack, AddressType addressType, uint16_t destination, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("dataConfirm %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
|
|
if (addressType == IndividualAddress)
|
|
{
|
|
_transportLayer.dataIndividualConfirm(ack, destination, hopType, priority, npdu.tpdu(), status);
|
|
return;
|
|
}
|
|
|
|
// group-address type
|
|
if (destination != 0)
|
|
{
|
|
_transportLayer.dataGroupConfirm(ack, source, destination, hopType, priority, npdu.tpdu(), status);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void NetworkLayerDevice::broadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("broadcastIndication %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
DptMedium mediumType = _netLayerEntities[srcIfIdx].mediumType();
|
|
|
|
// for closed media like TP1 and IP there is no system broadcast
|
|
// however we must be able to access those APCI via broadcast mode
|
|
// so we "translate" it to system broadcast like a coupler does when routing
|
|
// between closed and open media
|
|
if ( ((mediumType == DptMedium::KNX_TP1) || (mediumType == DptMedium::KNX_IP)) &&
|
|
isApciSystemBroadcast(npdu.tpdu().apdu()))
|
|
{
|
|
npdu.frame().systemBroadcast(SysBroadcast);
|
|
_transportLayer.dataSystemBroadcastIndication(hopType, priority, source, npdu.tpdu());
|
|
return;
|
|
}
|
|
|
|
_transportLayer.dataBroadcastIndication(hopType, priority, source, npdu.tpdu());
|
|
}
|
|
|
|
void NetworkLayerDevice::broadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("broadcastConfirm %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
_transportLayer.dataBroadcastConfirm(ack, hopType, priority, npdu.tpdu(), status);
|
|
}
|
|
|
|
void NetworkLayerDevice::systemBroadcastIndication(AckType ack, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("systemBroadcastIndication %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
_transportLayer.dataSystemBroadcastIndication(hopType, priority, source, npdu.tpdu());
|
|
}
|
|
|
|
void NetworkLayerDevice::systemBroadcastConfirm(AckType ack, FrameFormat format, Priority priority, uint16_t source, NPDU& npdu, bool status, uint8_t srcIfIdx)
|
|
{
|
|
LOGGER.info("systemBroadcastConfirm %S", npdu.toString());
|
|
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
|
_transportLayer.dataSystemBroadcastConfirm(ack, hopType, npdu.tpdu(), priority, status);
|
|
}
|