mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	improve the implementation of the 50 packet / second limit
delay knx.loop by 20ms has ugly side effects. count the frames in 100ms chunks to allow more than 5 packets per 100ms drop packet if over the limit.
This commit is contained in:
		
							parent
							
								
									4cdf6d4ffe
								
							
						
					
					
						commit
						1f3a5fe5a9
					
				@ -26,10 +26,11 @@ IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipPara
 | 
			
		||||
bool IpDataLinkLayer::sendFrame(CemiFrame& frame)
 | 
			
		||||
{
 | 
			
		||||
    KnxIpRoutingIndication packet(frame);
 | 
			
		||||
    
 | 
			
		||||
    if(countFrames())
 | 
			
		||||
        return false;
 | 
			
		||||
    bool success = sendBytes(packet.data(), packet.totalLength());
 | 
			
		||||
    // only send 50 packet per second: see KNX 3.2.6 p.6
 | 
			
		||||
    delay(20);
 | 
			
		||||
    //delay(20);
 | 
			
		||||
    dataConReceived(frame, success);
 | 
			
		||||
    return success;
 | 
			
		||||
}
 | 
			
		||||
@ -112,4 +113,55 @@ bool IpDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length)
 | 
			
		||||
 | 
			
		||||
    return _platform.sendBytesMultiCast(bytes, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IpDataLinkLayer::countFrames()
 | 
			
		||||
{
 | 
			
		||||
    // _frameCount[_frameCountBase] => frames sent since now and millis() % 100
 | 
			
		||||
    // _frameCount[(_frameCountBase - 1) % 10] => frames sent since millis() % 100 and millis() % 100 - 100
 | 
			
		||||
    // _frameCount[(_frameCountBase - 2) % 10] => frames sent since millis() % 100 - 100 and millis() % 100 - 200
 | 
			
		||||
    // ... => information about the number of frames sent in the last 1000 ms
 | 
			
		||||
 | 
			
		||||
    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 false;   // drop packet
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        _frameCount[_frameCountBase]++;
 | 
			
		||||
        print("go for it: ");
 | 
			
		||||
        print(sum);
 | 
			
		||||
        print(" curTime: ");
 | 
			
		||||
        println(curTime);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -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 countFrames();
 | 
			
		||||
 | 
			
		||||
    IpParameterObject& _ipParameters;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user