diff options
Diffstat (limited to 'tests/tbf/TbfTest.cpp')
-rw-r--r-- | tests/tbf/TbfTest.cpp | 646 |
1 files changed, 406 insertions, 240 deletions
diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 8700347d..643551b9 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -26,7 +26,6 @@ #include "tbf_ul.h" #include "gprs_ms.h" #include "gprs_debug.h" -#include "gprs_ms_storage.h" #include "pcu_utils.h" #include "gprs_bssgp_pcu.h" #include "pcu_l1_if.h" @@ -36,13 +35,14 @@ extern "C" { #include "pcu_vty.h" #include "coding_scheme.h" +#include "alloc_algo.h" #include <osmocom/core/application.h> #include <osmocom/core/msgb.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> #include <osmocom/vty/vty.h> -#include <osmocom/gprs/protocol/gsm_04_60.h> +#include <osmocom/gsm/protocol/gsm_44_060.h> #include <osmocom/gsm/l1sap.h> #include <osmocom/core/fsm.h> } @@ -67,6 +67,8 @@ static gprs_pcu *prepare_pcu(void) { struct gprs_pcu *pcu = gprs_pcu_alloc(tall_pcu_ctx); bssgp_set_bssgp_callback(gprs_gp_send_test_cb, NULL); + osmo_tdef_set(pcu->T_defs, -2030, 0, OSMO_TDEF_S); + osmo_tdef_set(pcu->T_defs, -2031, 0, OSMO_TDEF_S); return pcu; } @@ -78,7 +80,8 @@ static int bts_handle_rach(struct gprs_rlcmac_bts *bts, uint16_t ra, uint32_t Fn .ra = ra, .trx_nr = 0, .ts_nr = 0, - .rfn = Fn, + .rfn = fn2rfn(Fn), + .fn = Fn, .qta = qta, }; @@ -89,7 +92,7 @@ static void check_tbf(gprs_rlcmac_tbf *tbf) { OSMO_ASSERT(tbf); if (tbf->state_is(TBF_ST_WAIT_RELEASE)) - OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fsm.fi->timer)); + OSMO_ASSERT(tbf->timers_pending(T3191) || osmo_timer_pending(&tbf->state_fi->timer)); if (tbf->state_is(TBF_ST_RELEASING)) OSMO_ASSERT(tbf->timers_pending(T_MAX)); } @@ -120,45 +123,44 @@ static void test_tbf_tlli_update() /* * Make a uplink and downlink allocation */ - ms = bts_alloc_ms(bts, 0, 0); - gprs_rlcmac_tbf *dl_tbf = tbf_alloc_dl_tbf(bts, - ms, 0, false); + ms = ms_alloc(bts, NULL); + OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0); + gprs_rlcmac_tbf *dl_tbf = ms_dl_tbf(ms); OSMO_ASSERT(dl_tbf != NULL); - dl_tbf->update_ms(0x2342, GPRS_RLCMAC_DL_TBF); - dl_tbf->set_ta(4); - OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf); OSMO_ASSERT(dl_tbf->ms() == ms); + ms_confirm_tlli(ms, 0x2342); + dl_tbf->set_ta(4); - gprs_rlcmac_tbf *ul_tbf = tbf_alloc_ul_tbf(bts, - ms, 0, false); + OSMO_ASSERT(ms_new_ul_tbf_assigned_pacch(ms, 0)); + + gprs_rlcmac_tbf *ul_tbf = ms_ul_tbf(ms); OSMO_ASSERT(ul_tbf != NULL); - ul_tbf->update_ms(0x2342, GPRS_RLCMAC_UL_TBF); - OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); OSMO_ASSERT(ul_tbf->ms() == ms); + ms_update_announced_tlli(ms, 0x2342); - OSMO_ASSERT(bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms); + OSMO_ASSERT(bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI) == ms); /* * Now check.. that DL changes and that the timing advance * has changed. */ - dl_tbf->update_ms(0x4232, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), 0x4232); /* It is still there, since the new TLLI has not been used for UL yet */ - ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI); + ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI); OSMO_ASSERT(ms == ms_new); - ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI); + ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI); OSMO_ASSERT(ms == ms_new); OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); /* Now use the new TLLI for UL */ - ul_tbf->update_ms(0x4232, GPRS_RLCMAC_UL_TBF); - ms_new = bts_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI); + ms_update_announced_tlli(ms, 0x4232); + ms_new = bts_get_ms_by_tlli(bts, 0x2342, GSM_RESERVED_TMSI); OSMO_ASSERT(ms_new == NULL); - ms_new = bts_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI); + ms_new = bts_get_ms_by_tlli(bts, 0x4232, GSM_RESERVED_TMSI); OSMO_ASSERT(ms_new != NULL); OSMO_ASSERT(ms_ta(ms_new) == 4); @@ -190,42 +192,11 @@ static void setup_bts(struct gprs_rlcmac_bts *bts, uint8_t ts_no, uint8_t cs = 1 the_pcu->alloc_algorithm = alloc_algorithm_a; bts->initial_cs_dl = cs; bts->initial_cs_ul = cs; - osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S); - osmo_tdef_set(the_pcu->T_defs, -2031, 0, OSMO_TDEF_S); trx = &bts->trx[0]; - trx->pdch[ts_no].enable(); bts_set_current_frame_number(bts, DUMMY_FN); } -static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class, - uint8_t egprs_ms_class, uint8_t *trx_no_) -{ - int tfi; - uint8_t trx_no; - GprsMs *ms; - gprs_rlcmac_dl_tbf *dl_tbf; - - ms = bts_alloc_ms(bts, ms_class, egprs_ms_class); - - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1); - OSMO_ASSERT(tfi >= 0); - dl_tbf = tbf_alloc_dl_tbf(bts, ms, trx_no, true); - OSMO_ASSERT(dl_tbf); - dl_tbf->set_ta(0); - check_tbf(dl_tbf); - - /* "Establish" the DL TBF */ - osmo_fsm_inst_dispatch(dl_tbf->dl_ass_fsm.fi, TBF_DL_ASS_EV_SCHED_ASS, NULL); - osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ADD_CCCH, NULL); - osmo_fsm_inst_dispatch(dl_tbf->state_fsm.fi, TBF_EV_ASSIGN_ACK_PACCH, NULL); - check_tbf(dl_tbf); - - *trx_no_ = trx_no; - - return dl_tbf; -} - static unsigned fn_add_blocks(unsigned fn, unsigned blocks) { unsigned bn = fn2bn(fn) + blocks; @@ -235,11 +206,11 @@ static unsigned fn_add_blocks(unsigned fn, unsigned blocks) } static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts, - uint8_t trx_no, uint8_t ts_no, + struct gprs_rlcmac_pdch *pdch, uint32_t *fn, uint8_t *block_nr = NULL) { uint8_t bn = fn2bn(*fn); - gprs_rlcmac_rcv_rts_block(bts, trx_no, ts_no, *fn, bn); + gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, *fn, bn); *fn = fn_add_blocks(*fn, 1); bn += 1; if (block_nr) @@ -249,8 +220,37 @@ static void request_dl_rlc_block(struct gprs_rlcmac_bts *bts, static void request_dl_rlc_block(struct gprs_rlcmac_tbf *tbf, uint32_t *fn, uint8_t *block_nr = NULL) { - request_dl_rlc_block(tbf->bts, tbf->trx->trx_no, - tbf->control_ts, fn, block_nr); + request_dl_rlc_block(tbf->bts, tbf->control_ts, fn, block_nr); +} + +static gprs_rlcmac_dl_tbf *create_dl_tbf(struct gprs_rlcmac_bts *bts, uint8_t ms_class, + uint8_t egprs_ms_class, uint8_t *trx_no_) +{ + int tfi; + uint8_t trx_no; + GprsMs *ms; + gprs_rlcmac_dl_tbf *dl_tbf; + + ms = ms_alloc(bts, NULL); + ms_set_ms_class(ms, ms_class); + ms_set_egprs_ms_class(ms, egprs_ms_class); + + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx_no, -1); + OSMO_ASSERT(tfi >= 0); + OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0); + dl_tbf = ms_dl_tbf(ms); + OSMO_ASSERT(dl_tbf); + dl_tbf->set_ta(0); + check_tbf(dl_tbf); + + /* "Establish" the DL TBF */ + osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_ADD_CCCH, NULL); + osmo_fsm_inst_dispatch(dl_tbf->state_fi, TBF_EV_ASSIGN_READY_CCCH, NULL); + check_tbf(dl_tbf); + + *trx_no_ = trx_no; + + return dl_tbf; } enum test_tbf_final_ack_mode { @@ -306,15 +306,15 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) setup_bts(bts, ts_no); dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); ms = dl_tbf->ms(); for (i = 0; i < sizeof(llc_data); i++) llc_data[i] = i%256; /* Schedule two LLC frames */ - dl_tbf->append_data(1000, llc_data, sizeof(llc_data)); - dl_tbf->append_data(1000, llc_data, sizeof(llc_data)); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data)); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data)); /* Send only a few RLC/MAC blocks */ @@ -327,6 +327,13 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) OSMO_ASSERT(dl_tbf->have_data()); OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); + do { + /* Request to send one block */ + request_dl_rlc_block(dl_tbf, &fn, &block_nr); + } while (dl_tbf->state_is(TBF_ST_FLOW)); + + OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED)); + /* Queue a final ACK */ memset(rbb, 0, sizeof(rbb)); /* Receive a final ACK */ @@ -334,26 +341,29 @@ static void test_tbf_final_ack(enum test_tbf_final_ack_mode test_mode) /* Clean up and ensure tbfs are in the correct state */ OSMO_ASSERT(dl_tbf->state_is(TBF_ST_WAIT_RELEASE)); + + /* Now append new data, a new DL TBF should be created and assigned through the old one due to T3192: */ + ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data)); new_tbf = ms_dl_tbf(ms); check_tbf(new_tbf); OSMO_ASSERT(new_tbf != dl_tbf); OSMO_ASSERT(new_tbf->tfi() == 1); check_tbf(dl_tbf); if (test_mode == TEST_MODE_REVERSE_FREE) { - ms_ref(ms); + ms_ref(ms, __func__); tbf_free(new_tbf); OSMO_ASSERT(ms_dl_tbf(ms) == NULL); check_tbf(dl_tbf); tbf_free(dl_tbf); - ms_unref(ms); + ms_unref(ms, __func__); } else { - ms_ref(ms); + ms_ref(ms, __func__); tbf_free(dl_tbf); OSMO_ASSERT(ms_dl_tbf(ms) == new_tbf); check_tbf(new_tbf); tbf_free(new_tbf); OSMO_ASSERT(ms_dl_tbf(ms) == NULL); - ms_unref(ms); + ms_unref(ms, __func__); } TALLOC_FREE(the_pcu); @@ -382,7 +392,7 @@ static void test_tbf_delayed_release() OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2031, 200, OSMO_TDEF_MS) == 0); dl_tbf = create_dl_tbf(bts, ms_class, 0, &trx_no); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); for (i = 0; i < sizeof(llc_data); i++) llc_data[i] = i%256; @@ -390,8 +400,8 @@ static void test_tbf_delayed_release() OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); /* Schedule two LLC frames */ - dl_tbf->append_data(1000, llc_data, sizeof(llc_data)); - dl_tbf->append_data(1000, llc_data, sizeof(llc_data)); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data)); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, llc_data, sizeof(llc_data)); OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); @@ -447,43 +457,43 @@ static void test_tbf_imsi() dl_tbf[0] = create_dl_tbf(bts, ms_class, 0, &trx_no); dl_tbf[1] = create_dl_tbf(bts, ms_class, 0, &trx_no); - dl_tbf[0]->update_ms(0xf1000001, GPRS_RLCMAC_DL_TBF); - dl_tbf[1]->update_ms(0xf1000002, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf[0]->ms(), 0xf1000001); + ms_confirm_tlli(dl_tbf[1]->ms(), 0xf1000002); ms_set_imsi(dl_tbf[0]->ms(), "001001000000001"); - ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001"); + ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001"); OSMO_ASSERT(ms1 != NULL); - ms2 = bts_ms_store(bts)->get_ms(0xf1000001); + ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI); OSMO_ASSERT(ms2 != NULL); OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000001") == 0); OSMO_ASSERT(ms1 == ms2); /* change the IMSI on TBF 0 */ ms_set_imsi(dl_tbf[0]->ms(), "001001000000002"); - ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000001"); + ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000001"); OSMO_ASSERT(ms1 == NULL); - ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002"); + ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002"); OSMO_ASSERT(ms1 != NULL); OSMO_ASSERT(strcmp(ms_imsi(ms2), "001001000000002") == 0); OSMO_ASSERT(ms1 == ms2); /* use the same IMSI on TBF 1 */ { - ms_ref(ms2); + ms_ref(ms2, __func__); ms_set_imsi(dl_tbf[1]->ms(), "001001000000002"); - ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002"); + ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002"); OSMO_ASSERT(ms1 != NULL); OSMO_ASSERT(ms1 != ms2); OSMO_ASSERT(strcmp(ms_imsi(ms1), "001001000000002") == 0); OSMO_ASSERT(strcmp(ms_imsi(ms2), "") == 0); - ms_unref(ms2); + ms_unref(ms2, __func__); } - ms2 = bts_ms_store(bts)->get_ms(0xf1000001); + ms2 = bts_get_ms_by_tlli(bts, 0xf1000001, GSM_RESERVED_TMSI); OSMO_ASSERT(ms2 == NULL); tbf_free(dl_tbf[1]); - ms1 = bts_ms_store(bts)->get_ms(0, 0, "001001000000002"); + ms1 = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, "001001000000002"); OSMO_ASSERT(ms1 == NULL); TALLOC_FREE(the_pcu); @@ -529,7 +539,6 @@ static void test_tbf_exhaustion() OSMO_ASSERT(rc == -EBUSY); fprintf(stderr, "=== end %s ===\n", __func__); - gprs_bssgp_destroy(bts); TALLOC_FREE(the_pcu); } @@ -537,6 +546,7 @@ static void test_tbf_dl_llc_loss() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; uint8_t ts_no = 4; uint8_t ms_class = 45; int rc = 0; @@ -556,6 +566,7 @@ static void test_tbf_dl_llc_loss() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no); + pdch = &bts->trx[0].pdch[ts_no]; /* keep the MS object 10 seconds */ OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 10, OSMO_TDEF_S) == 0); @@ -567,7 +578,7 @@ static void test_tbf_dl_llc_loss() delay_csec, buf, sizeof(buf)); OSMO_ASSERT(rc >= 0); - ms = bts_ms_store(bts)->get_ms(0, 0, imsi); + ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_dl_tbf(ms) != NULL); ms_dl_tbf(ms)->set_ta(0); @@ -589,13 +600,13 @@ static void test_tbf_dl_llc_loss() OSMO_ASSERT(ms_dl_tbf(ms) != NULL); - /* Here PCU would answer with data_cnf and trigger + /* Here BTS would answer with data_cnf and trigger * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF. * That in turn would set up timer X2002. Finally, X2002 timeout * moves it to FLOW state. We set X2002 timeout to 0 here to get * immediate trigger through osmo_select_main() */ OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0); - osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fsm.fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL); + osmo_fsm_inst_dispatch(ms_dl_tbf(ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL); osmo_select_main(0); OSMO_ASSERT(ms_dl_tbf(ms)->state_is(TBF_ST_FLOW)); @@ -608,12 +619,13 @@ static void test_tbf_dl_llc_loss() 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x07, 0x00, 0x02, 0x4d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }, - { 0x07, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03, + /* On last DL block, PCU requests polling (DL ACK/NACK): S/P 1 and RRBP 01, hence 0x07 becomes 0xf1 */ + { 0x1f, 0x01, 0x04, 0x4d, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }, }; while (ms_dl_tbf(ms)->have_data()) { - msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, 7); + msg = ms_dl_tbf(ms)->create_dl_acked_block(fn += 4, pdch); fprintf(stderr, "MSG = %s\n", msgb_hexdump(msg)); if (!msgb_eq_data_print(msg, exp[expected_data - 1], GSM_MACBLOCK_LEN)) fprintf(stderr, "%s failed at %u\n", __func__, expected_data); @@ -624,25 +636,32 @@ static void test_tbf_dl_llc_loss() fprintf(stderr, "=== end %s ===\n", __func__); - gprs_bssgp_destroy(bts); + /* Restore MS release timeout to 0 to make sure it is freed immediately: */ + OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S) == 0); TALLOC_FREE(the_pcu); } static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta) + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta) { GprsMs *ms; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; - uint8_t trx_no = 0; - struct gprs_rlcmac_pdch *pdch; - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); + /* We set X2002 timeout to 0 here to get immediate trigger through osmo_select_main() below */ + OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0); bts_handle_rach(bts, 0x03, *fn, qta); - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf != NULL); + OSMO_ASSERT(ul_tbf->state_is(TBF_ST_ASSIGN)); + + /* ImmAss has been sent PCU=PCUIF=>BTS. This means UL TBF is in state + * ASSIGN with X2002 armed. It will move to FLOW once it expires. */ + osmo_select_main(0); + OSMO_ASSERT(ul_tbf->state_is(TBF_ST_FLOW)); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -654,10 +673,9 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_single_phase(struct gprs_rlcmac_bts uint8_t(tlli >> 8), uint8_t(tlli), /* TLLI */ }; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); return ul_tbf; @@ -671,13 +689,12 @@ static void send_ul_mac_block_buf(struct gprs_rlcmac_bts *bts, struct gprs_rlcma pdch_ulc_expire_fn(pdch->ulc, fn); } -static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsigned ts_no, +static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch, RlcMacUplink_t *ulreq, unsigned fn) { bitvec *rlc_block; uint8_t buf[64]; int num_bytes; - struct gprs_rlcmac_pdch *pdch; rlc_block = bitvec_alloc(23, tall_pcu_ctx); @@ -686,14 +703,12 @@ static void send_ul_mac_block(struct gprs_rlcmac_bts *bts, unsigned trx_no, unsi OSMO_ASSERT(size_t(num_bytes) < sizeof(buf)); bitvec_free(rlc_block); - pdch = &bts->trx[trx_no].pdch[ts_no]; send_ul_mac_block_buf(bts, pdch, fn, &buf[0], num_bytes); } -static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, uint8_t poll_ts) +static uint32_t get_poll_fn(struct gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch) { - struct gprs_rlcmac_pdch *pdch = &tbf->trx->pdch[poll_ts]; struct pdch_ulc *ulc = pdch->ulc; struct rb_node *node; struct pdch_ulc_node *item; @@ -716,33 +731,29 @@ static void send_control_ack(gprs_rlcmac_tbf *tbf) ctrl_ack->PayloadType = GPRS_RLCMAC_CONTROL_BLOCK; ctrl_ack->TLLI = tbf->tlli(); - send_ul_mac_block(tbf->bts, tbf->trx->trx_no, tbf->control_ts, + send_ul_mac_block(tbf->bts, tbf->control_ts, &ulreq, get_poll_fn(tbf, tbf->control_ts)); } -static void send_empty_block(gprs_rlcmac_tbf *tbf, unsigned ts_no, unsigned fn) +static void send_empty_block(gprs_rlcmac_tbf *tbf, struct gprs_rlcmac_pdch *pdch, unsigned fn) { - struct gprs_rlcmac_pdch *pdch; - pdch = &tbf->bts->trx[tbf->trx->trx_no].pdch[ts_no]; send_ul_mac_block_buf(tbf->bts, pdch, fn, NULL, 0); } static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; uint32_t rach_fn = *fn - 51; uint32_t sba_fn = *fn + 52; - uint8_t trx_no = 0; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; - struct gprs_rlcmac_pdch *pdch; RlcMacUplink_t ulreq = {0}; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; /* needed to set last_rts_fn in the PDCH object */ - request_dl_rlc_block(bts, trx_no, ts_no, fn); + request_dl_rlc_block(bts, pdch, fn); /* * simulate RACH, this sends an Immediate @@ -751,7 +762,7 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, bts_handle_rach(bts, 0x73, rach_fn, qta); /* get next free TFI */ - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); /* fake a resource request */ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; @@ -779,10 +790,10 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, Multislot_capability.EGPRS_multislot_class = ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -801,10 +812,9 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, 1, /* BSN:7, E:1 */ }; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data_msg[0], 23, *fn, &meas); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -832,7 +842,7 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, pdch->rcv_block(data_msg, 42, *fn, &meas); osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - struct msgb *msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + struct msgb *msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); static uint8_t exp1[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x87, 0xb0, 0x06, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b @@ -860,7 +870,7 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, pdch->rcv_block(data_msg, 42, *fn, &meas); osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + msg1 = tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); static uint8_t exp2[] = { 0x40, 0x24, 0x01, 0x0b, 0x3e, 0x24, 0x46, 0x68, 0x9c, 0x70, 0x88, 0xb0, 0x06, 0x8b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b @@ -874,21 +884,19 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(struct gprs_rlcmac_bts *bts, } static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; uint32_t rach_fn = *fn - 51; uint32_t sba_fn = *fn + 52; - uint8_t trx_no = 0; int tfi = 0, i = 0; gprs_rlcmac_ul_tbf *ul_tbf; - struct gprs_rlcmac_pdch *pdch; RlcMacUplink_t ulreq = {0}; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; /* needed to set last_rts_fn in the PDCH object */ - request_dl_rlc_block(bts, trx_no, ts_no, fn); + request_dl_rlc_block(bts, pdch, fn); /* * simulate RACH, this sends an Immediate @@ -897,7 +905,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts bts_handle_rach(bts, 0x73, rach_fn, qta); /* get next free TFI */ - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); /* fake a resource request */ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; @@ -925,10 +933,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts Multislot_capability.EGPRS_multislot_class = ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf != NULL); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -948,10 +956,9 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts uint8_t(1), /* BSN:7, E:1 */ }; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data_msg[0], 23, *fn, &meas); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -1309,18 +1316,17 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(struct gprs_rlcmac_bts } static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { uint32_t rach_fn = *fn - 51; uint32_t sba_fn = *fn + 52; - uint8_t trx_no = 0; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; RlcMacUplink_t ulreq = {0}; /* needed to set last_rts_fn in the PDCH object */ - request_dl_rlc_block(bts, trx_no, ts_no, fn); + request_dl_rlc_block(bts, pdch, fn); /* * simulate RACH, this sends an Immediate @@ -1329,7 +1335,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts, bts_handle_rach(bts, 0x73, rach_fn, qta); /* get next free TFI */ - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); /* fake a resource request */ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; @@ -1356,10 +1362,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts, MS_RA_capability_value[0].u.Content. Multislot_capability.EGPRS_multislot_class = ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); /* send packet uplink assignment */ *fn = sba_fn; request_dl_rlc_block(ul_tbf, fn); @@ -1373,15 +1379,13 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf(struct gprs_rlcmac_bts *bts, } static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf) { OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf->ta() == qta / 4); GprsMs *ms; - uint8_t trx_no = 0; int tfi = 0; - struct gprs_rlcmac_pdch *pdch; /* send fake data with cv=0*/ struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL; @@ -1411,11 +1415,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct data[5] = 0x0; data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); } osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); memset(data, 0x2b, sizeof(data)); hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data; hdr3->r = 0; @@ -1437,7 +1440,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); request_dl_rlc_block(ul_tbf, fn); @@ -1445,7 +1447,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct check_tbf(ul_tbf); OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -1454,15 +1456,13 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(struct } static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class, gprs_rlcmac_ul_tbf *ul_tbf) { OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf->ta() == qta / 4); GprsMs *ms; - uint8_t trx_no = 0; int tfi = 0; - struct gprs_rlcmac_pdch *pdch; check_tbf(ul_tbf); /* send fake data with cv=0*/ @@ -1494,11 +1494,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(stru data[5] = 0x0; data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); } osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); memset(data, 0x2b, sizeof(data)); hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data; hdr3->r = 0; @@ -1520,17 +1519,16 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(stru data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); request_dl_rlc_block(ul_tbf, fn); check_tbf(ul_tbf); OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -1539,17 +1537,15 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(stru } static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; - uint8_t trx_no = 0; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; - struct gprs_rlcmac_pdch *pdch; /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -1582,11 +1578,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcm data[5] = 0x0; data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); } osmo_fsm_inst_dispatch(ul_tbf->ul_ack_fsm.fi, TBF_UL_ACK_EV_SCHED_ACK, NULL); - tbf_ul_ack_create_rlcmac_msg(ul_tbf, *fn, ts_no); + tbf_ul_ack_create_rlcmac_msg(ul_tbf, pdch, *fn); memset(data, 0x2b, sizeof(data)); hdr3 = (struct gprs_rlc_ul_header_egprs_3 *)data; hdr3->r = 0; @@ -1608,7 +1603,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcm data[6] = 0x2b; data[7] = 0x2b; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); request_dl_rlc_block(ul_tbf, fn); @@ -1616,7 +1610,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcm check_tbf(ul_tbf); OSMO_ASSERT(tbf_ul_ack_fi(ul_tbf)->state == TBF_UL_ACK_ST_NONE); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -1624,26 +1618,24 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(struct gprs_rlcm return ul_tbf; } static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; uint32_t rach_fn = *fn - 51; uint32_t sba_fn = *fn + 52; - uint8_t trx_no = 0; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; - struct gprs_rlcmac_pdch *pdch; RlcMacUplink_t ulreq = {0}; /* needed to set last_rts_fn in the PDCH object */ - request_dl_rlc_block(bts, trx_no, ts_no, fn); + request_dl_rlc_block(bts, pdch, fn); /* simulate RACH, sends an Immediate Assignment Uplink on the AGCH */ bts_handle_rach(bts, 0x73, rach_fn, qta); /* get next free TFI */ - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); /* fake a resource request */ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; @@ -1670,10 +1662,10 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bt EGPRS_multislot_class = ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf != NULL); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -1693,10 +1685,9 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase(struct gprs_rlcmac_bts *bt uint8_t(1), /* BSN:7, E:1 */ }; - pdch = &bts->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data_msg[0], sizeof(data_msg), *fn, &meas); - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -1709,17 +1700,16 @@ static void send_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, const char { GprsMs *ms, *ms2; - ms = bts_ms_store(bts)->get_ms(tlli, 0, imsi); + ms = bts_get_ms(bts, tlli, GSM_RESERVED_TMSI, imsi); dl_tbf_handle(bts, tlli, 0, imsi, 0, 0, 1000, data, data_size); - ms = bts_ms_by_imsi(bts, imsi); + ms = bts_get_ms_by_imsi(bts, imsi); OSMO_ASSERT(ms != NULL); - OSMO_ASSERT(ms_dl_tbf(ms) != NULL); - if (imsi[0] && strcmp(imsi, "000") != 0) { - ms2 = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + if (imsi[0] != '\0') { + ms2 = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms == ms2); } } @@ -1731,7 +1721,7 @@ static void transmit_dl_data(struct gprs_rlcmac_bts *bts, uint32_t tlli, uint32_ GprsMs *ms; unsigned ts_no; - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms); dl_tbf = ms_dl_tbf(ms); OSMO_ASSERT(dl_tbf); @@ -1760,6 +1750,33 @@ static void test_tbf_single_phase() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; + int ts_no = 7; + uint32_t fn = DUMMY_FN; /* 17,25,9 */ + uint32_t tlli = 0xf1223344; + const char *imsi = "0011223344"; + uint16_t qta = 31; + gprs_rlcmac_ul_tbf *ul_tbf; + + fprintf(stderr, "=== start %s ===\n", __func__); + + setup_bts(bts, ts_no); + pdch = &bts->trx[0].pdch[ts_no]; + + ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta); + + print_ta_tlli(ul_tbf, true); + send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4); + + fprintf(stderr, "=== end %s ===\n", __func__); + TALLOC_FREE(the_pcu); +} + +static void test_tbf_single_phase2() +{ + the_pcu = prepare_pcu(); + struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = DUMMY_FN; /* 17,25,9 */ uint32_t tlli = 0xf1223344; @@ -1770,12 +1787,21 @@ static void test_tbf_single_phase() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no); + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli, &fn, qta); + ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli, &fn, qta); print_ta_tlli(ul_tbf, true); + /* PCU sends CTRL ACK/NCK with FINAL_ACK=1, hence TBF is not in state FINISHED */ + request_dl_rlc_block(bts, pdch, &fn); + OSMO_ASSERT(ul_tbf->state_is(TBF_ST_FINISHED)); + /* Now data is sent but no DL TBF is created because MS is not reachable for DL Assignment */ send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4); + /* After MS CTRL ACKs the FINAL_ACK=1 then it releases the TBF and goes + * to packet-idle mode. Hence PCU will trigger ImmAss(PktDlAss) on PCH. */ + send_control_ack(ul_tbf); + fprintf(stderr, "=== end %s ===\n", __func__); TALLOC_FREE(the_pcu); } @@ -1785,6 +1811,7 @@ static void test_tbf_egprs_two_phase_puan(void) the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); int ts_no = 7; + struct gprs_rlcmac_pdch *pdch; uint32_t fn = 2654218; uint16_t qta = 31; uint32_t tlli = 0xf1223344; @@ -1802,10 +1829,11 @@ static void test_tbf_egprs_two_phase_puan(void) bts->initial_mcs_dl = 9; the_pcu->vty.ws_base = 128; the_pcu->vty.ws_pdch = 64; + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf(bts, ts_no, tlli, &fn, qta, ms_class, egprs_ms_class); + ul_tbf = establish_ul_tbf(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); /* Function to generate URBB with no length */ - ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, ts_no, tlli, &fn, + ul_tbf = establish_ul_tbf_two_phase_puan_URBB_no_length(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class, ul_tbf); print_ta_tlli(ul_tbf, true); @@ -1813,7 +1841,7 @@ static void test_tbf_egprs_two_phase_puan(void) static_cast<gprs_rlc_ul_window *>(ul_tbf->window())->reset_state(); /* Function to generate URBB with length */ - ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, ts_no, tlli, &fn, + ul_tbf = establish_ul_tbf_two_phase_puan_URBB_with_length(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class, ul_tbf); print_ta_tlli(ul_tbf, true); @@ -1823,7 +1851,7 @@ static void test_tbf_egprs_two_phase_puan(void) /* Function to generate CRBB */ the_pcu->vty.ws_base = 128; the_pcu->vty.ws_pdch = 64; - ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, ts_no, tlli, &fn, + ul_tbf = establish_ul_tbf_two_phase_puan_CRBB(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); print_ta_tlli(ul_tbf, true); @@ -1925,8 +1953,8 @@ static void test_tbf_two_phase() setup_bts(bts, ts_no, 4); - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta, - ms_class, 0); + ul_tbf = establish_ul_tbf_two_phase(bts, &bts->trx[0].pdch[ts_no], + tlli, &fn, qta, ms_class, 0); print_ta_tlli(ul_tbf, true); send_dl_data(bts, tlli, imsi, (const uint8_t *)"TEST", 4); @@ -1945,6 +1973,7 @@ static void test_tbf_ra_update_rach() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -1959,8 +1988,9 @@ static void test_tbf_ra_update_rach() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 4); + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta, ms_class, 0); ms1 = ul_tbf->ms(); @@ -1987,7 +2017,7 @@ static void test_tbf_ra_update_rach() fn = fn_add_blocks(fn, 1); /* Now establish a new TBF for the RA UPDATE COMPLETE (new TLLI) */ - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli2, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli2, &fn, qta, ms_class, 0); ms2 = ul_tbf->ms(); @@ -2000,14 +2030,14 @@ static void test_tbf_ra_update_rach() * the PCU can see, that both MS objects belong to same MS */ send_dl_data(bts, tlli2, imsi, (const uint8_t *)"DATA", 4); - ms = bts_ms_by_imsi(bts, imsi); + ms = bts_get_ms_by_imsi(bts, imsi); OSMO_ASSERT(ms == ms2); print_ms(ms2, false); - ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms == NULL); - ms = bts_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli2, GSM_RESERVED_TMSI); OSMO_ASSERT(ms == ms2); TALLOC_FREE(the_pcu); @@ -2018,6 +2048,7 @@ static void test_tbf_dl_flow_and_rach_two_phase() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2031,8 +2062,9 @@ static void test_tbf_dl_flow_and_rach_two_phase() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 1); + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta, ms_class, 0); ms1 = ul_tbf->ms(); @@ -2048,11 +2080,11 @@ static void test_tbf_dl_flow_and_rach_two_phase() /* Get rid of old UL TBF */ tbf_free(ul_tbf); - ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms1 == ms); /* Now establish a new UL TBF, this will consume one LLC packet */ - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta, ms_class, 0); ms2 = ul_tbf->ms(); @@ -2061,7 +2093,7 @@ static void test_tbf_dl_flow_and_rach_two_phase() /* This should be the same MS object */ OSMO_ASSERT(ms2 == ms1); - ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms2 == ms); /* A DL TBF should still exist */ @@ -2079,6 +2111,7 @@ static void test_tbf_dl_flow_and_rach_single_phase() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2092,8 +2125,9 @@ static void test_tbf_dl_flow_and_rach_single_phase() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 1); + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta, ms_class, 0); ms1 = ul_tbf->ms(); @@ -2109,11 +2143,11 @@ static void test_tbf_dl_flow_and_rach_single_phase() /* Get rid of old UL TBF */ tbf_free(ul_tbf); - ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms1 == ms); /* Now establish a new UL TBF */ - ul_tbf = establish_ul_tbf_single_phase(bts, ts_no, tlli1, &fn, qta); + ul_tbf = establish_ul_tbf_single_phase(bts, pdch, tlli1, &fn, qta); ms2 = ul_tbf->ms(); print_ms(ms2, false); @@ -2121,7 +2155,7 @@ static void test_tbf_dl_flow_and_rach_single_phase() /* There should be a different MS object */ OSMO_ASSERT(ms2 != ms1); - ms = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms2 == ms); OSMO_ASSERT(ms1 != ms); @@ -2139,6 +2173,7 @@ static void test_tbf_dl_reuse() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2154,8 +2189,9 @@ static void test_tbf_dl_reuse() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 1); + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli1, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli1, &fn, qta, ms_class, 0); ms1 = ul_tbf->ms(); @@ -2210,13 +2246,13 @@ static void test_tbf_dl_reuse() ack->DOWNLINK_TFI = dl_tbf1->tfi(); ack->Ack_Nack_Description.FINAL_ACK_INDICATION = 1; - send_ul_mac_block(bts, 0, dl_tbf1->control_ts, &ulreq, get_poll_fn(dl_tbf1, dl_tbf1->control_ts)); + send_ul_mac_block(bts, dl_tbf1->control_ts, &ulreq, get_poll_fn(dl_tbf1, dl_tbf1->control_ts)); OSMO_ASSERT(dl_tbf1->state_is(TBF_ST_WAIT_RELEASE)); request_dl_rlc_block(dl_tbf1, &fn); - ms2 = bts_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); + ms2 = bts_get_ms_by_tlli(bts, tlli1, GSM_RESERVED_TMSI); OSMO_ASSERT(ms2 == ms1); OSMO_ASSERT(ms_dl_tbf(ms2)); OSMO_ASSERT(ms_dl_tbf(ms2)->state_is(TBF_ST_ASSIGN)); @@ -2272,14 +2308,12 @@ static void test_tbf_gprs_egprs() OSMO_ASSERT(rc == 0); fprintf(stderr, "=== end %s ===\n", __func__); - gprs_bssgp_destroy(bts); TALLOC_FREE(the_pcu); } static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_t exp_slots, uint16_t exp_ws, - bool free, bool end) + bool free) { - gprs_rlcmac_bts *bts = dl_tbf->bts; if (!dl_tbf) { fprintf(stderr, "%s(): FAILED (NULL TBF)\n", test); return; @@ -2298,11 +2332,6 @@ static inline void ws_check(gprs_rlcmac_dl_tbf *dl_tbf, const char *test, uint8_ if (free) tbf_free(dl_tbf); - - if (end) { - fprintf(stderr, "=== end %s ===\n", test); - gprs_bssgp_destroy(bts); - } } static void test_tbf_ws() @@ -2335,18 +2364,26 @@ static void test_tbf_ws() gprs_bssgp_init(bts, 4234, 4234, 1, 1, false, 0, 0, 0); /* Does no support EGPRS */ - ms = bts_alloc_ms(bts, ms_class, 0); - dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false); + ms = ms_alloc(bts, NULL); + ms_set_ms_class(ms, ms_class); + OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0); + dl_tbf = ms_dl_tbf(ms); + OSMO_ASSERT(dl_tbf); - ws_check(dl_tbf, __func__, 4, 64, true, false); + ws_check(dl_tbf, __func__, 4, 64, true); /* EGPRS-only */ /* Does support EGPRS */ - ms = bts_alloc_ms(bts, ms_class, ms_class); - dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, false); + ms = ms_alloc(bts, NULL); + ms_set_ms_class(ms, ms_class); + ms_set_egprs_ms_class(ms, ms_class); + OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0); + dl_tbf = ms_dl_tbf(ms); + OSMO_ASSERT(dl_tbf); - ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true); + ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true); + fprintf(stderr, "=== end %s ===\n", __func__); TALLOC_FREE(the_pcu); } @@ -2382,15 +2419,116 @@ static void test_tbf_update_ws(void) /* EGPRS-only */ /* Does support EGPRS */ - ms = bts_alloc_ms(bts, ms_class, ms_class); - dl_tbf = tbf_alloc_dl_tbf(bts, ms, 0, true); + ms = ms_alloc(bts, NULL); + ms_set_ms_class(ms, ms_class); + ms_set_egprs_ms_class(ms, ms_class); + OSMO_ASSERT(ms_new_dl_tbf_assigned_on_pch(ms) == 0); + dl_tbf = ms_dl_tbf(ms); + OSMO_ASSERT(dl_tbf); - ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false, false); + ws_check(dl_tbf, __func__, 1, 128 + 1 * 64, false); - dl_tbf->update(); + OSMO_ASSERT(dl_tbf_upgrade_to_multislot(dl_tbf) == 0); /* window size should be 384 */ - ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true, true); + ws_check(dl_tbf, __func__, 4, 128 + 4 * 64, true); + fprintf(stderr, "=== end %s ===\n", __func__); + TALLOC_FREE(the_pcu); +} + +/* Test DL-TBF first assigned over CCCH ImmAss, then after X2002 timeout, when MS +is available to receive from TBF on PACCH, upgrade it to multislot. In the +middle the MS would request a new UL-TBF and PCU ends up creating 2 MS objects on +different TRX, which are eventually merged. +Hence, new multislot DL-TBF allocation (assigned over PACCH) happens on a different TRX +than the one which was assigned over CCCH and where the PktDlAss is sent. SYS#6231 */ +static void test_ms_merge_dl_tbf_different_trx(void) +{ + the_pcu = prepare_pcu(); + struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + GprsMs *first_ms, *second_ms; + uint8_t ts_no = 1; + uint8_t ms_class = 11; + struct gprs_rlcmac_trx *trx0 = &bts->trx[0]; + struct gprs_rlcmac_trx *trx1 = &bts->trx[1]; + uint32_t old_tlli = 0xa3c2f953; + uint32_t new_tlli = 0xecc1f953; + const char *imsi = "001001000000001"; + uint8_t llc_buf[19]; + int rc; + unsigned delay_csec = 1000; + struct gprs_rlcmac_dl_tbf *dl_tbf; + struct gprs_rlcmac_ul_tbf *ul_tbf; + uint32_t fn = 0; + + fprintf(stderr, "=== start %s ===\n", __func__); + + bts->pcu->nsi = gprs_ns2_instantiate(tall_pcu_ctx, gprs_ns_prim_cb, NULL); + if (!bts->pcu->nsi) { + LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n"); + abort(); + } + + setup_bts(bts, ts_no); + the_pcu->alloc_algorithm = alloc_algorithm_b; + /* trx0->pdch[ts_no].enable(); Already enabled during setup_bts()) */ + trx0->pdch[ts_no].disable(); + trx1->pdch[4].enable(); + trx1->pdch[5].enable(); + trx1->pdch[6].enable(); + gprs_bssgp_init(bts, 5234, 5234, 1, 1, false, 0, 0, 0); + + /* Handle LLC frame 1. This will create the TBF we want in TRX1 and + * we'll have it upgrade to multislot on TRX0 later. This will trigger a + * CCCH Dl ImAss towards BTS PCUIF. The confirmation from BTS is + * injected further below (TBF_EV_ASSIGN_PCUIF_CNF). */ + memset(llc_buf, 1, sizeof(llc_buf)); + rc = dl_tbf_handle(bts, old_tlli, 0, imsi, ms_class, 0, + delay_csec, llc_buf, sizeof(llc_buf)); + OSMO_ASSERT(rc >= 0); + + first_ms = bts_get_ms(bts, GSM_RESERVED_TMSI, GSM_RESERVED_TMSI, imsi); + OSMO_ASSERT(first_ms); + dl_tbf = ms_dl_tbf(first_ms); + OSMO_ASSERT(dl_tbf); + OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx1); + OSMO_ASSERT(dl_tbf->control_ts->trx == trx1); + struct gprs_rlcmac_pdch *old_dl_control_ts = dl_tbf->control_ts; + + /* Enable PDCHs on TRX0 so that second_ms is allocated on TRX0: */ + trx0->pdch[1].enable(); + trx0->pdch[2].enable(); + trx0->pdch[3].enable(); + + second_ms = ms_alloc(bts, NULL); + ms_set_tlli(second_ms, new_tlli); + OSMO_ASSERT(ms_new_ul_tbf_assigned_pacch(second_ms, 0)); + ul_tbf = ms_ul_tbf(second_ms); + OSMO_ASSERT(ul_tbf != NULL); + ms_update_announced_tlli(second_ms, new_tlli); + + /* Here PCU gets to know the MS are the same and they get merged. */ + rc = dl_tbf_handle(bts, new_tlli, old_tlli, imsi, ms_class, 0, + delay_csec, llc_buf, sizeof(llc_buf)); + OSMO_ASSERT(rc >= 0); + /* Here we assert a new DL-TBF is created in the new MS (hence old from TRX1 is deleted and new one is in TRX0): */ + dl_tbf = ms_dl_tbf(second_ms); + OSMO_ASSERT(tbf_get_trx(dl_tbf) == trx0); + OSMO_ASSERT(dl_tbf->control_ts != old_dl_control_ts); + OSMO_ASSERT(dl_tbf == llist_first_entry_or_null(&trx0->dl_tbfs, struct llist_item, list)->entry); + OSMO_ASSERT(NULL == llist_first_entry_or_null(&trx1->dl_tbfs, struct llist_item, list)); + + /* Here BTS would answer with data_cnf and trigger + * bts_rcv_imm_ass_cnf(), which would trigger TBF_EV_ASSIGN_PCUIF_CNF. + * Since that's for an older DL-TBF assignment which no longer exists, it is ignored. */ + OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2002, 0, OSMO_TDEF_MS) == 0); + osmo_fsm_inst_dispatch(ms_dl_tbf(second_ms)->state_fi, TBF_EV_ASSIGN_PCUIF_CNF, NULL); + osmo_select_main(0); + + /* get the PACCH PktDlAss for the DL-TBF, allocated on the UL-TBF from the new MS obj: */ + request_dl_rlc_block(dl_tbf->bts, dl_tbf->control_ts, &fn); + + fprintf(stderr, "=== end %s ===\n", __func__); TALLOC_FREE(the_pcu); } @@ -2398,6 +2536,7 @@ static void test_tbf_puan_urbb_len(void) { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2414,8 +2553,9 @@ static void test_tbf_puan_urbb_len(void) setup_bts(bts, ts_no, 4); bts->initial_mcs_dl = 9; + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = puan_urbb_len_issue(bts, ts_no, tlli, &fn, qta, + ul_tbf = puan_urbb_len_issue(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); print_ta_tlli(ul_tbf, true); @@ -2426,16 +2566,14 @@ static void test_tbf_puan_urbb_len(void) } static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, - uint8_t ts_no, uint32_t tlli, uint32_t *fn, uint16_t qta, + struct gprs_rlcmac_pdch *pdch, uint32_t tlli, uint32_t *fn, uint16_t qta, uint8_t ms_class, uint8_t egprs_ms_class) { GprsMs *ms; uint32_t rach_fn = *fn - 51; uint32_t sba_fn = *fn + 52; - uint8_t trx_no = 0; int tfi = 0; gprs_rlcmac_ul_tbf *ul_tbf; - struct gprs_rlcmac_pdch *pdch; RlcMacUplink_t ulreq = {0}; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; Packet_Resource_Request_t *presreq = NULL; @@ -2443,7 +2581,7 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, Multislot_capability_t *pmultislotcap = NULL; /* needed to set last_rts_fn in the PDCH object */ - request_dl_rlc_block(bts, trx_no, ts_no, fn); + request_dl_rlc_block(bts, pdch, fn); /* * simulate RACH, this sends an Immediate @@ -2452,7 +2590,7 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, bts_handle_rach(bts, 0x73, rach_fn, qta); /* get next free TFI */ - tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx_no, -1); + tfi = bts_tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &pdch->trx->trx_no, -1); /* fake a resource request */ ulreq.u.MESSAGE_TYPE = MT_PACKET_RESOURCE_REQUEST; @@ -2475,10 +2613,10 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, pmultislotcap->EGPRS_multislot_class = ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); /* check the TBF */ - ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, trx_no, ts_no); + ul_tbf = bts_ul_tbf_by_tfi(bts, tfi, pdch->trx->trx_no, pdch->ts_no); OSMO_ASSERT(ul_tbf); OSMO_ASSERT(ul_tbf->ta() == qta / 4); @@ -2493,9 +2631,7 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, uint8_t data_msg[49] = {0}; - pdch = &bts->trx[trx_no].pdch[ts_no]; - - ms = bts_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); + ms = bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI); OSMO_ASSERT(ms != NULL); OSMO_ASSERT(ms_ta(ms) == qta/4); OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf); @@ -2528,7 +2664,7 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(struct gprs_rlcmac_bts *bts, data_msg[5] = 0x0; pdch->rcv_block(data_msg, 49, *fn, &meas); - OSMO_ASSERT(ul_tbf->m_llc.m_index == 43); + OSMO_ASSERT(ul_tbf->m_llc.index == 43); return ul_tbf; } @@ -2537,6 +2673,7 @@ static void test_tbf_li_decoding(void) { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2553,8 +2690,9 @@ static void test_tbf_li_decoding(void) setup_bts(bts, ts_no, 4); bts->initial_mcs_dl = 9; + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = tbf_li_decoding(bts, ts_no, tlli, &fn, qta, + ul_tbf = tbf_li_decoding(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); print_ta_tlli(ul_tbf, true); @@ -2609,7 +2747,7 @@ static void test_tbf_epdan_out_of_rx_window(void) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); prlcdlwindow = static_cast<gprs_rlc_dl_window *>(dl_tbf->window()); prlcmvb = &prlcdlwindow->m_v_b; prlcdlwindow->m_v_s = 1288; @@ -2664,6 +2802,7 @@ static void test_tbf_egprs_two_phase_spb(void) { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2680,8 +2819,9 @@ static void test_tbf_egprs_two_phase_spb(void) setup_bts(bts, ts_no, 4); bts->initial_mcs_dl = 9; + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase_spb(bts, ts_no, tlli, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase_spb(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); print_ta_tlli(ul_tbf, true); @@ -2695,6 +2835,7 @@ static void test_tbf_egprs_two_phase() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; int ts_no = 7; uint32_t fn = 2654218; uint16_t qta = 31; @@ -2711,8 +2852,9 @@ static void test_tbf_egprs_two_phase() setup_bts(bts, ts_no, 4); bts->initial_mcs_dl = 9; + pdch = &bts->trx[0].pdch[ts_no]; - ul_tbf = establish_ul_tbf_two_phase(bts, ts_no, tlli, &fn, qta, + ul_tbf = establish_ul_tbf_two_phase(bts, pdch, tlli, &fn, qta, ms_class, egprs_ms_class); print_ta_tlli(ul_tbf, true); @@ -2742,7 +2884,7 @@ static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs) bts->initial_mcs_dl = mcs; dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); for (i = 0; i < sizeof(llc_data); i++) llc_data[i] = i%256; @@ -2750,7 +2892,7 @@ static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs) OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); /* Schedule a small LLC frame */ - dl_tbf->append_data(1000, test_data, 10); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 10); OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); @@ -2762,7 +2904,7 @@ static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs) send_empty_block(dl_tbf, dl_tbf->control_ts, fn); /* Schedule a large LLC frame */ - dl_tbf->append_data(1000, test_data, sizeof(test_data)); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, sizeof(test_data)); OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); @@ -2771,9 +2913,16 @@ static void establish_and_use_egprs_dl_tbf(struct gprs_rlcmac_bts *bts, int mcs) /* Request to send one RLC/MAC block */ request_dl_rlc_block(dl_tbf, &fn); } + /* ACK all blocks */ + memset(rbb, 0xff, sizeof(rbb)); + _rcv_ack(false, dl_tbf, rbb); + /* X2031 may keep the TBF open for a while: */ + while (dl_tbf->state_is(TBF_ST_FLOW)) { + request_dl_rlc_block(dl_tbf, &fn); + } send_empty_block(dl_tbf, dl_tbf->control_ts, fn); - OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); + OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED)); _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */ @@ -2799,7 +2948,7 @@ static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts, bts->initial_mcs_dl = mcs; dl_tbf = create_dl_tbf(bts, ms_class, egprs_ms_class, &trx_no); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); for (i = 0; i < sizeof(test_data); i++) test_data[i] = i%256; @@ -2811,7 +2960,7 @@ static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts, * 2 RLC data blocks. Which are enough to test Header Type 1 * cases */ - dl_tbf->append_data(1000, test_data, 100); + ms_append_llc_dl_data(dl_tbf->ms(), 1000, test_data, 100); OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FLOW)); @@ -2822,6 +2971,19 @@ static gprs_rlcmac_dl_tbf *tbf_init(struct gprs_rlcmac_bts *bts, static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf) { uint8_t rbb[64/8]; + uint32_t fn = 0; + + if (dl_tbf->state_is(TBF_ST_FLOW)) { + /* X2031 may keep the TBF open for a while: */ + while (dl_tbf->state_is(TBF_ST_FLOW)) { + /* ACK all blocks */ + memset(rbb, 0xff, sizeof(rbb)); + _rcv_ack(false, dl_tbf, rbb); + request_dl_rlc_block(dl_tbf, &fn); + } + } + + OSMO_ASSERT(dl_tbf->state_is(TBF_ST_FINISHED)); _rcv_ack(true, dl_tbf, rbb); /* Receive a final ACK */ @@ -3113,7 +3275,6 @@ static void establish_and_use_egprs_dl_tbf_for_retx(struct gprs_rlcmac_bts *bts, MAKE_ACKED(msg, dl_tbf, fn, mcs, true); } /* Clean up pending items in UL controller: */ - send_empty_block(dl_tbf, dl_tbf->control_ts, fn+50); tbf_cleanup(dl_tbf); } @@ -3202,6 +3363,7 @@ static void test_packet_access_rej_prr_no_other_tbfs() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; uint32_t fn = 2654218; int ts_no = 7; uint8_t trx_no = 0; @@ -3212,21 +3374,21 @@ static void test_packet_access_rej_prr_no_other_tbfs() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 4); + pdch = &bts->trx[trx_no].pdch[ts_no]; OSMO_ASSERT(osmo_tdef_set(the_pcu->T_defs, -2000, 0, OSMO_TDEF_MS) == 0); int rc = 0; - ms = bts_alloc_ms(bts, 0, 0); + ms = ms_alloc(bts, NULL); ms_set_tlli(ms, tlli); - ul_tbf = handle_tbf_reject(bts, ms, trx_no, ts_no); + ul_tbf = ms_new_ul_tbf_rejected_pacch(ms, pdch); OSMO_ASSERT(ul_tbf != 0); /* trigger packet access reject */ uint8_t bn = fn2bn(fn); - rc = gprs_rlcmac_rcv_rts_block(bts, - trx_no, ts_no, fn, bn); + rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn); OSMO_ASSERT(rc == 0); osmo_select_main(0); @@ -3239,6 +3401,7 @@ static void test_packet_access_rej_prr() { the_pcu = prepare_pcu(); struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0); + struct gprs_rlcmac_pdch *pdch; uint32_t fn = 2654218; uint16_t qta = 31; int ts_no = 7; @@ -3256,6 +3419,7 @@ static void test_packet_access_rej_prr() fprintf(stderr, "=== start %s ===\n", __func__); setup_bts(bts, ts_no, 4); + pdch = &bts->trx[trx_no].pdch[ts_no]; int rc = 0; @@ -3290,14 +3454,13 @@ static void test_packet_access_rej_prr() pmultislotcap->EGPRS_multislot_class = egprs_ms_class; } - send_ul_mac_block(bts, trx_no, ts_no, &ulreq, sba_fn); + send_ul_mac_block(bts, pdch, &ulreq, sba_fn); sba_fn = fn_next_block(sba_fn); /* trigger packet access reject */ uint8_t bn = fn2bn(fn); - rc = gprs_rlcmac_rcv_rts_block(bts, - trx_no, ts_no, fn, bn); + rc = gprs_rlcmac_rcv_rts_block(bts, pdch->trx->trx_no, pdch->ts_no, fn, bn); OSMO_ASSERT(rc == 0); } @@ -3319,7 +3482,7 @@ void test_packet_access_rej_epdan() setup_bts(bts, 4); static gprs_rlcmac_dl_tbf *dl_tbf = tbf_init(bts, 1); - dl_tbf->update_ms(tlli, GPRS_RLCMAC_DL_TBF); + ms_confirm_tlli(dl_tbf->ms(), tlli); osmo_fsm_inst_dispatch(dl_tbf->ul_ass_fsm.fi, TBF_UL_ASS_EV_SCHED_ASS_REJ, NULL); struct msgb *msg = tbf_ul_ass_create_rlcmac_msg((const struct gprs_rlcmac_tbf*)dl_tbf, 0, 0); @@ -3351,7 +3514,7 @@ int main(int argc, char **argv) log_set_print_category_hex(osmo_stderr_target, 0); log_parse_category_mask(osmo_stderr_target, "DRLCMAC,1:DRLCMACDATA,3:DRLCMACDL,3:DRLCMACUL,3:" "DRLCMACSCHED,1:DRLCMACMEAS,3:DNS,3:DLBSSGP,3:DPCU,5:" - "DL1IF,6:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:"); + "DL1IF,6:DMS,1:DTBF,1:DTBFUL,1:DTBFDL,1:DLGLOBAL,2:"); osmo_fsm_log_addr(false); vty_init(&pcu_vty_info); pcu_vty_init(); @@ -3369,6 +3532,7 @@ int main(int argc, char **argv) test_tbf_exhaustion(); test_tbf_dl_llc_loss(); test_tbf_single_phase(); + test_tbf_single_phase2(); test_tbf_two_phase(); test_tbf_ra_update_rach(); test_tbf_dl_flow_and_rach_two_phase(); @@ -3390,6 +3554,7 @@ int main(int argc, char **argv) test_packet_access_rej_epdan(); test_packet_access_rej_prr(); test_packet_access_rej_prr_no_other_tbfs(); + test_ms_merge_dl_tbf_different_trx(); if (getenv("TALLOC_REPORT_FULL")) talloc_report_full(tall_pcu_ctx, stderr); @@ -3402,6 +3567,7 @@ int main(int argc, char **argv) extern "C" { void l1if_pdch_req() { abort(); } void l1if_connect_pdch() { abort(); } -void l1if_close_pdch() { abort(); } -void l1if_open_pdch() { abort(); } +void l1if_disconnect_pdch() { abort(); } +void l1if_close_trx() { abort(); } +void l1if_open_trx() { abort(); } } |