aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2016-01-19 15:53:30 +0100
committerJacob Erlbeck <jerlbeck@sysmocom.de>2016-02-08 00:45:36 +0100
commit36df7740dd7f81fe36d35e808cc53f518f4e360e (patch)
treec204fcc8e691a99ce2a42eb7b7491bea6248c01c /src
parent08c72fb4a91c267410535be26d2bb399914ff6d4 (diff)
edge: Make window size configurable
Currently the window size is fixed to 64 even for EGPRS. Support dynamic window sizes depending on the number of PDCH. The WS can be set to b + f * N_PDCH. If the result is not valid according to TS 44.060, Table 9.1.9.2.1, the value will be corrected to use the next lower valid value (or 64). The following VTY commands are added (config-pcu node): window-size <0-1024> set base (b) value and leave f unchanged window-size <0-1024> <0-256> set base (b) and factor (f) Sponsored-by: On-Waves ehf
Diffstat (limited to 'src')
-rw-r--r--src/bts.h4
-rw-r--r--src/encoding.cpp9
-rw-r--r--src/pcu_main.cpp4
-rw-r--r--src/pcu_vty.c24
-rw-r--r--src/pcu_vty_functions.cpp3
-rw-r--r--src/tbf.cpp18
6 files changed, 56 insertions, 6 deletions
diff --git a/src/bts.h b/src/bts.h
index c6247be..14b6c1f 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -188,8 +188,8 @@ struct gprs_rlcmac_bts {
uint8_t cs_adj_lower_limit;
struct {int16_t low; int16_t high;} cs_lqual_ranges[4];
uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */
- uint16_t egprs_ws_base;
- uint16_t egprs_ws_lin;
+ uint16_t ws_base;
+ uint16_t ws_pdch; /* increase WS by this value per PDCH */
/* State for dynamic algorithm selection */
int multislot_disabled;
diff --git a/src/encoding.cpp b/src/encoding.cpp
index 9def283..a26a5db 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -208,13 +208,14 @@ void Encoding::write_packet_uplink_assignment(
}
} else { /* EPGRS */
+ unsigned int ws_enc = (tbf->m_window.ws() - 64) / 32;
bitvec_write_field(dest, wp,0x1,1); // Message escape
bitvec_write_field(dest, wp,0x0,2); // EGPRS message contents
bitvec_write_field(dest, wp,0x0,1); // No CONTENTION_RESOLUTION_TLLI
bitvec_write_field(dest, wp,0x0,1); // No COMPACT reduced MA
bitvec_write_field(dest, wp,tbf->current_cs().to_num()-1, 4); // EGPRS Modulation and Coding IE
bitvec_write_field(dest, wp,0x0,1); // No RESEGMENT
- bitvec_write_field(dest, wp,0x0,5); // EGPRS Window Size = 64
+ bitvec_write_field(dest, wp,ws_enc,5); // EGPRS Window Size
bitvec_write_field(dest, wp,0x0,1); // No Access Technologies Request
bitvec_write_field(dest, wp,0x0,1); // No ARAC RETRANSMISSION REQUEST
bitvec_write_field(dest, wp,0x1,1); // TLLI_BLOCK_CHANNEL_CODING
@@ -282,6 +283,7 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block,
PDA_AdditionsR99_t *pda_r99;
uint8_t tn;
+ unsigned int ws_enc;
block->PAYLOAD_TYPE = 0x1; // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
block->RRBP = 0x0; // N+13
@@ -348,10 +350,13 @@ void Encoding::write_packet_downlink_assignment(RlcMacDownlink_t * block,
block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x0; // AdditionsR99 = off
return;
}
+
+ ws_enc = (tbf->window()->ws() - 64) / 32;
+
block->u.Packet_Downlink_Assignment.Exist_AdditionsR99 = 0x1; // AdditionsR99 = on
pda_r99 = &block->u.Packet_Downlink_Assignment.AdditionsR99;
pda_r99->Exist_EGPRS_Params = 1;
- pda_r99->EGPRS_WindowSize = 0; /* 64, see TS 44.060, table 12.5.2.1 */
+ pda_r99->EGPRS_WindowSize = ws_enc; /* see TS 44.060, table 12.5.2.1 */
pda_r99->LINK_QUALITY_MEASUREMENT_MODE = 0x0; /* no meas, see TS 44.060, table 11.2.7.2 */
pda_r99->Exist_BEP_PERIOD2 = 0; /* No extra EGPRS BEP PERIOD */
pda_r99->Exist_Packet_Extended_Timing_Advance = 0;
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 39de055..51a4eee 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -193,6 +193,10 @@ int main(int argc, char *argv[])
bts->cs_lqual_ranges[3].high = 256;
bts->cs_downgrade_threshold = 200;
+ /* TODO: increase them when CRBB decoding is implemented */
+ bts->ws_base = 64;
+ bts->ws_pdch = 0;
+
bts->llc_codel_interval_msec = LLC_CODEL_USE_DEFAULT;
bts->dl_tbf_idle_msec = 2000;
bts->llc_idle_ack_csec = 10;
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 97be4c7..b5ee1b5 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -118,6 +118,9 @@ static int config_write_pcu(struct vty *vty)
bts->max_mcs_ul, VTY_NEWLINE);
}
+ vty_out(vty, " window-size %d %d%s", bts->ws_base, bts->ws_pdch,
+ VTY_NEWLINE);
+
if (bts->force_llc_lifetime == 0xffff)
vty_out(vty, " queue lifetime infinite%s", VTY_NEWLINE);
else if (bts->force_llc_lifetime)
@@ -437,6 +440,26 @@ DEFUN(cfg_pcu_no_mcs_max,
return CMD_SUCCESS;
}
+DEFUN(cfg_pcu_window_size,
+ cfg_pcu_window_size_cmd,
+ "window-size <0-1024> [<0-256>]",
+ "Window size configuration (b + N_PDCH * f)\n"
+ "Base value (b)\n"
+ "Factor for number of PDCH (f)")
+{
+ struct gprs_rlcmac_bts *bts = bts_main_data();
+ uint16_t b = atoi(argv[0]);
+
+ bts->ws_base = b;
+ if (argc > 1) {
+ uint16_t f = atoi(argv[1]);
+ bts->ws_pdch = f;
+ }
+
+ return CMD_SUCCESS;
+}
+
+
#define QUEUE_STR "Packet queue options\n"
#define LIFETIME_STR "Set lifetime limit of LLC frame in centi-seconds " \
"(overrides the value given by SGSN)\n"
@@ -892,6 +915,7 @@ int pcu_vty_init(const struct log_info *cat)
install_element(PCU_NODE, &cfg_pcu_cs_lqual_ranges_cmd);
install_element(PCU_NODE, &cfg_pcu_mcs_max_cmd);
install_element(PCU_NODE, &cfg_pcu_no_mcs_max_cmd);
+ install_element(PCU_NODE, &cfg_pcu_window_size_cmd);
install_element(PCU_NODE, &cfg_pcu_queue_lifetime_cmd);
install_element(PCU_NODE, &cfg_pcu_queue_lifetime_inf_cmd);
install_element(PCU_NODE, &cfg_pcu_no_queue_lifetime_cmd);
diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp
index 2f7cb02..66994de 100644
--- a/src/pcu_vty_functions.cpp
+++ b/src/pcu_vty_functions.cpp
@@ -56,7 +56,8 @@ static void tbf_print_vty_info(struct vty *vty, gprs_rlcmac_tbf *tbf)
if (tbf->pdch[i])
vty_out(vty, "%d ", i);
}
- vty_out(vty, " CS=%s%s%s", tbf->current_cs().name(),
+ vty_out(vty, " CS=%s WS=%d%s%s",
+ tbf->current_cs().name(), tbf->window()->ws(),
VTY_NEWLINE, VTY_NEWLINE);
}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 9f19c9b..c852d66 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -28,6 +28,7 @@
#include <gprs_bssgp_pcu.h>
#include <gprs_ms.h>
#include <decoding.h>
+#include <pcu_utils.h>
extern "C" {
#include <osmocom/core/msgb.h>
@@ -634,6 +635,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts,
if (egprs_ms_class > 0 && bts->egprs_enabled) {
tbf->enable_egprs();
tbf->m_window.set_sns(RLC_EGPRS_SNS);
+ /* TODO: Allow bigger UL windows when CRBB encoding is supported */
tbf->m_window.set_ws(RLC_EGPRS_MIN_WS);
setup_egprs_mode(bts, ms);
LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n",
@@ -714,7 +716,6 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
if (egprs_ms_class > 0 && bts->egprs_enabled) {
tbf->enable_egprs();
tbf->m_window.set_sns(RLC_EGPRS_SNS);
- tbf->m_window.set_ws(RLC_EGPRS_MIN_WS);
setup_egprs_mode(bts, ms);
LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n",
tbf->name(), GprsCodingScheme::modeName(ms->mode()));
@@ -727,6 +728,21 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts,
return NULL;
}
+ if (tbf->is_egprs_enabled()) {
+ unsigned int num_pdch = pcu_bitcount(tbf->dl_slots());
+ unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch;
+ ws = (ws / 32) * 32;
+ ws = OSMO_MAX(64, ws);
+ if (num_pdch == 1)
+ ws = OSMO_MIN(192, ws);
+ else
+ ws = OSMO_MIN(128 * num_pdch, ws);
+
+ LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n",
+ tbf->name(), ws);
+ tbf->m_window.set_ws(ws);
+ }
+
llist_add(&tbf->list(), &bts->bts->dl_tbfs());
tbf->bts->tbf_dl_created();