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