diff --git a/src/gprs_ms.c b/src/gprs_ms.c index 073dd4a7..29d226fa 100644 --- a/src/gprs_ms.c +++ b/src/gprs_ms.c @@ -120,7 +120,6 @@ struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli) ms->current_cs_ul = UNKNOWN; ms->current_cs_dl = UNKNOWN; ms->is_idle = true; - ms->first_common_ts = TBF_TS_UNSET; INIT_LLIST_HEAD(&ms->list); INIT_LLIST_HEAD(&ms->old_tbfs); @@ -384,7 +383,7 @@ void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf) if (!ms->dl_tbf && !ms->ul_tbf) { ms_set_reserved_slots(ms, NULL, 0, 0); - ms->first_common_ts = TBF_TS_UNSET; + ms->first_common_ts = NULL; if (ms_tlli(ms) != 0) ms_release_timer_start(ms); @@ -920,15 +919,15 @@ enum CodingScheme ms_current_cs_dl(const struct GprsMs *ms, enum mcs_kind req_mc return cs; } -int8_t ms_first_common_ts(const struct GprsMs *ms) +struct gprs_rlcmac_pdch *ms_first_common_ts(const struct GprsMs *ms) { return ms->first_common_ts; } -void ms_set_first_common_ts(struct GprsMs *ms, uint8_t first_common_ts) +void ms_set_first_common_ts(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch) { - OSMO_ASSERT(first_common_ts < 8); - ms->first_common_ts = first_common_ts; + OSMO_ASSERT(pdch); + ms->first_common_ts = pdch; } uint8_t ms_dl_slots(const struct GprsMs *ms) diff --git a/src/gprs_ms.h b/src/gprs_ms.h index 92292e39..835ff186 100644 --- a/src/gprs_ms.h +++ b/src/gprs_ms.h @@ -64,8 +64,8 @@ struct GprsMs { struct gprs_rlcmac_ul_tbf *ul_tbf; struct gprs_rlcmac_dl_tbf *dl_tbf; struct llist_head old_tbfs; /* list of gprs_rlcmac_tbf */ - /* First common timeslot number used both in UL and DL, 0..7 or TBF_TS_UNSET (-1): */ - int8_t first_common_ts; + /* First common timeslot used both in UL and DL, or NULL if not set: */ + struct gprs_rlcmac_pdch *first_common_ts; uint32_t tlli; uint32_t new_ul_tlli; @@ -103,8 +103,8 @@ struct GprsMs { struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts, uint32_t tlli); -int8_t ms_first_common_ts(const struct GprsMs *ms); -void ms_set_first_common_ts(struct GprsMs *ms, uint8_t first_common_ts); +struct gprs_rlcmac_pdch *ms_first_common_ts(const struct GprsMs *ms); +void ms_set_first_common_ts(struct GprsMs *ms, struct gprs_rlcmac_pdch *pdch); void ms_set_reserved_slots(struct GprsMs *ms, struct gprs_rlcmac_trx *trx, uint8_t ul_slots, uint8_t dl_slots); struct GprsMs *ms_ref(struct GprsMs *ms); diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index 96098a9c..704b6960 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -350,6 +350,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, const char *mask_reason = NULL; struct GprsMs *ms = tbf->ms(); gprs_rlcmac_trx *trx = ms_current_trx(ms); + struct gprs_rlcmac_pdch *first_common_ts = ms_first_common_ts(ms); LOGPAL(tbf, "A", single, use_trx, LOGL_DEBUG, "Alloc start\n"); @@ -365,11 +366,9 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, dl_slots = ms_reserved_dl_slots(ms); ul_slots = ms_reserved_ul_slots(ms); - ts = ms_first_common_ts(ms); - - if (ts >= 0) { + if (first_common_ts) { mask_reason = "need to reuse TS"; - mask = 1 << ts; + mask = 1 << first_common_ts->ts_no; } else if (dl_slots || ul_slots) { mask_reason = "need to use a reserved common TS"; mask = dl_slots & ul_slots; @@ -412,7 +411,7 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, tbf->trx = trx; /* the only one TS is the common TS */ ms_set_reserved_slots(ms, trx, 1 << ts, 1 << ts); - ms_set_first_common_ts(ms, ts); + ms_set_first_common_ts(ms, pdch); tbf->upgrade_to_multislot = false; bts_do_rate_ctr_inc(bts, CTR_TBF_ALLOC_ALGO_A); @@ -861,7 +860,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, uint8_t ul_slots; uint8_t reserved_dl_slots; uint8_t reserved_ul_slots; - int8_t first_common_ts; + int8_t first_common_tn; uint8_t slotcount = 0; uint8_t reserve_count = 0, trx_no; int first_ts; @@ -870,6 +869,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, int tfi; struct GprsMs *ms = tbf->ms(); gprs_rlcmac_trx *trx; + struct gprs_rlcmac_pdch *first_common_ts = ms_first_common_ts(ms); LOGPAL(tbf, "B", single, use_trx, LOGL_DEBUG, "Alloc start\n"); @@ -877,7 +877,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, reserved_dl_slots = ms_reserved_dl_slots(ms); reserved_ul_slots = ms_reserved_ul_slots(ms); - first_common_ts = ms_first_common_ts(ms); + first_common_tn = first_common_ts ? first_common_ts->ts_no : -1; /* Step 2a: Find usable TRX and TFI */ tfi = tfi_find_free(bts, ms, tbf->direction, use_trx, &trx_no); @@ -899,7 +899,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, /* Step 3a: Derive the slot set for the current TBF */ rc = tbf_select_slot_set(tbf, trx, single, ul_slots, dl_slots, reserved_ul_slots, reserved_dl_slots, - first_common_ts); + first_common_tn); if (rc < 0) return -EINVAL; @@ -924,11 +924,12 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, return -EINVAL; } - first_common_ts = ffs(dl_slots & ul_slots) - 1; - if (first_common_ts < 0) { + first_common_tn = ffs(dl_slots & ul_slots) - 1; + if (first_common_tn < 0) { LOGPAL(tbf, "B", single, use_trx, LOGL_NOTICE, "first common slot unavailable\n"); return -EINVAL; } + first_common_ts = &trx->pdch[first_common_tn]; if (single && slotcount) { tbf->upgrade_to_multislot = (reserve_count > slotcount); diff --git a/src/pcu_vty_functions.cpp b/src/pcu_vty_functions.cpp index 17aa2038..facc34c9 100644 --- a/src/pcu_vty_functions.cpp +++ b/src/pcu_vty_functions.cpp @@ -55,6 +55,7 @@ static void tbf_print_vty_info(struct vty *vty, struct gprs_rlcmac_tbf *tbf) gprs_rlcmac_dl_tbf *dl_tbf = tbf_as_dl_tbf(tbf); uint32_t state_flags = tbf_state_flags(tbf); struct GprsMs *ms = tbf_ms(tbf); + const struct gprs_rlcmac_pdch *first_common_ts = ms_first_common_ts(ms); vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) TA=%u DIR=%s IMSI=%s%s", tbf->tfi(), tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", @@ -66,7 +67,8 @@ static void tbf_print_vty_info(struct vty *vty, struct gprs_rlcmac_tbf *tbf) state_flags, state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH), state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH), - ms_first_common_ts(ms), tbf->control_ts, + first_common_ts ? first_common_ts->ts_no : -1, + tbf->control_ts, tbf->ms_class(), ms_egprs_ms_class(ms), VTY_NEWLINE); diff --git a/src/tbf.cpp b/src/tbf.cpp index 2cc60539..c934f078 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -279,14 +279,15 @@ uint16_t egprs_window_size(const struct gprs_rlcmac_bts *bts, uint8_t slots) void tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) { - int8_t first_common_ts = ms_first_common_ts(tbf_ms(tbf)); + struct gprs_rlcmac_pdch *first_common = ms_first_common_ts(tbf_ms(tbf)); + OSMO_ASSERT(first_common); if (tbf->control_ts == TBF_TS_UNSET) LOGPTBF(tbf, LOGL_INFO, "Setting Control TS %d\n", - first_common_ts); - else if (tbf->control_ts != first_common_ts) + first_common->ts_no); + else if (tbf->control_ts != first_common->ts_no) LOGPTBF(tbf, LOGL_INFO, "Changing Control TS %d -> %d\n", - tbf->control_ts, first_common_ts); - tbf->control_ts = first_common_ts; + tbf->control_ts, first_common->ts_no); + tbf->control_ts = first_common->ts_no; } void gprs_rlcmac_tbf::n_reset(enum tbf_counters n) @@ -706,13 +707,14 @@ uint8_t gprs_rlcmac_tbf::ul_slots() const { uint8_t slots = 0; size_t i; + struct gprs_rlcmac_pdch *first_common; if (direction == GPRS_RLCMAC_DL_TBF) { if (control_ts < 8) slots |= 1 << control_ts; - int8_t first_common_ts = ms_first_common_ts(tbf_ms(this)); - if (first_common_ts != TBF_TS_UNSET) - slots |= 1 << first_common_ts; + first_common = ms_first_common_ts(tbf_ms(this)); + if (first_common) + slots |= 1 << first_common->ts_no; return slots; } diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index b04c5117..a0e03985 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -166,7 +166,7 @@ struct gprs_rlcmac_ul_tbf *ul_tbf_alloc_rejected(struct gprs_rlcmac_bts *bts, st ul_tbf->trx = trx; /* The only one TS is the common, control TS */ - ms_set_first_common_ts(ms, pdch->ts_no); + ms_set_first_common_ts(ms, pdch); tbf_assign_control_ts(ul_tbf); ul_tbf->m_ctrs = rate_ctr_group_alloc(ul_tbf, &tbf_ctrg_desc, next_tbf_ctr_group_id++); ul_tbf->m_ul_egprs_ctrs = rate_ctr_group_alloc(ul_tbf, diff --git a/tests/alloc/AllocTest.cpp b/tests/alloc/AllocTest.cpp index 215a7aed..4b4fbd5d 100644 --- a/tests/alloc/AllocTest.cpp +++ b/tests/alloc/AllocTest.cpp @@ -177,12 +177,13 @@ static void dump_assignment(struct gprs_rlcmac_tbf *tbf, const char *dir, bool v if (!verbose) return; const struct GprsMs *ms = tbf_ms(tbf); + const struct gprs_rlcmac_pdch *first_common = ms_first_common_ts(ms); for (size_t i = 0; i < ARRAY_SIZE(tbf->pdch); ++i) if (tbf->pdch[i]) printf("PDCH[%zu] 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", ms_first_common_ts(ms), dir); + printf("PDCH[%d] is first common for %s\n", first_common ? first_common->ts_no : -1, dir); } #define ENABLE_PDCH(ts_no, enable_flag, trx) \ @@ -569,13 +570,13 @@ static unsigned alloc_many_tbfs(struct gprs_rlcmac_bts *bts, unsigned min_class, trx = ms_current_trx(ms); OSMO_ASSERT(ul_tbf || dl_tbf); - OSMO_ASSERT(ms_first_common_ts(ms) != TBF_TS_UNSET); + OSMO_ASSERT(ms_first_common_ts(ms) != NULL); if (ul_tbf) { - ul_slots = 1 << (uint8_t)ms_first_common_ts(ms); + ul_slots = 1 << (uint8_t)ms_first_common_ts(ms)->ts_no; tfi = ul_tbf->tfi(); dir = GPRS_RLCMAC_UL_TBF; } else { - ul_slots = 1 << (uint8_t)ms_first_common_ts(ms); + ul_slots = 1 << (uint8_t)ms_first_common_ts(ms)->ts_no; tfi = dl_tbf->tfi(); dir = GPRS_RLCMAC_DL_TBF; } diff --git a/tests/ulc/PdchUlcTest.cpp b/tests/ulc/PdchUlcTest.cpp index 2501f609..a1993115 100644 --- a/tests/ulc/PdchUlcTest.cpp +++ b/tests/ulc/PdchUlcTest.cpp @@ -169,6 +169,7 @@ int _alloc_algorithm_dummy(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf * bool single, int8_t use_tbf) { tbf->trx = &bts->trx[0]; + ms_set_first_common_ts(tbf_ms(tbf), &tbf->trx->pdch[0]); return 0; }