diff options
Diffstat (limited to 'src/tbf.cpp')
-rw-r--r-- | src/tbf.cpp | 405 |
1 files changed, 186 insertions, 219 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp index 69b9e3a..aedb9ae 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -28,7 +28,6 @@ #include <gprs_bssgp_pcu.h> #include <gprs_ms.h> #include <decoding.h> -#include <pcu_utils.h> extern "C" { #include <osmocom/core/msgb.h> @@ -39,9 +38,21 @@ extern "C" { #include <string.h> extern void *tall_pcu_ctx; - static void tbf_timer_cb(void *_tbf); +//Maximum Window Size according to number of allocated timeslots +uint16_t windowsizebyTS[9] = { + 64, // default value + 192, // 1 TS + 256, // 2 TS + 384, // 3 TS + 512, // 4 TS + 640, // 5 TS + 768, // 6 TS + 896, // 7 TS + 1024 // 8 TS + }; + gprs_rlcmac_tbf::Meas::Meas() : rssi_sum(0), rssi_num(0) @@ -61,7 +72,6 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : ul_ack_state(GPRS_RLCMAC_UL_ACK_NONE), poll_state(GPRS_RLCMAC_POLL_NONE), poll_fn(0), - poll_ts(0), n3105(0), T(0), num_T_exp(0), @@ -76,12 +86,12 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : m_ms(NULL), m_ta(0), m_ms_class(0), - m_list(this), m_ms_list(this), - m_egprs_enabled(false) + m_egprs_enabled(false) { /* The classes of these members do not have proper constructors yet. * Just set them to 0 like talloc_zero did */ + memset(&list, 0, sizeof(list)); memset(&pdch, 0, sizeof(pdch)); memset(&timer, 0, sizeof(timer)); memset(&m_rlc, 0, sizeof(m_rlc)); @@ -90,6 +100,9 @@ gprs_rlcmac_tbf::gprs_rlcmac_tbf(BTS *bts_, gprs_rlcmac_tbf_direction dir) : m_llc.init(); m_name_buf[0] = '\0'; + + /* Back pointer for PODS llist compatibility */ + list.back = this; } gprs_rlcmac_bts *gprs_rlcmac_tbf::bts_data() const @@ -167,15 +180,15 @@ void gprs_rlcmac_tbf::set_ms_class(uint8_t ms_class_) m_ms_class = ms_class_; } -GprsCodingScheme gprs_rlcmac_tbf::current_cs() const +uint8_t gprs_rlcmac_tbf::current_cs() const { - GprsCodingScheme cs; + uint8_t cs; if (direction == GPRS_RLCMAC_UL_TBF) - cs = m_ms ? m_ms->current_cs_ul() : GprsCodingScheme(); + cs = m_ms ? m_ms->current_cs_ul() : bts->bts_data()->initial_cs_ul; else - cs = m_ms ? m_ms->current_cs_dl() : GprsCodingScheme(); + cs = m_ms ? m_ms->current_cs_dl() : bts->bts_data()->initial_cs_dl; - return cs; + return cs < 1 ? 1 : cs; } gprs_llc_queue *gprs_rlcmac_tbf::llc_queue() @@ -311,23 +324,11 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) void tbf_free(struct gprs_rlcmac_tbf *tbf) { - /* update counters */ - if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - tbf->bts->tbf_ul_freed(); - if (tbf->state_is(GPRS_RLCMAC_FLOW)) - tbf->bts->tbf_ul_aborted(); - } else { - tbf->bts->tbf_dl_freed(); - if (tbf->state_is(GPRS_RLCMAC_FLOW)) - tbf->bts->tbf_dl_aborted(); - } - /* Give final measurement report */ gprs_rlcmac_rssi_rep(tbf); if (tbf->direction == GPRS_RLCMAC_DL_TBF) { - gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(tbf); - - dl_tbf->abort(); + gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(tbf); + gprs_rlcmac_lost_rep(dl_tbf); dl_tbf->cleanup(); } @@ -347,7 +348,12 @@ void tbf_free(struct gprs_rlcmac_tbf *tbf) tbf->stop_timer(); #warning "TODO: Could/Should generate bssgp_tx_llc_discarded" tbf_unlink_pdch(tbf); - llist_del(&tbf->list()); + llist_del(&tbf->list.list); + + if (tbf->direction == GPRS_RLCMAC_UL_TBF) + tbf->bts->tbf_ul_freed(); + else + tbf->bts->tbf_dl_freed(); if (tbf->ms()) tbf->set_ms(NULL); @@ -394,7 +400,6 @@ int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) const char *gprs_rlcmac_tbf::tbf_state_name[] = { "NULL", "ASSIGN", - "WAIT ASSIGN", "FLOW", "FINISHED", "WAIT RELEASE", @@ -436,53 +441,10 @@ void gprs_rlcmac_tbf::stop_timer() } } -int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts, - uint32_t *poll_fn_, unsigned int *rrbp_) -{ - uint32_t fn_offs = 13; - uint32_t new_poll_fn = (fn + fn_offs) % 2715648; - - if (!is_control_ts(ts)) { - LOGP(DRLCMAC, LOGL_DEBUG, "Polling cannot be " - "scheduled in this TS %d (first control TS %d)\n", - ts, control_ts); - return -EINVAL; - } - if (poll_state != GPRS_RLCMAC_POLL_NONE) { - LOGP(DRLCMAC, LOGL_DEBUG, - "Polling is already scheduled for %s\n", - name()); - return -EBUSY; - } - if (bts->sba()->find(trx->trx_no, ts, (fn + 13) % 2715648)) { - LOGP(DRLCMAC, LOGL_DEBUG, "%s: Polling is already scheduled " - "for single block allocation at FN %d TS %d ...\n", - name(), new_poll_fn, ts); - return -EBUSY; - } - - *poll_fn_ = new_poll_fn; - *rrbp_ = 0; - - return 0; -} - -void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts) -{ - LOGP(DRLCMAC, LOGL_DEBUG, - "%s: Scheduling polling at FN %d TS %d\n", - name(), new_poll_fn, ts); - - /* schedule polling */ - poll_state = GPRS_RLCMAC_POLL_SCHED; - poll_fn = new_poll_fn; - poll_ts = ts; -} - void gprs_rlcmac_tbf::poll_timeout() { - LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d, TS=%d (curr FN %d)\n", - tbf_name(this), poll_fn, poll_ts, bts->current_frame_number()); + LOGP(DRLCMAC, LOGL_NOTICE, "%s poll timeout for FN=%d (curr FN %d)\n", + tbf_name(this), poll_fn, bts->current_frame_number()); poll_state = GPRS_RLCMAC_POLL_NONE; @@ -496,7 +458,7 @@ void gprs_rlcmac_tbf::poll_timeout() ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; bts->rlc_ack_timedout(); if (state_is(GPRS_RLCMAC_FINISHED)) { - gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); + gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this); ul_tbf->m_n3103++; if (ul_tbf->m_n3103 == ul_tbf->bts->bts_data()->n3103) { LOGP(DRLCMAC, LOGL_NOTICE, @@ -550,7 +512,7 @@ void gprs_rlcmac_tbf::poll_timeout() /* reschedule DL assignment */ dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; } else if (direction == GPRS_RLCMAC_DL_TBF) { - gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this); if (!(dl_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ACK))) { LOGP(DRLCMAC, LOGL_NOTICE, "- Timeout for polling " @@ -596,11 +558,13 @@ static int setup_tbf(struct gprs_rlcmac_tbf *tbf, bts = tbf->bts->bts_data(); - if (ms->mode() == GprsCodingScheme::EGPRS) - ms_class = egprs_ms_class; - tbf->m_created_ts = time(NULL); - tbf->set_ms_class(ms_class); + if(!tbf->is_egprs_enabled()) + tbf->set_ms_class(ms_class); + + else + tbf->set_ms_class(egprs_ms_class); + /* select algorithm */ rc = bts->alloc_algorithm(bts, ms, tbf, bts->alloc_algorithm_curst, single_slot, use_trx); @@ -643,17 +607,6 @@ static int ul_tbf_dtor(struct gprs_rlcmac_ul_tbf *tbf) return 0; } -static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms) -{ - if (GprsCodingScheme::getEgprsByNum(bts->max_mcs_ul).isEgprsGmsk() && - GprsCodingScheme::getEgprsByNum(bts->max_mcs_dl).isEgprsGmsk() && - ms->mode() != GprsCodingScheme::EGPRS) - { - ms->set_mode(GprsCodingScheme::EGPRS_GMSK); - } else { - ms->set_mode(GprsCodingScheme::EGPRS); - } -} struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, GprsMs *ms, int8_t use_trx, @@ -662,13 +615,6 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_ul_tbf *tbf; int rc; - if (egprs_ms_class == 0 && bts->egprs_enabled) { - LOGP(DRLCMAC, LOGL_NOTICE, - "Not accepting non-EGPRS phone in EGPRS-only mode\n"); - bts->bts->tbf_failed_egprs_only(); - return NULL; - } - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n", "UL", ms_class, egprs_ms_class); @@ -685,13 +631,10 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); if (egprs_ms_class > 0 && bts->egprs_enabled) { + /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ tbf->enable_egprs(); tbf->m_window.set_sns(RLC_EGPRS_SNS); - /* TODO: Allow bigger UL windows when CRBB encoding is supported */ tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); - setup_egprs_mode(bts, ms); - LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", - tbf->name(), GprsCodingScheme::modeName(ms->mode())); } rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); @@ -701,7 +644,7 @@ struct gprs_rlcmac_ul_tbf *tbf_alloc_ul_tbf(struct gprs_rlcmac_bts *bts, return NULL; } - llist_add(&tbf->list(), &bts->bts->ul_tbfs()); + llist_add(&tbf->list.list, &bts->ul_tbfs); tbf->bts->tbf_ul_created(); return tbf; @@ -734,25 +677,15 @@ static int dl_tbf_dtor(struct gprs_rlcmac_dl_tbf *tbf) } struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, - GprsMs *ms, int8_t use_trx, - uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot) + GprsMs *ms, int8_t use_trx, + uint8_t ms_class, uint8_t egprs_ms_class, uint8_t single_slot) { struct gprs_rlcmac_dl_tbf *tbf; - int rc; - - if (egprs_ms_class == 0 && bts->egprs_enabled) { - if (ms_class > 0) { - LOGP(DRLCMAC, LOGL_NOTICE, - "Not accepting non-EGPRS phone in EGPRS-only mode\n"); - bts->bts->tbf_failed_egprs_only(); - return NULL; - } - egprs_ms_class = 1; - } + int rc = -1; LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); - LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d/%d\n", - "DL", ms_class, egprs_ms_class); + LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: MS_CLASS=%d\n", + "DL", ms_class); tbf = talloc(tall_pcu_ctx, struct gprs_rlcmac_dl_tbf); @@ -762,40 +695,25 @@ struct gprs_rlcmac_dl_tbf *tbf_alloc_dl_tbf(struct gprs_rlcmac_bts *bts, talloc_set_destructor(tbf, dl_tbf_dtor); new (tbf) gprs_rlcmac_dl_tbf(bts->bts); - if (!ms) - ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); - if (egprs_ms_class > 0 && bts->egprs_enabled) { - tbf->enable_egprs(); - tbf->m_window.set_sns(RLC_EGPRS_SNS); - setup_egprs_mode(bts, ms); - LOGP(DRLCMAC, LOGL_INFO, "Enabled EGPRS for %s, mode %s\n", - tbf->name(), GprsCodingScheme::modeName(ms->mode())); - } + /* TODO: only for 8PSK, otherwise the GPRS MS class has to be used */ + tbf->enable_egprs(); + tbf->m_window.set_sns(RLC_EGPRS_SNS); + tbf->m_window.set_ws(RLC_EGPRS_MIN_WS); + } - rc = setup_tbf(tbf, ms, use_trx, ms_class, 0, single_slot); + if (!ms) + { + ms = bts->bts->ms_alloc(ms_class, egprs_ms_class); + } + rc = setup_tbf(tbf, ms, use_trx, ms_class, egprs_ms_class, single_slot); /* if no resource */ if (rc < 0) { talloc_free(tbf); return NULL; } - if (tbf->is_egprs_enabled()) { - unsigned int num_pdch = pcu_bitcount(tbf->dl_slots()); - unsigned int ws = bts->ws_base + num_pdch * bts->ws_pdch; - ws = (ws / 32) * 32; - ws = OSMO_MAX(64, ws); - if (num_pdch == 1) - ws = OSMO_MIN(192, ws); - else - ws = OSMO_MIN(128 * num_pdch, ws); - - LOGP(DRLCMAC, LOGL_INFO, "%s: Setting EGPRS window size to %d\n", - tbf->name(), ws); - tbf->m_window.set_ws(ws); - } - - llist_add(&tbf->list(), &bts->bts->dl_tbfs()); + llist_add(&tbf->list.list, &bts->dl_tbfs); tbf->bts->tbf_dl_created(); tbf->m_last_dl_poll_fn = -1; @@ -825,12 +743,6 @@ void gprs_rlcmac_tbf::handle_timeout() if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { if (state_is(GPRS_RLCMAC_ASSIGN)) { LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " - "PACCH assignment timeout (not yet sent).\n", - tbf_name(this)); - tbf_free(this); - return; - } else if (state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { - LOGP(DRLCMAC, LOGL_NOTICE, "%s releasing due to " "PACCH assignment timeout.\n", tbf_name(this)); tbf_free(this); return; @@ -839,9 +751,9 @@ void gprs_rlcmac_tbf::handle_timeout() "in assign state\n", tbf_name(this)); } if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { - gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this); + gprs_rlcmac_dl_tbf *dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this); dl_tbf->m_wait_confirm = 0; - if (dl_tbf->state_is(GPRS_RLCMAC_WAIT_ASSIGN)) { + if (dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) { tbf_assign_control_ts(dl_tbf); if (!dl_tbf->upgrade_to_multislot) { @@ -858,6 +770,7 @@ void gprs_rlcmac_tbf::handle_timeout() /* keep to flags */ dl_tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; + dl_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); dl_tbf->update(); @@ -905,40 +818,37 @@ int gprs_rlcmac_tbf::rlcmac_diag() return 0; } -struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) +struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) { struct msgb *msg; struct gprs_rlcmac_dl_tbf *new_dl_tbf = NULL; int poll_ass_dl = 1; - unsigned int rrbp = 0; - uint32_t new_poll_fn = 0; - int rc; - bool old_tfi_is_valid = is_tfi_assigned(); - - if (direction == GPRS_RLCMAC_DL_TBF && !is_control_ts(ts)) { + int nbofdlts = 0, i; + uint16_t window_size, new_ws; + if (direction == GPRS_RLCMAC_DL_TBF && control_ts != first_common_ts) { LOGP(DRLCMAC, LOGL_NOTICE, "Cannot poll for downlink " - "assigment, because MS cannot reply. (TS=%d, " - "first common TS=%d)\n", ts, + "assigment, because MS cannot reply. (control TS=%d, " + "first common TS=%d)\n", control_ts, first_common_ts); poll_ass_dl = 0; } if (poll_ass_dl) { - if (poll_state == GPRS_RLCMAC_POLL_SCHED && - ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) - { - LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "scheduled for %s, so we must wait for the uplink " + if (poll_state != GPRS_RLCMAC_POLL_NONE) { + LOGP(DRLCMAC, LOGL_DEBUG, "Polling is already sheduled " + "for %s, so we must wait for downlink " "assignment...\n", tbf_name(this)); - return NULL; + return NULL; } - rc = check_polling(fn, ts, &new_poll_fn, &rrbp); - if (rc < 0) + if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) { + LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " + "scheduled for single block allocation...\n"); return NULL; + } } /* on uplink TBF we get the downlink TBF to be assigned. */ if (direction == GPRS_RLCMAC_UL_TBF) { - gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); + gprs_rlcmac_ul_tbf *ul_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this); /* be sure to check first, if contention resolution is done, * otherwise we cannot send the assignment yet */ @@ -960,19 +870,23 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; return NULL; } + if(is_egprs_enabled()) { + for (i = 0; i < 8; i++) { + if (new_dl_tbf->pdch[i]) + nbofdlts++; + } - if (new_dl_tbf == as_dl_tbf(this)) - LOGP(DRLCMAC, LOGL_DEBUG, - "New and old TBF are the same %s\n", name()); + new_ws = windowsizebyTS[nbofdlts]; - if (old_tfi_is_valid && !new_dl_tbf->is_tlli_valid()) { - LOGP(DRLCMACDL, LOGL_ERROR, - "The old TFI is not assigned and there is no " - "TLLI. Old TBF %s, new TBF %s\n", - name(), new_dl_tbf->name()); - dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - return NULL; + if (new_ws > (new_dl_tbf->m_window.ws())) + new_dl_tbf->m_window.set_ws(new_ws); + + + window_size = new_dl_tbf->m_window.ws(); + LOGP(DRLCMACDL, LOGL_ERROR, " New Window_size is assigned in" + "create_DL_ASS %d\n",window_size); } + window_size = new_dl_tbf->m_window.ws(); new_dl_tbf->was_releasing = was_releasing; msg = msgb_alloc(23, "rlcmac_dl_ass"); @@ -983,15 +897,15 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) msgb_free(msg); return NULL; } + bitvec_unhex(ass_vec, "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); LOGP(DRLCMAC, LOGL_INFO, "%s start Packet Downlink Assignment (PACCH)\n", tbf_name(new_dl_tbf)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); - Encoding::write_packet_downlink_assignment(mac_control_block, - old_tfi_is_valid, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), - new_dl_tbf, poll_ass_dl, rrbp, - bts_data()->alpha, bts_data()->gamma, -1, 0, - is_egprs_enabled()); + Encoding::write_packet_downlink_assignment(mac_control_block, m_tfi, + (direction == GPRS_RLCMAC_DL_TBF), new_dl_tbf, + poll_ass_dl, bts_data()->alpha, bts_data()->gamma, -1, 0, + window_size); LOGP(DRLCMAC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n"); encode_gsm_rlcmac_downlink(ass_vec, mac_control_block); LOGPC(DCSN1, LOGL_NOTICE, "\n"); @@ -1001,13 +915,12 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) talloc_free(mac_control_block); if (poll_ass_dl) { - set_polling(new_poll_fn, ts); - if (new_dl_tbf->state_is(GPRS_RLCMAC_ASSIGN)) - new_dl_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); + poll_state = GPRS_RLCMAC_POLL_SCHED; + poll_fn = (fn + 13) % 2715648; dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGP(DRLCMACDL, LOGL_INFO, - "%s Scheduled DL Assignment polling on FN=%d, TS=%d\n", - name(), poll_fn, poll_ts); + "%s Scheduled DL Assignment polling on FN=%d\n", + name(), poll_fn); } else { dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; new_dl_tbf->set_state(GPRS_RLCMAC_FLOW); @@ -1020,25 +933,25 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) return msg; } -struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) +struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn) { struct msgb *msg; struct gprs_rlcmac_ul_tbf *new_tbf = NULL; - int rc; - unsigned int rrbp; - uint32_t new_poll_fn; + + int nbofults = 0, i; + uint16_t new_ws; - if (poll_state == GPRS_RLCMAC_POLL_SCHED && - ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { + if (poll_state != GPRS_RLCMAC_POLL_NONE) { LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already " - "scheduled for %s, so we must wait for the uplink " + "sheduled for %s, so we must wait for uplink " "assignment...\n", tbf_name(this)); return NULL; } - - rc = check_polling(fn, ts, &new_poll_fn, &rrbp); - if (rc < 0) - return NULL; + if (bts->sba()->find(trx->trx_no, control_ts, (fn + 13) % 2715648)) { + LOGP(DRLCMACUL, LOGL_DEBUG, "Polling is already scheduled for " + "single block allocation...\n"); + return NULL; + } if (ms()) new_tbf = ms()->ul_tbf(); @@ -1050,6 +963,19 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) return NULL; } + if(is_egprs_enabled()) { + for (i = 0; i < 8; i++) { + if (new_tbf->pdch[i]) + nbofults++; + } + new_ws = windowsizebyTS[nbofults]; + + if (new_ws > (new_tbf->m_window.ws())) + new_tbf->m_window.set_ws(new_ws); + + LOGP(DRLCMACDL, LOGL_ERROR, "New Window_size assigned in" + " create_UL_ASS %d\n",new_tbf->m_window.ws()); + } msg = msgb_alloc(23, "rlcmac_ul_ass"); if (!msg) return NULL; @@ -1063,7 +989,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) "2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"); Encoding::write_packet_uplink_assignment(bts_data(), ass_vec, m_tfi, (direction == GPRS_RLCMAC_DL_TBF), tlli(), - is_tlli_valid(), new_tbf, 1, rrbp, bts_data()->alpha, + is_tlli_valid(), new_tbf, 1, bts_data()->alpha, bts_data()->gamma, -1, is_egprs_enabled()); bitvec_pack(ass_vec, msgb_put(msg, 23)); RlcMacDownlink_t * mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t); @@ -1074,13 +1000,12 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) bitvec_free(ass_vec); talloc_free(mac_control_block); - set_polling(new_poll_fn, ts); + poll_state = GPRS_RLCMAC_POLL_SCHED; + poll_fn = (fn + 13) % 2715648; ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; - if (new_tbf->state_is(GPRS_RLCMAC_ASSIGN)) - new_tbf->set_state(GPRS_RLCMAC_WAIT_ASSIGN); LOGP(DRLCMACDL, LOGL_INFO, - "%s Scheduled UL Assignment polling on FN=%d, TS=%d\n", - name(), poll_fn, poll_ts); + "%s Scheduled UL Assignment polling on FN=%d\n", + name(), poll_fn); return msg; } @@ -1110,11 +1035,9 @@ int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch() struct gprs_rlcmac_dl_tbf *new_tbf = NULL; bts->tbf_reused(); - new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), ms(), this->trx->trx_no, ms_class(), ms() ? ms()->egprs_ms_class() : 0, 0); - if (!new_tbf) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); return -1; @@ -1126,7 +1049,6 @@ int gprs_rlcmac_tbf::establish_dl_tbf_on_pacch() return 0; } - int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) { struct gprs_rlcmac_tbf *dl_tbf = NULL; @@ -1145,8 +1067,15 @@ int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) if (!ms()) set_ms(old_ms); + + /* there might be an active and valid downlink TBF */ + if (!ms()->dl_tbf() && dl_tbf) + /* Move it to the current MS (see the guard above) */ + dl_tbf->set_ms(ms()); } + /* The TLLI has been taken from an UL message */ + update_ms(new_tlli, GPRS_RLCMAC_UL_TBF); if (dl_tbf && dl_tbf->ms() != ms()) { LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from " "TLLI=0x%08x while %s still exists. " @@ -1163,15 +1092,34 @@ int gprs_rlcmac_tbf::set_tlli_from_ul(uint32_t new_tlli) tbf_free(ul_tbf); ul_tbf = NULL; } + return 1; +} - /* The TLLI has been taken from an UL message */ - update_ms(new_tlli, GPRS_RLCMAC_UL_TBF); +int gprs_rlcmac_tbf::extract_tlli(const uint8_t *data, const size_t len) +{ + struct rlc_ul_header *rh = (struct rlc_ul_header *)data; + uint32_t new_tlli; + int rc; -#if 0 /* REMOVEME ??? */ - if (ms()->need_dl_tbf()) - establish_dl_tbf_on_pacch(); -#endif - return 1; + OSMO_ASSERT(direction == GPRS_RLCMAC_UL_TBF); + + /* no TLLI yet */ + if (!rh->ti) { + LOGP(DRLCMACUL, LOGL_NOTICE, "UL DATA TFI=%d without " + "TLLI, but no TLLI received yet\n", rh->tfi); + return 0; + } + rc = Decoding::tlli_from_ul_data(data, len, &new_tlli); + if (rc) { + bts->decode_error(); + LOGP(DRLCMACUL, LOGL_NOTICE, "Failed to decode TLLI " + "of UL DATA TFI=%d.\n", rh->tfi); + return 0; + } + LOGP(DRLCMACUL, LOGL_INFO, "Decoded premier TLLI=0x%08x of " + "UL DATA TFI=%d.\n", new_tlli, rh->tfi); + + return set_tlli_from_ul(new_tlli); } const char *tbf_name(gprs_rlcmac_tbf *tbf) @@ -1197,11 +1145,11 @@ const char *gprs_rlcmac_tbf::name() const void gprs_rlcmac_tbf::rotate_in_list() { - llist_del(&list()); + llist_del(&list.list); if (direction == GPRS_RLCMAC_UL_TBF) - llist_add(&list(), &bts->ul_tbfs()); + llist_add(&list.list, &bts->bts_data()->ul_tbfs); else - llist_add(&list(), &bts->dl_tbfs()); + llist_add(&list.list, &bts->bts_data()->dl_tbfs); } uint8_t gprs_rlcmac_tbf::tsc() const @@ -1209,6 +1157,8 @@ uint8_t gprs_rlcmac_tbf::tsc() const return trx->pdch[first_ts].tsc; } + + uint8_t gprs_rlcmac_tbf::dl_slots() const { uint8_t slots = 0; @@ -1245,7 +1195,24 @@ uint8_t gprs_rlcmac_tbf::ul_slots() const return slots; } -bool gprs_rlcmac_tbf::is_control_ts(uint8_t ts) const +void tbf_print_vty_info(struct vty *vty, struct llist_head *ltbf) { - return ts == control_ts; + gprs_rlcmac_tbf *tbf = llist_pods_entry(ltbf, gprs_rlcmac_tbf); + + vty_out(vty, "TBF: TFI=%d TLLI=0x%08x (%s) DIR=%s IMSI=%s%s", tbf->tfi(), + tbf->tlli(), tbf->is_tlli_valid() ? "valid" : "invalid", + tbf->direction == GPRS_RLCMAC_UL_TBF ? "UL" : "DL", + tbf->imsi(), VTY_NEWLINE); + vty_out(vty, " created=%lu state=%08x 1st_TS=%d 1st_cTS=%d ctrl_TS=%d " + "MS_CLASS=%d%s", + tbf->created_ts(), tbf->state_flags, tbf->first_ts, + tbf->first_common_ts, tbf->control_ts, tbf->ms_class(), + VTY_NEWLINE); + vty_out(vty, " TS_alloc="); + for (int i = 0; i < 8; i++) { + if (tbf->pdch[i]) + vty_out(vty, "%d ", i); + } + vty_out(vty, " CS=%d%s%s", tbf->ms() ? tbf->ms()->current_cs_dl() : 1, + VTY_NEWLINE, VTY_NEWLINE); } |