diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bts.cpp | 54 | ||||
-rw-r--r-- | src/tbf.cpp | 21 | ||||
-rw-r--r-- | src/tbf.h | 10 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 33 |
4 files changed, 83 insertions, 35 deletions
diff --git a/src/bts.cpp b/src/bts.cpp index 86659621..b6600144 100644 --- a/src/bts.cpp +++ b/src/bts.cpp @@ -511,9 +511,12 @@ void BTS::trigger_dl_ass( LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment on " "PACCH, because %s exists\n", tbf_name(old_tbf)); old_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; + + old_tbf->set_new_tbf(dl_tbf); + old_tbf->was_releasing = old_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); + /* use TA from old TBF */ dl_tbf->ta = old_tbf->ta; - dl_tbf->was_releasing = dl_tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE); /* change state */ dl_tbf->set_state(GPRS_RLCMAC_ASSIGN); dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); @@ -530,6 +533,7 @@ void BTS::trigger_dl_ass( dl_tbf->set_state(GPRS_RLCMAC_ASSIGN); dl_tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_CCCH); dl_tbf->assign_imsi(imsi); + dl_tbf->set_new_tbf(dl_tbf); /* send immediate assignment */ dl_tbf->bts->snd_dl_ass(dl_tbf, 0, imsi); dl_tbf->m_wait_confirm = 1; @@ -729,7 +733,7 @@ int gprs_rlcmac_pdch::rcv_data_block_acknowledged(uint8_t *data, uint8_t len, in void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, uint32_t fn) { - struct gprs_rlcmac_tbf *tbf; + struct gprs_rlcmac_tbf *tbf, *new_tbf; uint32_t tlli = 0; tlli = packet->TLLI; @@ -766,25 +770,27 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, /* reset N3105 */ tbf->n3105 = 0; tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; - if (tbf->direction == GPRS_RLCMAC_UL_TBF) - tbf = bts()->dl_tbf_by_tlli(tbf->tlli()); -#warning "TBF is changing on the way... *sigh*" - if (!tbf) { + + new_tbf = tbf->new_tbf(); + if (!new_tbf) { LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but DL " "TBF is gone TLLI=0x%08x\n", tlli); return; } - tbf->set_state(GPRS_RLCMAC_FLOW); + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) + tbf_free(tbf); + + new_tbf->set_state(GPRS_RLCMAC_FLOW); /* stop pending assignment timer */ - tbf->stop_timer(); - if ((tbf->state_flags & + new_tbf->stop_timer(); + if ((new_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_DL_ASS))) { - tbf->state_flags &= + new_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_DL_ASS); LOGP(DRLCMAC, LOGL_NOTICE, "Recovered downlink " - "assignment for %s\n", tbf_name(tbf)); + "assignment for %s\n", tbf_name(new_tbf)); } - tbf_assign_control_ts(tbf); + tbf_assign_control_ts(new_tbf); return; } if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_WAIT_ACK) { @@ -792,23 +798,25 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, /* reset N3105 */ tbf->n3105 = 0; tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_NONE; -#warning "TBF is changing on the way... *sigh*" - if (tbf->direction == GPRS_RLCMAC_DL_TBF) - tbf = bts()->ul_tbf_by_tlli(tbf->tlli()); - if (!tbf) { + + new_tbf = tbf->new_tbf(); + if (!new_tbf) { LOGP(DRLCMAC, LOGL_ERROR, "Got ACK, but UL " "TBF is gone TLLI=0x%08x\n", tlli); return; } - tbf->set_state(GPRS_RLCMAC_FLOW); - if ((tbf->state_flags & + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) + tbf_free(tbf); + + new_tbf->set_state(GPRS_RLCMAC_FLOW); + if ((new_tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_TO_UL_ASS))) { - tbf->state_flags &= + new_tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_TO_UL_ASS); LOGP(DRLCMAC, LOGL_NOTICE, "Recovered uplink " - "assignment for UL %s\n", tbf_name(tbf)); + "assignment for UL %s\n", tbf_name(new_tbf)); } - tbf_assign_control_ts(tbf); + tbf_assign_control_ts(new_tbf); return; } LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK " @@ -858,7 +866,7 @@ void gprs_rlcmac_pdch::rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *ack_n if (ack_nack->Exist_Channel_Request_Description) { LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " "message, so we provide one:\n"); - tbf_alloc_ul(bts_data(), tbf->trx->trx_no, tbf->ms_class, tbf->tlli(), tbf->ta, tbf); + tbf->set_new_tbf(tbf_alloc_ul(bts_data(), tbf->trx->trx_no, tbf->ms_class, tbf->tlli(), tbf->ta, tbf)); /* schedule uplink assignment */ tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; } @@ -920,6 +928,8 @@ void gprs_rlcmac_pdch::rcv_resource_request(Packet_Resource_Request_t *request, ul_tbf = tbf_alloc_ul(bts_data(), trx_no(), ms_class, tlli, ta, NULL); if (!ul_tbf) return; + + ul_tbf->set_new_tbf(ul_tbf); /* set control ts to current MS's TS, until assignment complete */ LOGP(DRLCMAC, LOGL_DEBUG, "Change control TS to %d until assinment is complete.\n", ts_no); ul_tbf->control_ts = ts_no; diff --git a/src/tbf.cpp b/src/tbf.cpp index ccf73627..2afe2576 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -51,6 +51,11 @@ void gprs_rlcmac_tbf::assign_imsi(const char *imsi) m_imsi[sizeof(m_imsi) - 1] = '\0'; } +void gprs_rlcmac_tbf::set_new_tbf(gprs_rlcmac_tbf *tbf) +{ + m_new_tbf = tbf; +} + gprs_rlcmac_ul_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, int8_t use_trx, uint8_t ms_class, uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf) @@ -557,10 +562,10 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn) "finished.\n"); return NULL; } - #warning "THIS should probably go over the IMSI too" - new_dl_tbf = ul_tbf->bts->dl_tbf_by_tlli(m_tlli); - } else - new_dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(this); + } + + new_dl_tbf = static_cast<gprs_rlcmac_dl_tbf *>(m_new_tbf); + new_dl_tbf->was_releasing = was_releasing; if (!new_dl_tbf) { LOGP(DRLCMACDL, LOGL_ERROR, "We have a schedule for downlink " "assignment at uplink %s, but there is no downlink " @@ -625,13 +630,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn) return NULL; } - /* on down TBF we get the uplink TBF to be assigned. */ -#warning "Probably want to find by IMSI too" - if (direction == GPRS_RLCMAC_DL_TBF) - new_tbf = bts->ul_tbf_by_tlli(m_tlli); - else - new_tbf = static_cast<gprs_rlcmac_ul_tbf *>(this); - + new_tbf = static_cast<gprs_rlcmac_ul_tbf *>(m_new_tbf); if (!new_tbf) { LOGP(DRLCMACUL, LOGL_ERROR, "We have a schedule for uplink " "assignment at downlink %s, but there is no uplink " @@ -142,6 +142,9 @@ struct gprs_rlcmac_tbf { const char *imsi() const; void assign_imsi(const char *imsi); + void set_new_tbf(gprs_rlcmac_tbf *tbf); + gprs_rlcmac_tbf *new_tbf() const; + time_t created_ts() const; /* attempt to make things a bit more fair */ @@ -165,6 +168,8 @@ struct gprs_rlcmac_tbf { enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; + gprs_rlcmac_tbf *m_new_tbf; + enum gprs_rlcmac_tbf_poll_state poll_state; uint32_t poll_fn; /* frame number to poll */ @@ -289,6 +294,11 @@ inline const char *gprs_rlcmac_tbf::imsi() const return m_imsi; } +inline gprs_rlcmac_tbf *gprs_rlcmac_tbf::new_tbf() const +{ + return m_new_tbf; +} + inline time_t gprs_rlcmac_tbf::created_ts() const { return m_created_ts; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 8abea201..a715af78 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -643,10 +643,39 @@ int gprs_rlcmac_dl_tbf::rcvd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb void gprs_rlcmac_dl_tbf::reuse_tbf(const uint8_t *data, const uint16_t len) { + uint8_t trx; + struct gprs_rlcmac_dl_tbf *new_tbf; + int8_t tfi; /* must be signed */ + int rc; + struct msgb *msg; + bts->tbf_reused(); - m_llc.put_frame(data, len); + + tfi = bts->tfi_find_free(GPRS_RLCMAC_DL_TBF, &trx, this->trx->trx_no); + if (tfi < 0) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); + /* FIXME: send reject */ + return; + } + new_tbf = tbf_alloc_dl_tbf(bts->bts_data(), NULL, tfi, trx, ms_class, 0); + if (!new_tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); + /* FIXME: send reject */ + return; + } + + new_tbf->m_tlli = m_tlli; + new_tbf->m_tlli_valid = m_tlli_valid; + new_tbf->ta = ta; + new_tbf->assign_imsi(m_imsi); + + /* Copy over all data to the new TBF */ + new_tbf->m_llc.put_frame(data, len); bts->llc_frame_sched(); + while ((msg = m_llc.dequeue())) + new_tbf->m_llc.enqueue(msg); + /* reset rlc states */ m_tx_counter = 0; m_wait_confirm = 0; @@ -661,7 +690,7 @@ void gprs_rlcmac_dl_tbf::reuse_tbf(const uint8_t *data, const uint16_t len) LOGP(DRLCMAC, LOGL_DEBUG, "%s Trigger dowlink assignment on PACCH, " "because another LLC PDU has arrived in between\n", tbf_name(this)); - bts->trigger_dl_ass(this, this, NULL); + bts->trigger_dl_ass(new_tbf, this, NULL); } bool gprs_rlcmac_dl_tbf::dl_window_stalled() const |