aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--tests/tbf/TbfTest.cpp56
-rw-r--r--tests/tbf/TbfTest.err75
-rw-r--r--tests/tbf/TbfTest.ok2
9 files changed, 189 insertions, 6 deletions
diff --git a/src/bts.h b/src/bts.h
index c6247be9..14b6c1f8 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 9def2831..a26a5db4 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 39de0555..51a4eeec 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 97be4c72..b5ee1b55 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 2f7cb02a..66994ded 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 9f19c9b7..c852d665 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();
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp
index 895ba8e5..c868ca2d 100644
--- a/tests/tbf/TbfTest.cpp
+++ b/tests/tbf/TbfTest.cpp
@@ -1105,6 +1105,61 @@ static void test_tbf_gprs_egprs()
gprs_bssgp_destroy();
}
+static void test_tbf_ws()
+{
+ BTS the_bts;
+ gprs_rlcmac_bts *bts;
+ uint8_t ts_no = 4;
+ uint8_t ms_class = 12;
+ gprs_rlcmac_dl_tbf *dl_tbf;
+
+ printf("=== start %s ===\n", __func__);
+
+ bts = the_bts.bts_data();
+ setup_bts(&the_bts, ts_no);
+
+ bts->ws_base = 128;
+ bts->ws_pdch = 64;
+ bts->alloc_algorithm = alloc_algorithm_b;
+ bts->trx[0].pdch[2].enable();
+ bts->trx[0].pdch[3].enable();
+ bts->trx[0].pdch[4].enable();
+ bts->trx[0].pdch[5].enable();
+
+ gprs_bssgp_create_and_connect(bts, 33001, 0, 33001,
+ 1234, 1234, 1234, 1, 1, 0, 0, 0);
+
+ /* Does no support EGPRS */
+ dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, 0, 0);
+ OSMO_ASSERT(dl_tbf != NULL);
+ fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
+ dl_tbf->dl_slots(),
+ pcu_bitcount(dl_tbf->dl_slots()),
+ dl_tbf->window()->ws());
+ OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
+ OSMO_ASSERT(dl_tbf->window()->ws() == 64);
+ tbf_free(dl_tbf);
+
+ /* EGPRS-only */
+ bts->egprs_enabled = 1;
+
+ /* Does support EGPRS */
+ dl_tbf = tbf_alloc_dl_tbf(bts, NULL, 0, ms_class, ms_class, 0);
+
+ OSMO_ASSERT(dl_tbf != NULL);
+ fprintf(stderr, "DL TBF slots: 0x%02x, N: %d, WS: %d\n",
+ dl_tbf->dl_slots(),
+ pcu_bitcount(dl_tbf->dl_slots()),
+ dl_tbf->window()->ws());
+ OSMO_ASSERT(pcu_bitcount(dl_tbf->dl_slots()) == 4);
+ OSMO_ASSERT(dl_tbf->window()->ws() == 128 + 4 * 64);
+ tbf_free(dl_tbf);
+
+ printf("=== end %s ===\n", __func__);
+
+ gprs_bssgp_destroy();
+}
+
static const struct log_info_cat default_categories[] = {
{"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
{"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_DEBUG, 1},
@@ -1163,6 +1218,7 @@ int main(int argc, char **argv)
test_tbf_dl_flow_and_rach_single_phase();
test_tbf_dl_reuse();
test_tbf_gprs_egprs();
+ test_tbf_ws();
if (getenv("TALLOC_REPORT_FULL"))
talloc_report_full(tall_pcu_ctx, stderr);
diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err
index 0ca4b829..a93d959b 100644
--- a/tests/tbf/TbfTest.err
+++ b/tests/tbf/TbfTest.err
@@ -3041,3 +3041,78 @@ msg block (BSN 10, CS-1): 0f 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54
Sending data request: trx=0 ts=7 sapi=5 arfcn=0 fn=2654448 block=1 data=08 03 14 4d 43 20 50 41 43 4b 45 54 20 30 39 20 28 54 42 46 20 32 29
Not accepting non-EGPRS phone in EGPRS-only mode
No PDCH resource
+********** TBF starts here **********
+Allocating DL TBF: MS_CLASS=12/0
+Creating MS object, TLLI = 0x00000000
+Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12
+Searching for first unallocated TFI: TRX=0
+ Found TFI=0.
+Slot Allocation (Algorithm B) for class 12
+- Rx=4 Tx=4 Sum Rx+Tx=5 Tta=2 Ttb=1 Tra=2 Trb=1 Type=1
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 6, because not enabled
+- Skipping TS 7, because not enabled
+- Possible DL/UL slots: (TS=0)"..CCCC.."(TS=7)
+- Selected DL slots: (TS=0)"..DDDD.."(TS=7)
+Using 4 slots for DL
+- Reserved DL/UL slots: (TS=0)"..DDCD.."(TS=7)
+- Assigning DL TS 2
+PDCH(TS 2, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 3
+PDCH(TS 3, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 4
+PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 5
+PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Setting Control TS 4
+Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)
+Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL): trx = 0, ul_slots = 10, dl_slots = 3c
+DL TBF slots: 0x3c, N: 4, WS: 64
+TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL) free
+PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL), 0 TBFs, USFs = 00, TFIs = 00000000.
+Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL)
+Destroying MS object, TLLI = 0x00000000
+********** TBF ends here **********
+********** TBF starts here **********
+Allocating DL TBF: MS_CLASS=12/12
+Creating MS object, TLLI = 0x00000000
+Modifying MS object, TLLI = 0x00000000, MS class 0 -> 12
+Modifying MS object, TLLI = 0x00000000, EGPRS MS class 0 -> 12
+Enabled EGPRS for TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), mode EGPRS
+Searching for first unallocated TFI: TRX=0
+ Found TFI=0.
+Slot Allocation (Algorithm B) for class 12
+- Rx=4 Tx=4 Sum Rx+Tx=5 Tta=2 Ttb=1 Tra=2 Trb=1 Type=1
+- Skipping TS 0, because not enabled
+- Skipping TS 1, because not enabled
+- Skipping TS 6, because not enabled
+- Skipping TS 7, because not enabled
+- Possible DL/UL slots: (TS=0)"..CCCC.."(TS=7)
+- Selected DL slots: (TS=0)"..DDDD.."(TS=7)
+Using 4 slots for DL
+- Reserved DL/UL slots: (TS=0)"..DDCD.."(TS=7)
+- Assigning DL TS 2
+PDCH(TS 2, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 3
+PDCH(TS 3, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 4
+PDCH(TS 4, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Assigning DL TS 5
+PDCH(TS 5, TRX 0): Attaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
+- Setting Control TS 4
+Attaching TBF to MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS)
+Allocated TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): trx = 0, ul_slots = 10, dl_slots = 3c
+TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS): Setting EGPRS window size to 384
+DL TBF slots: 0x3c, N: 4, WS: 384
+TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS) free
+PDCH(TS 2, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 3, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 4, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000.
+PDCH(TS 5, TRX 0): Detaching TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS), 0 TBFs, USFs = 00, TFIs = 00000000.
+Detaching TBF from MS object, TLLI = 0x00000000, TBF = TBF(TFI=0 TLLI=0x00000000 DIR=DL STATE=NULL EGPRS)
+Destroying MS object, TLLI = 0x00000000
+********** TBF ends here **********
diff --git a/tests/tbf/TbfTest.ok b/tests/tbf/TbfTest.ok
index c4bc8705..c6c4aea2 100644
--- a/tests/tbf/TbfTest.ok
+++ b/tests/tbf/TbfTest.ok
@@ -28,3 +28,5 @@
=== end test_tbf_dl_reuse ===
=== start test_tbf_gprs_egprs ===
=== end test_tbf_gprs_egprs ===
+=== start test_tbf_ws ===
+=== end test_tbf_ws ===