mirror of
https://github.com/thelsing/knx.git
synced 2025-09-05 17:50:22 +02:00
Filter table setting/clearing
This commit is contained in:
parent
592e4bb2a8
commit
7bedb0e672
@ -8,6 +8,8 @@
|
|||||||
#include "callback_property.h"
|
#include "callback_property.h"
|
||||||
#include "function_property.h"
|
#include "function_property.h"
|
||||||
|
|
||||||
|
static constexpr uint16_t kFilterTableSize = 65536 / 8; // Each group address is represented by one bit
|
||||||
|
|
||||||
enum RouteTableServices
|
enum RouteTableServices
|
||||||
{
|
{
|
||||||
ClearRoutingTable = 0x01, // no info bytes
|
ClearRoutingTable = 0x01, // no info bytes
|
||||||
@ -98,9 +100,146 @@ const uint8_t* RouterObject::restore(const uint8_t* buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterObject::commandClearSetRoutingTable(bool bitIsSet)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < kFilterTableSize; i++)
|
||||||
|
{
|
||||||
|
data()[i] = bitIsSet ? 0xFF : 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RouterObject::statusClearSetRoutingTable(bool bitIsSet)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < kFilterTableSize; i++)
|
||||||
|
{
|
||||||
|
if (data()[i] != (bitIsSet ? 0xFF : 0x00))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RouterObject::commandClearSetGroupAddress(uint16_t startAddress, uint16_t endAddress, bool bitIsSet)
|
||||||
|
{
|
||||||
|
uint16_t startOctet = startAddress / 8;
|
||||||
|
uint8_t startBitPosition = startAddress % 8;
|
||||||
|
uint16_t endOctet = endAddress / 8;
|
||||||
|
uint8_t endBitPosition = endAddress % 8;
|
||||||
|
|
||||||
|
if (startOctet == endOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = startBitPosition; bitPos <= endBitPosition; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
data()[startOctet] |= 1 << bitPos;
|
||||||
|
else
|
||||||
|
data()[startOctet] &= ~(1 << bitPos);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = startOctet; i <= endOctet; i++)
|
||||||
|
{
|
||||||
|
if (i == startOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = startBitPosition; bitPos <= 7; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
data()[i] |= 1 << bitPos;
|
||||||
|
else
|
||||||
|
data()[i] &= ~(1 << bitPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i == endOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = 0; bitPos <= endBitPosition; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
data()[i] |= 1 << bitPos;
|
||||||
|
else
|
||||||
|
data()[i] &= ~(1 << bitPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
data()[i] = 0xFF;
|
||||||
|
else
|
||||||
|
data()[i] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RouterObject::statusClearSetGroupAddress(uint16_t startAddress, uint16_t endAddress, bool bitIsSet)
|
||||||
|
{
|
||||||
|
uint16_t startOctet = startAddress / 8;
|
||||||
|
uint8_t startBitPosition = startAddress % 8;
|
||||||
|
uint16_t endOctet = endAddress / 8;
|
||||||
|
uint8_t endBitPosition = endAddress % 8;
|
||||||
|
|
||||||
|
if (startOctet == endOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = startBitPosition; bitPos <= endBitPosition; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
{
|
||||||
|
if ((data()[startOctet] & (1 << bitPos)) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((data()[startOctet] & (1 << bitPos)) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = startOctet; i <= endOctet; i++)
|
||||||
|
{
|
||||||
|
if (i == startOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = startBitPosition; bitPos <= 7; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
{
|
||||||
|
if ((data()[i] & (1 << bitPos)) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((data()[i] & (1 << bitPos)) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i == endOctet)
|
||||||
|
{
|
||||||
|
for (uint8_t bitPos = 0; bitPos <= endBitPosition; bitPos++)
|
||||||
|
{
|
||||||
|
if (bitIsSet)
|
||||||
|
{
|
||||||
|
if ((data()[i] & (1 << bitPos)) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((data()[i] & (1 << bitPos)) != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data()[i] != (bitIsSet ? 0xFF : 0x00))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void RouterObject::functionRouteTableControl(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
void RouterObject::functionRouteTableControl(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
{
|
{
|
||||||
bool isError = false;
|
|
||||||
RouteTableServices srvId = (RouteTableServices) data[1];
|
RouteTableServices srvId = (RouteTableServices) data[1];
|
||||||
|
|
||||||
// Filter Table Realization Type 3
|
// Filter Table Realization Type 3
|
||||||
@ -116,10 +255,45 @@ void RouterObject::functionRouteTableControl(bool isCommand, uint8_t* data, uint
|
|||||||
switch(srvId)
|
switch(srvId)
|
||||||
{
|
{
|
||||||
case ClearRoutingTable:
|
case ClearRoutingTable:
|
||||||
|
commandClearSetRoutingTable(false);
|
||||||
|
resultData[0] = ReturnCodes::Success;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
resultLength = 2;
|
||||||
|
return;
|
||||||
case SetRoutingTable:
|
case SetRoutingTable:
|
||||||
|
commandClearSetRoutingTable(true);
|
||||||
|
resultData[0] = ReturnCodes::Success;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
resultLength = 2;
|
||||||
|
return;
|
||||||
case ClearGroupAddress:
|
case ClearGroupAddress:
|
||||||
case SetGroupAddress: break;
|
{
|
||||||
default: isError = true;
|
uint16_t startAddress;
|
||||||
|
uint16_t endAddress;
|
||||||
|
popWord(startAddress, &data[2]);
|
||||||
|
popWord(endAddress, &data[4]);
|
||||||
|
commandClearSetGroupAddress(startAddress, endAddress, false);
|
||||||
|
resultData[0] = ReturnCodes::Success;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
pushWord(startAddress, &resultData[2]);
|
||||||
|
pushWord(endAddress, &resultData[4]);
|
||||||
|
resultLength = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SetGroupAddress:
|
||||||
|
{
|
||||||
|
uint16_t startAddress;
|
||||||
|
uint16_t endAddress;
|
||||||
|
popWord(startAddress, &data[2]);
|
||||||
|
popWord(endAddress, &data[4]);
|
||||||
|
commandClearSetGroupAddress(startAddress, endAddress, true);
|
||||||
|
resultData[0] = ReturnCodes::Success;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
pushWord(startAddress, &resultData[2]);
|
||||||
|
pushWord(endAddress, &resultData[4]);
|
||||||
|
resultLength = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -127,19 +301,48 @@ void RouterObject::functionRouteTableControl(bool isCommand, uint8_t* data, uint
|
|||||||
switch(srvId)
|
switch(srvId)
|
||||||
{
|
{
|
||||||
case ClearRoutingTable:
|
case ClearRoutingTable:
|
||||||
|
resultData[0] = statusClearSetRoutingTable(false) ? ReturnCodes::Success : ReturnCodes::GenericError;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
resultLength = 2;
|
||||||
|
return;
|
||||||
case SetRoutingTable:
|
case SetRoutingTable:
|
||||||
|
resultData[0] = statusClearSetRoutingTable(true) ? ReturnCodes::Success : ReturnCodes::GenericError;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
resultLength = 2;
|
||||||
|
return;
|
||||||
case ClearGroupAddress:
|
case ClearGroupAddress:
|
||||||
case SetGroupAddress: break;
|
{
|
||||||
default: isError = true;
|
uint16_t startAddress;
|
||||||
|
uint16_t endAddress;
|
||||||
|
popWord(startAddress, &data[2]);
|
||||||
|
popWord(endAddress, &data[4]);
|
||||||
|
resultData[0] = statusClearSetGroupAddress(startAddress, endAddress, false) ? ReturnCodes::Success : ReturnCodes::GenericError;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
pushWord(startAddress, &resultData[2]);
|
||||||
|
pushWord(endAddress, &resultData[4]);
|
||||||
|
resultLength = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case SetGroupAddress:
|
||||||
|
{
|
||||||
|
uint16_t startAddress;
|
||||||
|
uint16_t endAddress;
|
||||||
|
popWord(startAddress, &data[2]);
|
||||||
|
popWord(endAddress, &data[4]);
|
||||||
|
resultData[0] = statusClearSetGroupAddress(startAddress, endAddress, true) ? ReturnCodes::Success : ReturnCodes::GenericError;
|
||||||
|
resultData[1] = srvId;
|
||||||
|
pushWord(startAddress, &resultData[2]);
|
||||||
|
pushWord(endAddress, &resultData[4]);
|
||||||
|
resultLength = 6;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isError)
|
// We should not get here
|
||||||
{
|
|
||||||
resultData[0] = ReturnCodes::GenericError;
|
resultData[0] = ReturnCodes::GenericError;
|
||||||
resultData[1] = srvId;
|
resultData[1] = srvId;
|
||||||
resultLength = 2;
|
resultLength = 2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RouterObject::functionRfEnableSbc(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
void RouterObject::functionRfEnableSbc(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||||
@ -174,7 +377,7 @@ void RouterObject::updateMcb()
|
|||||||
{
|
{
|
||||||
uint8_t mcb[propertySize(PID_MCB_TABLE)];
|
uint8_t mcb[propertySize(PID_MCB_TABLE)];
|
||||||
|
|
||||||
static constexpr uint32_t segmentSize = 8192;
|
static constexpr uint32_t segmentSize = kFilterTableSize;
|
||||||
uint16_t crc16 = crc16Ccitt(data(), segmentSize);
|
uint16_t crc16 = crc16Ccitt(data(), segmentSize);
|
||||||
|
|
||||||
pushInt(segmentSize, &mcb[0]); // Segment size
|
pushInt(segmentSize, &mcb[0]); // Segment size
|
||||||
|
@ -30,6 +30,11 @@ private:
|
|||||||
void functionRouteTableControl(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength);
|
void functionRouteTableControl(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength);
|
||||||
void functionRfEnableSbc(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength);
|
void functionRfEnableSbc(bool isCommand, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength);
|
||||||
|
|
||||||
|
void commandClearSetRoutingTable(bool bitIsSet);
|
||||||
|
bool statusClearSetRoutingTable(bool bitIsSet);
|
||||||
|
void commandClearSetGroupAddress(uint16_t startAddress, uint16_t endAddress, bool bitIsSet);
|
||||||
|
bool statusClearSetGroupAddress(uint16_t startAddress, uint16_t endAddress, bool bitIsSet);
|
||||||
|
|
||||||
void updateMcb();
|
void updateMcb();
|
||||||
|
|
||||||
bool _rfSbcRoutingEnabled = false;
|
bool _rfSbcRoutingEnabled = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user