From 66ba0844be5058032cb31c6ee3e31428417b171f Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Tue, 21 Jul 2015 17:25:52 +0200 Subject: bssgp: Use measured leak rate for flow control (EXPERIMENTAL) THIS IS EXPERIMENTAL, DO NOT USE IN PRODUCTION The leak rate sent to the SGSN does not reflect the current CS level, lost frames, and control message overhead. Use the ratio between sent blocks and successfully received bytes to derive the net leak rate. TODO: - The values are not stable, possibly resulting from interference with the sampling rate or from the interval between send and receive if they fall into different sampling intervals. - Perhaps the rate can be computed from sent data bytes / sent data frames or from the average packet size and the global nack rate. --- src/gprs_bssgp_pcu.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/gprs_bssgp_pcu.cpp') diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 7601b218..f909aea4 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -586,6 +586,23 @@ static uint32_t get_and_reset_avg_queue_delay(void) return avg_delay_ms; } +static int get_and_reset_measured_leak_rate(int num_pdch) +{ + int rate; /* byte per second */ + + if (the_pcu.queue_frames_sent == 0) + return -1; + + /* 20ms/num_pdch is the average RLC block duration */ + rate = the_pcu.queue_bytes_recv * 1000 * num_pdch / + (20 * the_pcu.queue_frames_sent); + + the_pcu.queue_frames_sent = 0; + the_pcu.queue_bytes_recv = 0; + + return rate; +} + int gprs_bssgp_tx_fc_bvc(void) { struct gprs_rlcmac_bts *bts; @@ -624,6 +641,20 @@ int gprs_bssgp_tx_fc_bvc(void) ms_bucket_size = bts->fc_ms_bucket_size; ms_leak_rate = bts->fc_ms_leak_rate; + if (leak_rate == 0) { + int meas_rate; + + if (num_pdch < 0) + num_pdch = count_pdch(bts); + + meas_rate = get_and_reset_measured_leak_rate(num_pdch); + if (meas_rate > 0) { + leak_rate = meas_rate; + LOGP(DBSSGP, LOGL_DEBUG, + "Measured BVC leak rate = %d\n", leak_rate); + } + } + if (leak_rate == 0) { if (num_pdch < 0) num_pdch = count_pdch(bts); @@ -823,6 +854,16 @@ struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void) return the_pcu.bctx; } +void gprs_bssgp_update_frames_sent() +{ + the_pcu.queue_frames_sent += 1; +} + +void gprs_bssgp_update_bytes_received(unsigned bytes_recv) +{ + the_pcu.queue_bytes_recv += bytes_recv; +} + void gprs_bssgp_update_queue_delay(const struct timeval *tv_recv, const struct timeval *tv_now) { -- cgit v1.2.3