Merge pull request #245 from OpenKNX/improve_ipDataLinkLayer_limit

Improve ip data link layer send limit
This commit is contained in:
thelsing 2023-05-29 19:09:33 +02:00 committed by GitHub
commit dd092dbba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 3 deletions

View File

@ -26,10 +26,10 @@ IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipPara
bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
{
KnxIpRoutingIndication packet(frame);
bool success = sendBytes(packet.data(), packet.totalLength());
// only send 50 packet per second: see KNX 3.2.6 p.6
delay(20);
if(isSendLimitReached())
return false;
bool success = sendBytes(packet.data(), packet.totalLength());
dataConReceived(frame, success);
return success;
}
@ -112,4 +112,50 @@ bool IpDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length)
return _platform.sendBytesMultiCast(bytes, length);
}
bool IpDataLinkLayer::isSendLimitReached()
{
uint32_t curTime = millis() / 100;
// check if the countbuffer must be adjusted
if(_frameCountTimeBase >= curTime)
{
uint32_t timeBaseDiff = _frameCountTimeBase - curTime;
if(timeBaseDiff > 10)
timeBaseDiff = 10;
for(int i = 0; i < timeBaseDiff ; i++)
{
_frameCountBase++;
_frameCountBase = _frameCountBase % 10;
_frameCount[_frameCountBase] = 0;
}
_frameCountTimeBase = curTime;
}
else // _frameCountTimeBase < curTime => millis overflow, reset
{
for(int i = 0; i < 10 ; i++)
_frameCount[i] = 0;
_frameCountBase = 0;
_frameCountTimeBase = curTime;
}
//check if we are over the limit
uint16_t sum = 0;
for(int i = 0; i < 10 ; i++)
sum += _frameCount[i];
if(sum > 50)
{
println("Dropping packet due to 50p/s limit");
return true; // drop packet
}
else
{
_frameCount[_frameCountBase]++;
//print("sent packages in last 1000ms: ");
//print(sum);
//print(" curTime: ");
//println(curTime);
return false;
}
}
#endif

View File

@ -22,8 +22,12 @@ class IpDataLinkLayer : public DataLinkLayer
private:
bool _enabled = false;
uint8_t _frameCount[10] = {0,0,0,0,0,0,0,0,0,0};
uint8_t _frameCountBase = 0;
uint32_t _frameCountTimeBase = 0;
bool sendFrame(CemiFrame& frame);
bool sendBytes(uint8_t* buffer, uint16_t length);
bool isSendLimitReached();
IpParameterObject& _ipParameters;
};