From 4af30533f0e01a7156ff92f7689ccf35900740c3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 19:16:55 +0100 Subject: alloc/tests: Create an allocation test for various scenarious The allocation in the TBF/BTS code is quite complex. In parts this is due the assignment and requests occuring under differen circumstances. Attempt to re-create the commono scenarios. Remove the bogus msclass check in gprs_rlcmac_tbf::update as the allocation code will check the ms class anyway. --- src/tbf.cpp | 5 -- tests/alloc/AllocTest.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++++ tests/alloc/AllocTest.ok | 32 +++++++++++ 3 files changed, 173 insertions(+), 5 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index ba615eca..a91193d2 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -317,11 +317,6 @@ int gprs_rlcmac_tbf::update() if (direction != GPRS_RLCMAC_DL_TBF) return -EINVAL; - if (!ms_class) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Cannot update, no class\n"); - return -EINVAL; - } - ul_tbf = bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF); tbf_unlink_pdch(this); diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 5790ade1..5c903210 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -97,6 +97,146 @@ static void test_alloc_a() test_alloc_a(GPRS_RLCMAC_UL_TBF, 7); } +static void dump_assignment(struct gprs_rlcmac_tbf *tbf, const char *dir) +{ + for (int i = 0; i < ARRAY_SIZE(tbf->pdch); ++i) + if (tbf->pdch[i]) + printf("PDCH[%d] is used for %s\n", i, dir); + printf("PDCH[%d] is control_ts for %s\n", tbf->control_ts, dir); + printf("PDCH[%d] is first common for %s\n", tbf->first_common_ts, dir); +} + +static void test_alloc_b() +{ + printf("Going to test multislot assignment.\n"); + /* + * PDCH is on TS 6,7,8 and we start with a UL allocation and + * then follow two DL allocations (once single, once normal). + * + * Uplink assigned and still available.. + */ + { + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + int tfi; + uint8_t ts_no, trx_no; + + gprs_rlcmac_tbf *ul_tbf, *dl_tbf; + + printf("Testing UL then DL assignment.\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 1); + OSMO_ASSERT(ul_tbf); + dump_assignment(ul_tbf, "UL"); + + /* assume final ack has not been sent */ + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 0); + OSMO_ASSERT(dl_tbf); + dump_assignment(dl_tbf, "DL"); + + tbf_free(dl_tbf); + tbf_free(ul_tbf); + } + + /** + * Test with the other order.. first DL and then UL + */ + { + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + int tfi; + uint8_t ts_no, trx_no; + + gprs_rlcmac_tbf *ul_tbf, *dl_tbf; + + printf("Testing DL then UL assignment followed by update\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[5].enable(); + trx->pdch[6].enable(); + trx->pdch[7].enable(); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 1); + dl_tbf->m_tlli = 0x23; + dl_tbf->m_tlli_valid = true; + OSMO_ASSERT(dl_tbf); + dump_assignment(dl_tbf, "DL"); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 0); + ul_tbf->m_tlli = 0x23; + ul_tbf->m_tlli_valid = true; + ul_tbf->dir.ul.contention_resolution_done = 1; + OSMO_ASSERT(ul_tbf); + dump_assignment(ul_tbf, "UL"); + + /* now update the dl_tbf */ + dl_tbf->update(); + dump_assignment(dl_tbf, "DL"); + + tbf_free(dl_tbf); + tbf_free(ul_tbf); + } + + /* Andreas osmocom-pcu example */ + { + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + int tfi; + uint8_t ts_no, trx_no; + + gprs_rlcmac_tbf *ul_tbf, *dl_tbf; + + printf("Testing jolly example\n"); + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + trx->pdch[1].enable(); + trx->pdch[2].enable(); + trx->pdch[3].enable(); + trx->pdch[4].enable(); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 0); + OSMO_ASSERT(ul_tbf); + dump_assignment(ul_tbf, "UL"); + + /* assume final ack has not been sent */ + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 0); + OSMO_ASSERT(dl_tbf); + dump_assignment(dl_tbf, "DL"); + + tbf_free(dl_tbf); + tbf_free(ul_tbf); + } +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); @@ -109,6 +249,7 @@ int main(int argc, char **argv) log_set_print_filename(osmo_stderr_target, 0); test_alloc_a(); + test_alloc_b(); return EXIT_SUCCESS; } diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 86a8c193..271a4200 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -1,2 +1,34 @@ Testing alloc_a direction(0) Testing alloc_a direction(1) +Going to test multislot assignment. +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[3] is used for UL +PDCH[3] is control_ts for UL +PDCH[3] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[3] is control_ts for DL +PDCH[3] is first common for DL -- cgit v1.2.3 From c7b998cc73005fd7da26f8fe2d562e40691a8ae6 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 19:25:10 +0100 Subject: alloc/test: Go through all possible ms_classes for the allocation Generate results for all possible classes. --- tests/alloc/AllocTest.cpp | 29 +- tests/alloc/AllocTest.ok | 935 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 955 insertions(+), 9 deletions(-) diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 5c903210..68fcb2a4 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -106,9 +106,9 @@ static void dump_assignment(struct gprs_rlcmac_tbf *tbf, const char *dir) printf("PDCH[%d] is first common for %s\n", tbf->first_common_ts, dir); } -static void test_alloc_b() +static void test_alloc_b(int ms_class) { - printf("Going to test multislot assignment.\n"); + printf("Going to test multislot assignment MS_CLASS=%d\n", ms_class); /* * PDCH is on TS 6,7,8 and we start with a UL allocation and * then follow two DL allocations (once single, once normal). @@ -136,17 +136,19 @@ static void test_alloc_b() tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 1); + ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 1); OSMO_ASSERT(ul_tbf); dump_assignment(ul_tbf, "UL"); /* assume final ack has not been sent */ tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 0); + dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0); OSMO_ASSERT(dl_tbf); dump_assignment(dl_tbf, "DL"); + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + tbf_free(dl_tbf); tbf_free(ul_tbf); } @@ -175,7 +177,7 @@ static void test_alloc_b() tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 1); + dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 1); dl_tbf->m_tlli = 0x23; dl_tbf->m_tlli_valid = true; OSMO_ASSERT(dl_tbf); @@ -183,16 +185,19 @@ static void test_alloc_b() tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 0); + ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0); ul_tbf->m_tlli = 0x23; ul_tbf->m_tlli_valid = true; ul_tbf->dir.ul.contention_resolution_done = 1; OSMO_ASSERT(ul_tbf); dump_assignment(ul_tbf, "UL"); + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + /* now update the dl_tbf */ dl_tbf->update(); dump_assignment(dl_tbf, "DL"); + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); tbf_free(dl_tbf); tbf_free(ul_tbf); @@ -221,22 +226,30 @@ static void test_alloc_b() tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, 0, 0); + ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0); OSMO_ASSERT(ul_tbf); dump_assignment(ul_tbf, "UL"); /* assume final ack has not been sent */ tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); OSMO_ASSERT(tfi >= 0); - dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, 0, 0); + dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0); OSMO_ASSERT(dl_tbf); dump_assignment(dl_tbf, "DL"); + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + tbf_free(dl_tbf); tbf_free(ul_tbf); } } +static void test_alloc_b() +{ + for (int i = 0; i < 30; ++i) + test_alloc_b(i); +} + int main(int argc, char **argv) { tall_pcu_ctx = talloc_named_const(NULL, 1, "moiji-mobile AllocTest context"); diff --git a/tests/alloc/AllocTest.ok b/tests/alloc/AllocTest.ok index 271a4200..9fb2db96 100644 --- a/tests/alloc/AllocTest.ok +++ b/tests/alloc/AllocTest.ok @@ -1,6 +1,6 @@ Testing alloc_a direction(0) Testing alloc_a direction(1) -Going to test multislot assignment. +Going to test multislot assignment MS_CLASS=0 Testing UL then DL assignment. PDCH[6] is used for UL PDCH[6] is control_ts for UL @@ -32,3 +32,936 @@ PDCH[3] is used for DL PDCH[4] is used for DL PDCH[3] is control_ts for DL PDCH[3] is first common for DL +Going to test multislot assignment MS_CLASS=1 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=2 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=3 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=4 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=5 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=6 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=7 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=8 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[3] is used for UL +PDCH[3] is control_ts for UL +PDCH[3] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[3] is control_ts for DL +PDCH[3] is first common for DL +Going to test multislot assignment MS_CLASS=9 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=10 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[3] is used for UL +PDCH[3] is control_ts for UL +PDCH[3] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[3] is control_ts for DL +PDCH[3] is first common for DL +Going to test multislot assignment MS_CLASS=11 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[3] is used for UL +PDCH[3] is control_ts for UL +PDCH[3] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[3] is control_ts for DL +PDCH[3] is first common for DL +Going to test multislot assignment MS_CLASS=12 +Testing UL then DL assignment. +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing DL then UL assignment followed by update +PDCH[6] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +PDCH[6] is used for UL +PDCH[6] is control_ts for UL +PDCH[6] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[6] is control_ts for DL +PDCH[6] is first common for DL +Testing jolly example +PDCH[3] is used for UL +PDCH[3] is control_ts for UL +PDCH[3] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[3] is control_ts for DL +PDCH[3] is first common for DL +Going to test multislot assignment MS_CLASS=13 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=14 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[4] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=15 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[4] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=16 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[4] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=17 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[4] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=18 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[6] is used for UL +PDCH[7] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[1] is used for UL +PDCH[2] is used for UL +PDCH[3] is used for UL +PDCH[4] is used for UL +PDCH[1] is control_ts for UL +PDCH[1] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[1] is control_ts for DL +PDCH[1] is first common for DL +Going to test multislot assignment MS_CLASS=19 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=20 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=21 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=22 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=23 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=24 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=25 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=26 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=27 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=28 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL +Going to test multislot assignment MS_CLASS=29 +Testing UL then DL assignment. +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing DL then UL assignment followed by update +PDCH[5] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +PDCH[5] is used for UL +PDCH[5] is control_ts for UL +PDCH[5] is first common for UL +PDCH[5] is used for DL +PDCH[6] is used for DL +PDCH[7] is used for DL +PDCH[5] is control_ts for DL +PDCH[5] is first common for DL +Testing jolly example +PDCH[2] is used for UL +PDCH[2] is control_ts for UL +PDCH[2] is first common for UL +PDCH[1] is used for DL +PDCH[2] is used for DL +PDCH[3] is used for DL +PDCH[4] is used for DL +PDCH[2] is control_ts for DL +PDCH[2] is first common for DL -- cgit v1.2.3 From df022f6cb20bdaacc0217dfe54bdcc6d7a578c54 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 20:24:16 +0100 Subject: alloc: Add a note that the tx window handling differs from rx It looks like the code is different (without a reason) a good reason. --- src/gprs_rlcmac_ts_alloc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 44c0efb2..f48d8d4f 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -422,6 +422,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " "because not enabled\n", ts); + #warning "Why isn't it needed to increase the window?" continue; } /* check if TSC changes */ @@ -435,6 +436,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, "configured with the same TSC!\n", ts, tbf->trx->trx_no); /* increase window for Type 1 */ + #warning "Why isn't it needed to check for tx_window" if (Type == 1) i++; continue; -- cgit v1.2.3 From f34f34495b201a283d9cd2f8fc80c096a86cbeeb Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 20:33:37 +0100 Subject: alloc: Simplify the assignment of Trb and Ttb Put the cases for MS_A/MS_B and MS_A/MS_C together. --- src/gprs_rlcmac_ts_alloc.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index f48d8d4f..b8028aac 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -236,13 +236,9 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, Type = ms_class->type; /* Tta and Ttb may depend on hopping or frequency change */ - if (Ttb == MS_A) + if (Ttb == MS_A || Ttb == MS_B) Ttb = 0; - if (Trb == MS_A) - Trb = 0; - if (Ttb == MS_B) - Ttb = 0; - if (Trb == MS_C) + if (Trb == MS_A || Trb == MS_C) Trb = 0; LOGP(DRLCMAC, LOGL_DEBUG, "- Rx=%d Tx=%d Sum Rx+Tx=%s Tta=%s Ttb=%d " -- cgit v1.2.3 From 882fc9b1746bde1eec47c266edc02446dad677c5 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 20:34:26 +0100 Subject: alloc: Move the selection of downlink slots to a new method This code could evolve into working for Uplink and Downlink. The only different for the final Uplink assignment is that free USFs are collected. --- src/gprs_rlcmac_ts_alloc.cpp | 153 ++++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 67 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index b8028aac..eb7f0ecb 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -178,6 +178,80 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, return 0; } +/* + * Select a window of Rx slots if available. + * The maximum allowed slots depend on RX or the window of available + * slots. This must be done for uplink TBF also, because it is the basis + * for calculating control slot and uplink slot(s). + */ +static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx, + const int ms_type, const int ms_max_rxslots, + uint8_t *out_rx_win_min, uint8_t *out_rx_win_max) + +{ + uint8_t rx_window = 0; + int rx_window_size = 0; + int8_t last_tsc = -1; /* must be signed */ + uint8_t rx_win_min = 0, rx_win_max = 0; + + for (int ts_no = 0; ts_no < 8; ts_no++) { + struct gprs_rlcmac_pdch *pdch; + pdch = &trx->pdch[ts_no]; + + /* check if enabled */ + if (!pdch->is_enabled()) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because " + "not enabled\n", ts_no); + if (ms_type == 1 && rx_window) + rx_window_size += 1; + continue; + } + /* check if TSC changes */ + if (last_tsc < 0) + last_tsc = pdch->tsc; + else if (last_tsc != pdch->tsc) { + LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of TRX=%d, " + "because it has different TSC than lower TS " + "of TRX. In order to allow multislot, all " + "slots must be configured with the same " + "TSC!\n", ts_no, trx->trx_no); + if (ms_type == 1 && rx_window) + rx_window_size += 1; + continue; + } + + if (!rx_window) + rx_win_min = ts_no; + + rx_window |= (1 << ts_no); + LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", ts_no); + + /* range of window (required for Type 1) */ + rx_win_max = ts_no; + + if (++rx_window_size == ms_max_rxslots) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / " + "window reached maximum alowed Rx size\n"); + break; + } + } + + LOGP(DRLCMAC, LOGL_DEBUG, "- Selected slots for RX: " + "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", + ((rx_window & 0x01)) ? 'D' : '.', + ((rx_window & 0x02)) ? 'D' : '.', + ((rx_window & 0x04)) ? 'D' : '.', + ((rx_window & 0x08)) ? 'D' : '.', + ((rx_window & 0x10)) ? 'D' : '.', + ((rx_window & 0x20)) ? 'D' : '.', + ((rx_window & 0x40)) ? 'D' : '.', + ((rx_window & 0x80)) ? 'D' : '.'); + + *out_rx_win_min = rx_win_min; + *out_rx_win_max = rx_win_max; + return rx_window; +} + /* Slot Allocation: Algorithm B * * Assign as many downlink slots as possible. @@ -188,17 +262,15 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *old_tbf, struct gprs_rlcmac_tbf *tbf, uint32_t cust, uint8_t single) { - struct gprs_rlcmac_pdch *pdch; const struct gprs_ms_multislot_class *ms_class; - uint8_t Rx, Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */ + uint8_t Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */ uint8_t Tta, Ttb, Tra, Trb, Tt, Tr; /* Minimum Number of Slots */ uint8_t Type; /* Type of Mobile */ - uint8_t rx_win_min = 0, rx_win_max = 7; + uint8_t rx_window; uint8_t tx_win_min, tx_win_max, tx_range; - uint8_t rx_window = 0, tx_window = 0; + uint8_t tx_window = 0; static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" }; int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */ - int8_t tsc = -1; /* must be signed */ int8_t first_common_ts = -1; uint8_t i, ts; uint8_t slotcount = 0; @@ -226,7 +298,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, return -EINVAL; } - Rx = ms_class->rx; Tx = ms_class->tx; Sum = ms_class->sum; Tta = ms_class->ta; @@ -242,7 +313,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, Trb = 0; LOGP(DRLCMAC, LOGL_DEBUG, "- Rx=%d Tx=%d Sum Rx+Tx=%s Tta=%s Ttb=%d " - " Tra=%d Trb=%d Type=%d\n", Rx, Tx, + " Tra=%d Trb=%d Type=%d\n", ms_class->rx, Tx, (Sum == MS_NA) ? "N/A" : digit[Sum], (Tta == MS_NA) ? "N/A" : digit[Tta], Ttb, Tra, Trb, Type); @@ -251,63 +322,10 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, Tt = Ttb; Tr = Trb; - /* select a window of Rx slots if available - * The maximum allowed slots depend on RX or the window of available - * slots. - * This must be done for uplink TBF also, because it is the basis - * for calculating control slot and uplink slot(s). */ - for (ts = 0, i = 0; ts < 8; ts++) { - pdch = &tbf->trx->pdch[ts]; - /* check if enabled */ - if (!pdch->is_enabled()) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because " - "not enabled\n", ts); - /* increase window for Type 1 */ - if (Type == 1 && rx_window) - i++; - continue; - } - /* check if TSC changes */ - if (tsc < 0) - tsc = pdch->tsc; - else if (tsc != pdch->tsc) { - LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of TRX=%d, " - "because it has different TSC than lower TS " - "of TRX. In order to allow multislot, all " - "slots must be configured with the same " - "TSC!\n", ts, tbf->trx->trx_no); - /* increase window for Type 1 */ - if (Type == 1 && rx_window) - i++; - continue; - } - - if (!rx_window) - rx_win_min = ts; + uint8_t rx_win_min, rx_win_max; + rx_window = select_dl_slots(tbf->trx, ms_class->type, ms_class->rx, + &rx_win_min, &rx_win_max); - rx_window |= (1 << ts); - LOGP(DRLCMAC, LOGL_DEBUG, "- Selected DL TS %d\n", ts); - - /* range of window (required for Type 1) */ - rx_win_max = ts; - - if (++i == Rx) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / " - "window reached maximum alowed Rx size\n"); - break; - } - } - - LOGP(DRLCMAC, LOGL_DEBUG, "- Selected slots for RX: " - "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", - ((rx_window & 0x01)) ? 'D' : '.', - ((rx_window & 0x02)) ? 'D' : '.', - ((rx_window & 0x04)) ? 'D' : '.', - ((rx_window & 0x08)) ? 'D' : '.', - ((rx_window & 0x10)) ? 'D' : '.', - ((rx_window & 0x20)) ? 'D' : '.', - ((rx_window & 0x40)) ? 'D' : '.', - ((rx_window & 0x80)) ? 'D' : '.'); /* reduce window, if existing uplink slots collide RX window */ if (Type == 1 && old_tbf && old_tbf->direction == GPRS_RLCMAC_UL_TBF) { @@ -412,7 +430,9 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, * also assign the first common ts, which is used for control or single * slot. */ if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + int tsc = -1; for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { + struct gprs_rlcmac_pdch *pdch; pdch = &tbf->trx->pdch[ts]; /* check if enabled */ if (!pdch->is_enabled()) { @@ -487,6 +507,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, /* assign the first common ts, which is used for control or * single slot. */ for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { + struct gprs_rlcmac_pdch *pdch; pdch = &tbf->trx->pdch[ts]; /* check if enabled */ if (!pdch->is_enabled()) { @@ -520,8 +541,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, continue; LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning DL TS " "%d\n", ts); - pdch = &tbf->trx->pdch[ts]; - assign_dlink_tbf(pdch, tbf); + assign_dlink_tbf(&tbf->trx->pdch[ts], tbf); slotcount++; if (slotcount == 1) tbf->first_ts = ts; @@ -540,8 +560,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, if ((tx_window & (1 << ts))) { LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS " "%d\n", ts); - pdch = &tbf->trx->pdch[ts]; - assign_uplink_tbf_usf(pdch, tbf, usf[ts]); + assign_uplink_tbf_usf(&tbf->trx->pdch[ts], tbf, usf[ts]); slotcount++; if (slotcount == 1) tbf->first_ts = ts; -- cgit v1.2.3 From e45c19b3e8f54c3d57757fc42dc6e6b0018cdd9f Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 20:53:53 +0100 Subject: alloc: Move the collision handling to a new method The naming of RX/TX still looks fishy and it should use DL/UL instead. Work on pointers right now. We could introduce a struct with the window min and max and pass this struct. The usage of 'D' appears wrong in the ul_usage.. --- src/gprs_rlcmac_ts_alloc.cpp | 152 +++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 64 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index eb7f0ecb..f2708744 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -252,6 +252,89 @@ static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx, return rx_window; } +static int reduce_rx_window(const int ms_type, const struct gprs_rlcmac_tbf *old_tbf, + const int Tt, const int Tr, + int *rx_window, + uint8_t *rx_win_min, uint8_t *rx_win_max) +{ + if (ms_type != 1) + return 0; + if (!old_tbf) + return 0; + if (old_tbf->direction != GPRS_RLCMAC_UL_TBF) + return 0; + + uint8_t collide = 0, ul_usage = 0; + + /* calculate mask of colliding slots */ + for (uint8_t ts_no = 0; ts_no < 8; ts_no++) { + int j; + if (!old_tbf->pdch[ts_no]) + continue; + + ul_usage |= (1 << ts_no); + /* mark bits from TS-t .. TS+r */ + for (j = ts_no - Tt; j != ((ts_no + Tr + 1) & 7); j = (j + 1) & 7) + collide |= (1 << j); + } + + LOGP(DRLCMAC, LOGL_DEBUG, "- Not allowed slots due to existing " + "UL allocation: (TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7) " + " D=downlink x=not usable\n", + ((ul_usage & 0x01)) ? 'D' : ((collide & 0x01))?'x':'.', + ((ul_usage & 0x02)) ? 'D' : ((collide & 0x02))?'x':'.', + ((ul_usage & 0x04)) ? 'D' : ((collide & 0x04))?'x':'.', + ((ul_usage & 0x08)) ? 'D' : ((collide & 0x08))?'x':'.', + ((ul_usage & 0x10)) ? 'D' : ((collide & 0x10))?'x':'.', + ((ul_usage & 0x20)) ? 'D' : ((collide & 0x20))?'x':'.', + ((ul_usage & 0x40)) ? 'D' : ((collide & 0x40))?'x':'.', + ((ul_usage & 0x80)) ? 'D' : ((collide & 0x80))?'x':'.'); + + /* + * Uplink/Downlink in GSM is shifted by three timeslots. Make + * sure they don't collide. + */ + *rx_window &= ~(collide << 3); + *rx_window &= ~(collide >> 5); + LOGP(DRLCMAC, LOGL_DEBUG, "- Remaining slots for RX: " + "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", + ((*rx_window & 0x01)) ? 'D' : '.', + ((*rx_window & 0x02)) ? 'D' : '.', + ((*rx_window & 0x04)) ? 'D' : '.', + ((*rx_window & 0x08)) ? 'D' : '.', + ((*rx_window & 0x10)) ? 'D' : '.', + ((*rx_window & 0x20)) ? 'D' : '.', + ((*rx_window & 0x40)) ? 'D' : '.', + ((*rx_window & 0x80)) ? 'D' : '.'); + + if (!*rx_window) { + LOGP(DRLCMAC, LOGL_NOTICE, "No suitable downlink slots " + "available with current uplink assignment\n"); + return -EBUSY; + } + + /* calculate new min/max */ + for (uint8_t ts_no = *rx_win_min; ts_no <= *rx_win_max; ts_no++) { + if ((*rx_window & (1 << ts_no))) + break; + *rx_win_min = ts_no + 1; + LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " + "raising start of DL window to %d\n", + *rx_win_min); + } + for (uint8_t ts_no = *rx_win_max; ts_no >= *rx_win_min; ts_no--) { + if ((*rx_window & (1 << ts_no))) + break; + *rx_win_max = ts_no - 1; + LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " + "lowering end of DL window to %d\n", + *rx_win_max); + } + + return 0; +} + + /* Slot Allocation: Algorithm B * * Assign as many downlink slots as possible. @@ -266,7 +349,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, uint8_t Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */ uint8_t Tta, Ttb, Tra, Trb, Tt, Tr; /* Minimum Number of Slots */ uint8_t Type; /* Type of Mobile */ - uint8_t rx_window; + int rx_window; uint8_t tx_win_min, tx_win_max, tx_range; uint8_t tx_window = 0; static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" }; @@ -328,69 +411,10 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, /* reduce window, if existing uplink slots collide RX window */ - if (Type == 1 && old_tbf && old_tbf->direction == GPRS_RLCMAC_UL_TBF) { - uint8_t collide = 0, ul_usage = 0; - int j; - - /* calculate mask of colliding slots */ - for (ts = 0; ts < 8; ts++) { - if (old_tbf->pdch[ts]) { - ul_usage |= (1 << ts); - /* mark bits from TS-t .. TS+r */ - for (j = ts - Tt; j != ((ts + Tr + 1) & 7); - j = (j + 1) & 7) - collide |= (1 << j); - } - } - LOGP(DRLCMAC, LOGL_DEBUG, "- Not allowed slots due to existing " - "UL allocation: (TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7) " - " D=downlink x=not usable\n", - ((ul_usage & 0x01)) ? 'D' : ((collide & 0x01))?'x':'.', - ((ul_usage & 0x02)) ? 'D' : ((collide & 0x02))?'x':'.', - ((ul_usage & 0x04)) ? 'D' : ((collide & 0x04))?'x':'.', - ((ul_usage & 0x08)) ? 'D' : ((collide & 0x08))?'x':'.', - ((ul_usage & 0x10)) ? 'D' : ((collide & 0x10))?'x':'.', - ((ul_usage & 0x20)) ? 'D' : ((collide & 0x20))?'x':'.', - ((ul_usage & 0x40)) ? 'D' : ((collide & 0x40))?'x':'.', - ((ul_usage & 0x80)) ? 'D' : ((collide & 0x80))?'x':'.'); - - /* apply mask to reduce tx_window (shifted by 3 slots) */ - rx_window &= ~(collide << 3); - rx_window &= ~(collide >> 5); - LOGP(DRLCMAC, LOGL_DEBUG, "- Remaining slots for RX: " - "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", - ((rx_window & 0x01)) ? 'D' : '.', - ((rx_window & 0x02)) ? 'D' : '.', - ((rx_window & 0x04)) ? 'D' : '.', - ((rx_window & 0x08)) ? 'D' : '.', - ((rx_window & 0x10)) ? 'D' : '.', - ((rx_window & 0x20)) ? 'D' : '.', - ((rx_window & 0x40)) ? 'D' : '.', - ((rx_window & 0x80)) ? 'D' : '.'); - if (!rx_window) { - LOGP(DRLCMAC, LOGL_NOTICE, "No suitable downlink slots " - "available with current uplink assignment\n"); - return -EBUSY; - } - - /* calculate new min/max */ - for (ts = rx_win_min; ts <= rx_win_max; ts++) { - if ((rx_window & (1 << ts))) - break; - rx_win_min = ts + 1; - LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " - "raising start of DL window to %d\n", - rx_win_min); - } - for (ts = rx_win_max; ts >= rx_win_min; ts--) { - if ((rx_window & (1 << ts))) - break; - rx_win_max = ts - 1; - LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " - "lowering end of DL window to %d\n", - rx_win_max); - } - } + int rc = reduce_rx_window(ms_class->type, old_tbf, Tt, Tr, + &rx_window, &rx_win_min, &rx_win_max); + if (rc < 0) + return rc; /* reduce window, to allow at least one uplink TX slot * this is only required for Type 1 */ -- cgit v1.2.3 From dd4af8045f3306b8b59a1ba8319dc903ce00e550 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 21:03:42 +0100 Subject: alloc: Move upating of the rx window max for Type==1 to a new method --- src/gprs_rlcmac_ts_alloc.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index f2708744..c612f3e6 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -334,6 +334,25 @@ static int reduce_rx_window(const int ms_type, const struct gprs_rlcmac_tbf *old return 0; } +/* + * reduce window, to allow at least one uplink TX slot + * this is only required for Type 1 + */ +static uint8_t update_rx_win_max(const int ms_type, const int Tt, + const int Tr, uint8_t rx_win_min, uint8_t rx_win_max) +{ + if (ms_type != 1) + return rx_win_max; + + if (rx_win_max - rx_win_min + 1 + Tt + 1 + Tr > 8) { + rx_win_max = rx_win_min + 7 - Tt - 1 - Tr; + LOGP(DRLCMAC, LOGL_DEBUG, "- Reduce RX window due to time " + "contraints to %d slots\n", rx_win_max - rx_win_min + 1); + } + + return rx_win_max; +} + /* Slot Allocation: Algorithm B * @@ -415,16 +434,8 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, &rx_window, &rx_win_min, &rx_win_max); if (rc < 0) return rc; - - /* reduce window, to allow at least one uplink TX slot - * this is only required for Type 1 */ - if (Type == 1 && rx_win_max - rx_win_min + 1 + Tt + 1 + Tr > 8) { - rx_win_max = rx_win_min + 7 - Tt - 1 - Tr; - LOGP(DRLCMAC, LOGL_DEBUG, "- Reduce RX window due to time " - "contraints to %d slots\n", - rx_win_max - rx_win_min + 1); - } - + rx_win_max = update_rx_win_max(ms_class->type, Tt, Tr, + rx_win_min, rx_win_max); LOGP(DRLCMAC, LOGL_DEBUG, "- RX-Window is: %d..%d\n", rx_win_min, rx_win_max); -- cgit v1.2.3 From 3fd2ddf1a2c8c6c471b9996af6fc8f7c4c579fd5 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 25 Dec 2013 21:11:20 +0100 Subject: alloc: Move the tx window calculation to a new method --- src/gprs_rlcmac_ts_alloc.cpp | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index c612f3e6..2c2636fd 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -353,6 +353,27 @@ static uint8_t update_rx_win_max(const int ms_type, const int Tt, return rx_win_max; } +static void tx_win_from_rx(const int ms_type, + uint8_t rx_win_min, uint8_t rx_win_max, + int Tt, int Tr, + uint8_t *tx_win_min, uint8_t *tx_win_max, + uint8_t *tx_range) +{ + if (ms_type == 1) { + /* calculate TX window (shifted by 3 timeslots) + * it uses the space between tx_win_max and tx_win_min */ + *tx_win_min = (rx_win_max - 2 + Tt) & 7; + *tx_win_max = (rx_win_min + 4 - Tr) & 7; + } else { + /* TX and RX simultaniously */ + *tx_win_min = rx_win_min; + *tx_win_max = 7; + } + + *tx_range = (*tx_win_max - *tx_win_min + 1) & 7; + LOGP(DRLCMAC, LOGL_DEBUG, "- TX-Window is: %d..%d\n", *tx_win_min, + *tx_win_max); +} /* Slot Allocation: Algorithm B * @@ -369,7 +390,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, uint8_t Tta, Ttb, Tra, Trb, Tt, Tr; /* Minimum Number of Slots */ uint8_t Type; /* Type of Mobile */ int rx_window; - uint8_t tx_win_min, tx_win_max, tx_range; uint8_t tx_window = 0; static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" }; int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */ @@ -440,23 +460,9 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, rx_win_max); /* calculate TX window */ - if (Type == 1) { - /* calculate TX window (shifted by 3 timeslots) - * it uses the space between tx_win_max and tx_win_min */ - tx_win_min = (rx_win_max - 2 + Tt) & 7; - tx_win_max = (rx_win_min + 4 - Tr) & 7; - /* calculate the TX window size (might be larger than Tx) */ - tx_range = (tx_win_max - tx_win_min + 1) & 7; - } else { - /* TX and RX simultaniously */ - tx_win_min = rx_win_min; - tx_win_max = 7; - /* TX window size (might be larger than Tx) */ - tx_range = tx_win_max - tx_win_min + 1; - } - - LOGP(DRLCMAC, LOGL_DEBUG, "- TX-Window is: %d..%d\n", tx_win_min, - tx_win_max); + uint8_t tx_win_min, tx_win_max, tx_range; + tx_win_from_rx(ms_class->type, rx_win_min, rx_win_max, Tt, Tr, + &tx_win_min, &tx_win_max, &tx_range); /* select a window of Tx slots if available * The maximum allowed slots depend on TX or the window of available -- cgit v1.2.3 From 1fe69323ad3b5aad8f625f7d1162c7037ceab190 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 26 Dec 2013 09:31:31 +0100 Subject: alloc: Move the selection of the first enabled pdch to a new method --- src/gprs_rlcmac_ts_alloc.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 2c2636fd..f65e673c 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -375,6 +375,28 @@ static void tx_win_from_rx(const int ms_type, *tx_win_max); } +/* + * Assign the first common ts, which is used for control or + * single slot. + */ +static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min, uint8_t tx_range) +{ + uint8_t ts_no; + int i; + for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7) { + gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; + /* check if enabled */ + if (!pdch->is_enabled()) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " + "because not enabled\n", ts_no); + continue; + } + return ts_no; + } + + return -1; +} + /* Slot Allocation: Algorithm B * * Assign as many downlink slots as possible. @@ -545,20 +567,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, return -EBUSY; } } else { - /* assign the first common ts, which is used for control or - * single slot. */ - for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { - struct gprs_rlcmac_pdch *pdch; - pdch = &tbf->trx->pdch[ts]; - /* check if enabled */ - if (!pdch->is_enabled()) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " - "because not enabled\n", ts); - continue; - } - first_common_ts = ts; - break; - } + first_common_ts = select_first_ts(tbf->trx, tx_win_min, tx_range); } if (first_common_ts < 0) { -- cgit v1.2.3 From 73193110f22f6e8bec774a7426c735ecc6d9733a Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 26 Dec 2013 09:49:05 +0100 Subject: alloc: Move the uplink ts selection/pre-assignment out of the code Create a select_ul_slots which is very (95%) similar to the select_dl_slots handling. This needs to be refactored and the todo for multiple uplink slots should be handled too. Add a warning about a potential failure on a busy PCU. --- src/gprs_rlcmac_ts_alloc.cpp | 187 +++++++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 87 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index f65e673c..171c2041 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -375,6 +375,97 @@ static void tx_win_from_rx(const int ms_type, *tx_win_max); } +/* + * Select a window of Tx slots if available. + * The maximum allowed slots depend on TX or the window of available + * slots. + */ +static int select_ul_slots(gprs_rlcmac_trx *trx, + const int ms_type, const int ms_max_txslots, + uint8_t tx_win_min, uint8_t tx_range, + int8_t *usf, int8_t *first_common_ts) +{ + int tsc = -1; + uint8_t tx_window = 0; + int i; + uint8_t ts_no; + + for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7) { + gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; + + /* check if enabled */ + if (!pdch->is_enabled()) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " + "because not enabled\n", ts_no); + #warning "Why isn't it needed to increase the window?" + continue; + } + /* check if TSC changes */ + if (tsc < 0) + tsc = pdch->tsc; + else if (tsc != pdch->tsc) { + LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of " + "TRX=%d, because it has different TSC " + "than lower TS of TRX. In order to " + "allow multislot, all slots must be " + "configured with the same TSC!\n", + ts_no, trx->trx_no); + /* increase window for Type 1 */ + #warning "Why isn't it needed to check for tx_window" + if (ms_type == 1) + i++; + continue; + } + /* check for free usf */ + usf[ts_no] = find_free_usf(pdch); + if (usf[ts_no] < 0) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " + "because no USF available\n", ts_no); + /* increase window for Type 1 */ + if (ms_type == 1) + i++; + continue; + } + + if (!tx_window) + *first_common_ts = ts_no; + + tx_window |= (1 << ts_no); + LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts_no); + + if (1 && ms_type == 1) { /* FIXME: multislot UL assignment */ + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " + "1 slot assigned\n"); + break; + } + if (++i == ms_max_txslots) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " + "slots / window reached maximum " + "allowed Tx size\n"); + break; + } + } + + LOGP(DRLCMAC, LOGL_DEBUG, "- Selected TX window: " + "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", + ((tx_window & 0x01)) ? 'U' : '.', + ((tx_window & 0x02)) ? 'U' : '.', + ((tx_window & 0x04)) ? 'U' : '.', + ((tx_window & 0x08)) ? 'U' : '.', + ((tx_window & 0x10)) ? 'U' : '.', + ((tx_window & 0x20)) ? 'U' : '.', + ((tx_window & 0x40)) ? 'U' : '.', + ((tx_window & 0x80)) ? 'U' : '.'); + + if (!tx_window) { + LOGP(DRLCMAC, LOGL_NOTICE, "No suitable uplink slots " + "available\n"); + return -EBUSY; + } + + return tx_window; +} + /* * Assign the first common ts, which is used for control or * single slot. @@ -412,11 +503,10 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, uint8_t Tta, Ttb, Tra, Trb, Tt, Tr; /* Minimum Number of Slots */ uint8_t Type; /* Type of Mobile */ int rx_window; - uint8_t tx_window = 0; static const char *digit[10] = { "0","1","2","3","4","5","6","7","8","9" }; int8_t usf[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; /* must be signed */ int8_t first_common_ts = -1; - uint8_t i, ts; + uint8_t ts; uint8_t slotcount = 0; @@ -486,89 +576,18 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, tx_win_from_rx(ms_class->type, rx_win_min, rx_win_max, Tt, Tr, &tx_win_min, &tx_win_max, &tx_range); - /* select a window of Tx slots if available - * The maximum allowed slots depend on TX or the window of available - * slots. - * - * also assign the first common ts, which is used for control or single - * slot. */ + /* select UL slots but in both cases assign first_common_ts */ + uint8_t tx_window = 0; if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - int tsc = -1; - for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) { - struct gprs_rlcmac_pdch *pdch; - pdch = &tbf->trx->pdch[ts]; - /* check if enabled */ - if (!pdch->is_enabled()) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " - "because not enabled\n", ts); - #warning "Why isn't it needed to increase the window?" - continue; - } - /* check if TSC changes */ - if (tsc < 0) - tsc = pdch->tsc; - else if (tsc != pdch->tsc) { - LOGP(DRLCMAC, LOGL_ERROR, "Skipping TS %d of " - "TRX=%d, because it has different TSC " - "than lower TS of TRX. In order to " - "allow multislot, all slots must be " - "configured with the same TSC!\n", - ts, tbf->trx->trx_no); - /* increase window for Type 1 */ - #warning "Why isn't it needed to check for tx_window" - if (Type == 1) - i++; - continue; - } - /* check for free usf */ - usf[ts] = find_free_usf(pdch); - if (usf[ts] < 0) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " - "because no USF available\n", ts); - /* increase window for Type 1 */ - if (Type == 1) - i++; - continue; - } - - if (!tx_window) - first_common_ts = ts; - - tx_window |= (1 << ts); - LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts); - - if (1 && Type == 1) { /* FIXME: multislot UL assignment */ - LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " - "1 slot assigned\n"); - break; - } - if (++i == Tx) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " - "slots / window reached maximum " - "allowed Tx size\n"); - break; - } - } - - LOGP(DRLCMAC, LOGL_DEBUG, "- Selected TX window: " - "(TS=0)\"%c%c%c%c%c%c%c%c\"(TS=7)\n", - ((tx_window & 0x01)) ? 'U' : '.', - ((tx_window & 0x02)) ? 'U' : '.', - ((tx_window & 0x04)) ? 'U' : '.', - ((tx_window & 0x08)) ? 'U' : '.', - ((tx_window & 0x10)) ? 'U' : '.', - ((tx_window & 0x20)) ? 'U' : '.', - ((tx_window & 0x40)) ? 'U' : '.', - ((tx_window & 0x80)) ? 'U' : '.'); - - if (!tx_window) { - LOGP(DRLCMAC, LOGL_NOTICE, "No suitable uplink slots " - "available\n"); - return -EBUSY; - } + rc = select_ul_slots(tbf->trx, ms_class->type, ms_class->tx, + tx_win_min, tx_range, usf, &first_common_ts); + if (rc < 0) + return rc; + tx_window = rc; } else { first_common_ts = select_first_ts(tbf->trx, tx_win_min, tx_range); } + #warning "first_common_ts might be different if there was no free USF for the new uplink assignment" if (first_common_ts < 0) { LOGP(DRLCMAC, LOGL_NOTICE, "No first common slots available\n"); @@ -600,12 +619,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, } } } else { - /* assign uplink */ - if (tx_window == 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "No uplink slots " - "available\n"); - return -EINVAL; - } for (ts = 0; ts < 8; ts++) { if ((tx_window & (1 << ts))) { LOGP(DRLCMAC, LOGL_DEBUG, "- Assigning UL TS " -- cgit v1.2.3 From b03d427b088380cc16461abb20115f36669777a9 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:14:19 +0100 Subject: alloc_algorithm_b: Correctly increment RX/TX window, even if TS is not useable --- src/gprs_rlcmac_ts_alloc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 171c2041..d2ccda99 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -203,7 +203,7 @@ static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx, LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because " "not enabled\n", ts_no); if (ms_type == 1 && rx_window) - rx_window_size += 1; + goto inc_window; continue; } /* check if TSC changes */ @@ -216,7 +216,7 @@ static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx, "slots must be configured with the same " "TSC!\n", ts_no, trx->trx_no); if (ms_type == 1 && rx_window) - rx_window_size += 1; + goto inc_window; continue; } @@ -229,6 +229,7 @@ static uint8_t select_dl_slots(struct gprs_rlcmac_trx *trx, /* range of window (required for Type 1) */ rx_win_max = ts_no; +inc_window: if (++rx_window_size == ms_max_rxslots) { LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / " "window reached maximum alowed Rx size\n"); @@ -397,7 +398,8 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, if (!pdch->is_enabled()) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " "because not enabled\n", ts_no); - #warning "Why isn't it needed to increase the window?" + if (ms_type == 1 && tx_window) + goto inc_window; continue; } /* check if TSC changes */ @@ -410,10 +412,8 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, "allow multislot, all slots must be " "configured with the same TSC!\n", ts_no, trx->trx_no); - /* increase window for Type 1 */ - #warning "Why isn't it needed to check for tx_window" if (ms_type == 1) - i++; + goto inc_window; continue; } /* check for free usf */ @@ -421,9 +421,8 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, if (usf[ts_no] < 0) { LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " "because no USF available\n", ts_no); - /* increase window for Type 1 */ if (ms_type == 1) - i++; + goto inc_window; continue; } @@ -433,6 +432,7 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, tx_window |= (1 << ts_no); LOGP(DRLCMAC, LOGL_DEBUG, "- Selected UL TS %d\n", ts_no); +inc_window: if (1 && ms_type == 1) { /* FIXME: multislot UL assignment */ LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because " "1 slot assigned\n"); -- cgit v1.2.3 From ccde4c462d94f2800edae4c4f8ad6c2c87d1c11a Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:17:22 +0100 Subject: alloc_algorithm_b: For type 1 MS, limit number of donwlink TS to 5 The algorithm does not support more than 5 TS on downlink for type 1 MS. Supporting more than 5 TS would require adding more complexity to this algorithm. MS that support more than 4 (or 5) TS on downlink are rare, if they really exist. --- src/gprs_rlcmac_ts_alloc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index d2ccda99..a4e247a8 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -235,6 +235,12 @@ inc_window: "window reached maximum alowed Rx size\n"); break; } + if (ms_type == 1 && rx_window_size == 5) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Done, because slots / " + "window reached maximum supported Rx size of " + "this algorithm\n"); + break; + } } LOGP(DRLCMAC, LOGL_DEBUG, "- Selected slots for RX: " -- cgit v1.2.3 From 7a16d46fdcad1df8c525f10ed344cd28d75292cc Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:25:18 +0100 Subject: alloc_algorithm_b: Set tx_range to 8, if all 8 TS are supported by MS --- src/gprs_rlcmac_ts_alloc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index a4e247a8..62d1dd18 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -378,6 +378,9 @@ static void tx_win_from_rx(const int ms_type, } *tx_range = (*tx_win_max - *tx_win_min + 1) & 7; + /* if TX window fills complete range */ + if (*tx_range == 0) + *tx_range = 8; LOGP(DRLCMAC, LOGL_DEBUG, "- TX-Window is: %d..%d\n", *tx_win_min, *tx_win_max); } -- cgit v1.2.3 From 765736dc77966563c08c38c6561f75b3b91c55f9 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:27:31 +0100 Subject: alloc_algorithm_b: Do not select uplink slots that cannot be used for downlink In order to poll MS, the mobile must be able to receive polling request. In order to allow the MS to transmit, the USF must be received by the mobile. --- src/gprs_rlcmac_ts_alloc.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 62d1dd18..96fc0927 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -393,7 +393,7 @@ static void tx_win_from_rx(const int ms_type, static int select_ul_slots(gprs_rlcmac_trx *trx, const int ms_type, const int ms_max_txslots, uint8_t tx_win_min, uint8_t tx_range, - int8_t *usf, int8_t *first_common_ts) + int8_t *usf, int8_t *first_common_ts, uint8_t rx_window) { int tsc = -1; uint8_t tx_window = 0; @@ -411,6 +411,14 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, goto inc_window; continue; } + /* check if used as downlink */ + if (!(rx_window & (1 << ts_no))) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " + "because not a downlink slot\n", ts_no); + if (ms_type == 1 && tx_window) + goto inc_window; + continue; + } /* check if TSC changes */ if (tsc < 0) tsc = pdch->tsc; @@ -479,7 +487,8 @@ inc_window: * Assign the first common ts, which is used for control or * single slot. */ -static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min, uint8_t tx_range) +static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min, + uint8_t tx_range, uint8_t rx_window) { uint8_t ts_no; int i; @@ -491,6 +500,12 @@ static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min, uint8_t tx_ "because not enabled\n", ts_no); continue; } + /* check if used as downlink */ + if (!(rx_window & (1 << ts_no))) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, " + "because not a downlink slot\n", ts_no); + continue; + } return ts_no; } @@ -589,12 +604,14 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, uint8_t tx_window = 0; if (tbf->direction == GPRS_RLCMAC_UL_TBF) { rc = select_ul_slots(tbf->trx, ms_class->type, ms_class->tx, - tx_win_min, tx_range, usf, &first_common_ts); + tx_win_min, tx_range, usf, + &first_common_ts, rx_window); if (rc < 0) return rc; tx_window = rc; } else { - first_common_ts = select_first_ts(tbf->trx, tx_win_min, tx_range); + first_common_ts = select_first_ts(tbf->trx, tx_win_min, + tx_range, rx_window); } #warning "first_common_ts might be different if there was no free USF for the new uplink assignment" -- cgit v1.2.3 From f3eec04655ad0ac629950f3891cb97720ab608e5 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 26 Dec 2013 10:19:18 +0100 Subject: alloc/test: Add a crazy test that tests each possible combination Make a crazy test that will test each possible PDCH configuration and MS Class and verify that the UL/DL assignments work and that they are on the same first_common_ts. --- tests/alloc/AllocTest.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 68fcb2a4..80e8c344 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -244,10 +244,140 @@ static void test_alloc_b(int ms_class) } } +#define ENABLE_PDCH(ts_no, enable_flag, trx) \ + if (enable_flag) \ + trx->pdch[ts_no].enable(); + +static void test_alloc_b(bool ts0, bool ts1, bool ts2, bool ts3, bool ts4, bool ts5, bool ts6, bool ts7, int ms_class) +{ + /* we can test the allocation failures differently */ + if (!ts0 && !ts1 && !ts2 && !ts3 && !ts4 && !ts5 && !ts6 && !ts7) + return; + + printf("Mass test: TS0(%c%c%c%c%c%c%c%c)TS7 MS_Class=%d\n", + ts0 ? 'O' : 'x', + ts1 ? 'O' : 'x', + ts2 ? 'O' : 'x', + ts3 ? 'O' : 'x', + ts4 ? 'O' : 'x', + ts5 ? 'O' : 'x', + ts6 ? 'O' : 'x', + ts7 ? 'O' : 'x', ms_class); + fflush(stdout); + + { + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + int tfi; + uint8_t ts_no, trx_no; + + gprs_rlcmac_tbf *ul_tbf, *dl_tbf; + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + ENABLE_PDCH(0, ts0, trx); + ENABLE_PDCH(1, ts1, trx); + ENABLE_PDCH(2, ts2, trx); + ENABLE_PDCH(3, ts3, trx); + ENABLE_PDCH(4, ts4, trx); + ENABLE_PDCH(5, ts5, trx); + ENABLE_PDCH(6, ts6, trx); + ENABLE_PDCH(7, ts7, trx); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + + OSMO_ASSERT(tfi >= 0); + ul_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 1); + OSMO_ASSERT(ul_tbf); + + /* assume final ack has not been sent */ + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + dl_tbf = tbf_alloc(bts, ul_tbf, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 0); + OSMO_ASSERT(dl_tbf); + + /* verify that both are on the same ts */ + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + + tbf_free(dl_tbf); + tbf_free(ul_tbf); + } + + /** + * Test with the other order.. first DL and then UL + */ + { + BTS the_bts; + struct gprs_rlcmac_bts *bts; + struct gprs_rlcmac_trx *trx; + int tfi; + uint8_t ts_no, trx_no; + + gprs_rlcmac_tbf *ul_tbf, *dl_tbf; + + bts = the_bts.bts_data(); + bts->alloc_algorithm = alloc_algorithm_b; + + trx = &bts->trx[0]; + ENABLE_PDCH(0, ts0, trx); + ENABLE_PDCH(1, ts1, trx); + ENABLE_PDCH(2, ts2, trx); + ENABLE_PDCH(3, ts3, trx); + ENABLE_PDCH(4, ts4, trx); + ENABLE_PDCH(5, ts5, trx); + ENABLE_PDCH(6, ts6, trx); + ENABLE_PDCH(7, ts7, trx); + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + dl_tbf = tbf_alloc(bts, NULL, GPRS_RLCMAC_DL_TBF, tfi, trx_no, ms_class, 1); + OSMO_ASSERT(dl_tbf); + dl_tbf->m_tlli = 0x23; + dl_tbf->m_tlli_valid = true; + + tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + ul_tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx_no, ms_class, 0); + OSMO_ASSERT(ul_tbf); + ul_tbf->m_tlli = 0x23; + ul_tbf->m_tlli_valid = true; + ul_tbf->dir.ul.contention_resolution_done = 1; + + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + + /* now update the dl_tbf */ + dl_tbf->update(); + OSMO_ASSERT(dl_tbf->first_common_ts == ul_tbf->first_common_ts); + + tbf_free(dl_tbf); + tbf_free(ul_tbf); + } +} + +static void test_all_alloc_b() +{ + /* it is a bit crazy... */ + for (uint8_t ts0 = 0; ts0 < 2; ++ts0) + for (uint8_t ts1 = 0; ts1 < 2; ++ts1) + for (uint8_t ts2 = 0; ts2 < 2; ++ts2) + for (uint8_t ts3 = 0; ts3 < 2; ++ts3) + for (uint8_t ts4 = 0; ts4 < 2; ++ts4) + for (uint8_t ts5 = 0; ts5 < 2; ++ts5) + for (uint8_t ts6 = 0; ts6 < 2; ++ts6) + for (uint8_t ts7 = 0; ts7 < 2; ++ts7) + for (int ms_class = 0; ms_class < 30; ++ms_class) + test_alloc_b(ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7, ms_class); +} + static void test_alloc_b() { for (int i = 0; i < 30; ++i) test_alloc_b(i); + + test_all_alloc_b(); } int main(int argc, char **argv) -- cgit v1.2.3 From fe2dcc8aecf4d2f9bab186e2619507659b85517e Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:39:54 +0100 Subject: alloc_algorithm_b: Increment 'i', so allocated TS will not exceed tx_range --- src/gprs_rlcmac_ts_alloc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 96fc0927..e1e2498d 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -400,7 +400,7 @@ static int select_ul_slots(gprs_rlcmac_trx *trx, int i; uint8_t ts_no; - for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7) { + for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) { gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; /* check if enabled */ @@ -492,7 +492,7 @@ static int select_first_ts(gprs_rlcmac_trx *trx, uint8_t tx_win_min, { uint8_t ts_no; int i; - for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7) { + for (ts_no = tx_win_min, i = 0; i < tx_range; ts_no = (ts_no + 1) & 7, i++) { gprs_rlcmac_pdch *pdch = &trx->pdch[ts_no]; /* check if enabled */ if (!pdch->is_enabled()) { -- cgit v1.2.3 From 1cd9d886e6328ad9a85f849f2c027bb4bb8d410e Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 4 Jan 2014 15:42:38 +0100 Subject: alloc_algorithm_b: Add seperate function to shrink rx window when TS are removed After reduce_rx_window() and update_rx_win_max() was called, one or more TS might be removed. tx_win_min and tx_win_max must be adjusted to the new range of allocated slots. --- src/gprs_rlcmac_ts_alloc.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index e1e2498d..58dd2e9b 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -320,25 +320,29 @@ static int reduce_rx_window(const int ms_type, const struct gprs_rlcmac_tbf *old return -EBUSY; } + return 0; +} + +/* shrink range of rx_win_min and rx_win_max */ +static void shrink_rx_window(uint8_t *rx_win_min, uint8_t *rx_win_max, int rx_window) +{ /* calculate new min/max */ for (uint8_t ts_no = *rx_win_min; ts_no <= *rx_win_max; ts_no++) { - if ((*rx_window & (1 << ts_no))) + if ((rx_window & (1 << ts_no))) break; *rx_win_min = ts_no + 1; - LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " + LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so " "raising start of DL window to %d\n", *rx_win_min); } for (uint8_t ts_no = *rx_win_max; ts_no >= *rx_win_min; ts_no--) { - if ((*rx_window & (1 << ts_no))) + if ((rx_window & (1 << ts_no))) break; *rx_win_max = ts_no - 1; - LOGP(DRLCMAC, LOGL_DEBUG, "- TS has been deleted, so " + LOGP(DRLCMAC, LOGL_DEBUG, "- TS is unused, so " "lowering end of DL window to %d\n", *rx_win_max); } - - return 0; } /* @@ -590,8 +594,10 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, &rx_window, &rx_win_min, &rx_win_max); if (rc < 0) return rc; + shrink_rx_window(&rx_win_min, &rx_win_max, rx_window); rx_win_max = update_rx_win_max(ms_class->type, Tt, Tr, rx_win_min, rx_win_max); + shrink_rx_window(&rx_win_min, &rx_win_max, rx_window); LOGP(DRLCMAC, LOGL_DEBUG, "- RX-Window is: %d..%d\n", rx_win_min, rx_win_max); -- cgit v1.2.3