@@ -508,13 +508,16 @@ struct reliable_endpoint_t
508
508
struct reliable_config_t config ;
509
509
double time ;
510
510
float rtt ;
511
+ float rtt_min ;
512
+ float jitter ;
511
513
float packet_loss ;
512
514
float sent_bandwidth_kbps ;
513
515
float received_bandwidth_kbps ;
514
516
float acked_bandwidth_kbps ;
515
517
int num_acks ;
516
518
uint16_t * acks ;
517
519
uint16_t sequence ;
520
+ float * rtt_history_buffer ;
518
521
struct reliable_sequence_buffer_t * sent_packets ;
519
522
struct reliable_sequence_buffer_t * received_packets ;
520
523
struct reliable_sequence_buffer_t * fragment_reassembly ;
@@ -556,9 +559,10 @@ void reliable_default_config( struct reliable_config_t * config )
556
559
config -> received_packets_buffer_size = 256 ;
557
560
config -> fragment_reassembly_buffer_size = 64 ;
558
561
config -> rtt_smoothing_factor = 0.0025f ;
562
+ config -> rtt_history_size = 512 ;
559
563
config -> packet_loss_smoothing_factor = 0.1f ;
560
564
config -> bandwidth_smoothing_factor = 0.1f ;
561
- config -> packet_header_size = 28 ; // note: UDP over IPv4 = 20 + 8 bytes, UDP over IPv6 = 40 + 8 bytes
565
+ config -> packet_header_size = 28 ; // note: UDP over IPv4 = 20 + 8 bytes, UDP over IPv6 = 40 + 8 bytes
562
566
}
563
567
564
568
struct reliable_endpoint_t * reliable_endpoint_create ( struct reliable_config_t * config , double time )
@@ -574,6 +578,7 @@ struct reliable_endpoint_t * reliable_endpoint_create( struct reliable_config_t
574
578
reliable_assert ( config -> received_packets_buffer_size > 0 );
575
579
reliable_assert ( config -> transmit_packet_function != NULL );
576
580
reliable_assert ( config -> process_packet_function != NULL );
581
+ reliable_assert ( config -> rtt_history_size > 0 );
577
582
578
583
void * allocator_context = config -> allocator_context ;
579
584
void * (* allocate_function )(void * ,size_t ) = config -> allocate_function ;
@@ -601,7 +606,7 @@ struct reliable_endpoint_t * reliable_endpoint_create( struct reliable_config_t
601
606
endpoint -> config = * config ;
602
607
endpoint -> time = time ;
603
608
604
- endpoint -> acks = (uint16_t * ) allocate_function ( allocator_context , config -> ack_buffer_size * sizeof ( uint16_t ) );
609
+ endpoint -> acks = (uint16_t * ) allocate_function ( allocator_context , config -> ack_buffer_size * sizeof (uint16_t ) );
605
610
606
611
endpoint -> sent_packets = reliable_sequence_buffer_create ( config -> sent_packets_buffer_size ,
607
612
sizeof ( struct reliable_sent_packet_data_t ),
@@ -621,7 +626,14 @@ struct reliable_endpoint_t * reliable_endpoint_create( struct reliable_config_t
621
626
allocate_function ,
622
627
free_function );
623
628
624
- memset ( endpoint -> acks , 0 , config -> ack_buffer_size * sizeof ( uint16_t ) );
629
+ endpoint -> rtt_history_buffer = (float * ) allocate_function ( allocator_context , config -> rtt_history_size * sizeof (float ) );
630
+
631
+ for ( int i = 0 ; i < config -> rtt_history_size ; i ++ )
632
+ {
633
+ endpoint -> rtt_history_buffer [i ] = -1.0f ;
634
+ }
635
+
636
+ memset ( endpoint -> acks , 0 , config -> ack_buffer_size * sizeof (uint16_t ) );
625
637
626
638
return endpoint ;
627
639
}
@@ -632,6 +644,8 @@ void reliable_endpoint_destroy( struct reliable_endpoint_t * endpoint )
632
644
reliable_assert ( endpoint -> acks );
633
645
reliable_assert ( endpoint -> sent_packets );
634
646
reliable_assert ( endpoint -> received_packets );
647
+ reliable_assert ( endpoint -> fragment_reassembly );
648
+ reliable_assert ( endpoint -> rtt_history_buffer );
635
649
636
650
int i ;
637
651
for ( i = 0 ; i < endpoint -> config .fragment_reassembly_buffer_size ; ++ i )
@@ -652,6 +666,8 @@ void reliable_endpoint_destroy( struct reliable_endpoint_t * endpoint )
652
666
reliable_sequence_buffer_destroy ( endpoint -> received_packets );
653
667
reliable_sequence_buffer_destroy ( endpoint -> fragment_reassembly );
654
668
669
+ endpoint -> free_function ( endpoint -> allocator_context , endpoint -> rtt_history_buffer );
670
+
655
671
endpoint -> free_function ( endpoint -> allocator_context , endpoint );
656
672
}
657
673
@@ -1141,8 +1157,14 @@ void reliable_endpoint_receive_packet( struct reliable_endpoint_t * endpoint, ui
1141
1157
endpoint -> counters [RELIABLE_ENDPOINT_COUNTER_NUM_PACKETS_ACKED ]++ ;
1142
1158
sent_packet_data -> acked = 1 ;
1143
1159
1144
- float rtt = (float ) ( endpoint -> time - sent_packet_data -> time ) * 1000.0f ;
1160
+ const float rtt = (float ) ( endpoint -> time - sent_packet_data -> time ) * 1000.0f ;
1161
+
1145
1162
reliable_assert ( rtt >= 0.0 );
1163
+
1164
+ int index = ack_sequence % endpoint -> config .rtt_history_size ;
1165
+
1166
+ endpoint -> rtt_history_buffer [index ] = rtt ;
1167
+
1146
1168
if ( ( endpoint -> rtt == 0.0f && rtt > 0.0f ) || fabs ( endpoint -> rtt - rtt ) < 0.00001 )
1147
1169
{
1148
1170
endpoint -> rtt = rtt ;
@@ -1291,13 +1313,6 @@ void reliable_endpoint_reset( struct reliable_endpoint_t * endpoint )
1291
1313
{
1292
1314
reliable_assert ( endpoint );
1293
1315
1294
- endpoint -> time = 0 ;
1295
- endpoint -> rtt = 0 ;
1296
- endpoint -> packet_loss = 0 ;
1297
- endpoint -> sent_bandwidth_kbps = 0 ;
1298
- endpoint -> received_bandwidth_kbps = 0 ;
1299
- endpoint -> acked_bandwidth_kbps = 0 ;
1300
-
1301
1316
endpoint -> num_acks = 0 ;
1302
1317
endpoint -> sequence = 0 ;
1303
1318
@@ -1327,7 +1342,45 @@ void reliable_endpoint_update( struct reliable_endpoint_t * endpoint, double tim
1327
1342
reliable_assert ( endpoint );
1328
1343
1329
1344
endpoint -> time = time ;
1330
-
1345
+
1346
+ // calculate min rtt
1347
+ {
1348
+ float min_rtt = 10000.0f ;
1349
+ for ( int i = 0 ; i < endpoint -> config .rtt_history_size ; i ++ )
1350
+ {
1351
+ if ( endpoint -> rtt_history_buffer [i ] >= 0.0f && endpoint -> rtt_history_buffer [i ] < min_rtt )
1352
+ {
1353
+ min_rtt = endpoint -> rtt_history_buffer [i ];
1354
+ }
1355
+ }
1356
+ if ( min_rtt == 10000.0f )
1357
+ {
1358
+ min_rtt = 0.0f ;
1359
+ }
1360
+ endpoint -> rtt_min = min_rtt ;
1361
+ }
1362
+
1363
+ // calculate jitter
1364
+ {
1365
+ float sum = 0.0f ;
1366
+ int count = 0 ;
1367
+ for ( int i = 0 ; i < endpoint -> config .rtt_history_size ; i ++ )
1368
+ {
1369
+ if ( endpoint -> rtt_history_buffer [i ] >= 0.0f )
1370
+ {
1371
+ sum += endpoint -> rtt_history_buffer [i ];
1372
+ }
1373
+ }
1374
+ if ( count > 0 )
1375
+ {
1376
+ endpoint -> jitter = sum / (float )count ;
1377
+ }
1378
+ else
1379
+ {
1380
+ endpoint -> jitter = 0.0f ;
1381
+ }
1382
+ }
1383
+
1331
1384
// calculate packet loss
1332
1385
{
1333
1386
uint32_t base_sequence = ( endpoint -> sent_packets -> sequence - endpoint -> config .sent_packets_buffer_size + 1 ) + 0xFFFF ;
@@ -1485,6 +1538,18 @@ float reliable_endpoint_rtt( struct reliable_endpoint_t * endpoint )
1485
1538
return endpoint -> rtt ;
1486
1539
}
1487
1540
1541
+ float reliable_endpoint_rtt_min ( struct reliable_endpoint_t * endpoint )
1542
+ {
1543
+ reliable_assert ( endpoint );
1544
+ return endpoint -> rtt_min ;
1545
+ }
1546
+
1547
+ float reliable_endpoint_jitter ( struct reliable_endpoint_t * endpoint )
1548
+ {
1549
+ reliable_assert ( endpoint );
1550
+ return endpoint -> jitter ;
1551
+ }
1552
+
1488
1553
float reliable_endpoint_packet_loss ( struct reliable_endpoint_t * endpoint )
1489
1554
{
1490
1555
reliable_assert ( endpoint );
@@ -2126,7 +2191,7 @@ void test_packets()
2126
2191
uint8_t packet_data [TEST_MAX_PACKET_BYTES ];
2127
2192
uint16_t sequence = reliable_endpoint_next_packet_sequence ( context .sender );
2128
2193
int packet_bytes = generate_packet_data ( sequence , packet_data );
2129
- reliable_endpoint_send_packet ( context .receiver , packet_data , packet_bytes );
2194
+ reliable_endpoint_send_packet ( context .sender , packet_data , packet_bytes );
2130
2195
}
2131
2196
2132
2197
reliable_endpoint_update ( context .sender , time );
@@ -2234,13 +2299,15 @@ void test_sequence_buffer_rollover()
2234
2299
{
2235
2300
uint8_t packet_data [16 ];
2236
2301
int packet_bytes = sizeof ( packet_data ) / sizeof ( uint8_t );
2302
+ reliable_endpoint_next_packet_sequence ( context .sender );
2237
2303
reliable_endpoint_send_packet ( context .sender , packet_data , packet_bytes );
2238
2304
2239
2305
++ num_packets_sent ;
2240
2306
}
2241
2307
2242
2308
uint8_t packet_data [TEST_MAX_PACKET_BYTES ];
2243
2309
int packet_bytes = sizeof ( packet_data ) / sizeof ( uint8_t );
2310
+ reliable_endpoint_next_packet_sequence ( context .sender );
2244
2311
reliable_endpoint_send_packet ( context .sender , packet_data , packet_bytes );
2245
2312
++ num_packets_sent ;
2246
2313
0 commit comments