diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index 9899580e..009dfcb2 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -188,6 +188,9 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( const struct gprs_rlc_data_info *rlc, uint8_t *data, struct pcu_l1_meas *meas) { + const struct gprs_rlc_data_block_info *rdbi; + struct gprs_rlc_data *block; + int8_t rssi = meas->have_rssi ? meas->rssi : 0; const uint16_t ws = m_window.ws(); @@ -218,10 +221,8 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( for (block_idx = 0; block_idx < rlc->num_data_blocks; block_idx++) { int num_chunks; uint8_t *rlc_data; - const struct gprs_rlc_data_block_info *rdbi = - &rlc->block_info[block_idx]; + rdbi = &rlc->block_info[block_idx]; bool need_rlc_data = false; - struct gprs_rlc_data *block; LOGPTBFUL(this, LOGL_DEBUG, "Got %s RLC data block: CV=%d, BSN=%d, SPB=%d, PI=%d, E=%d, TI=%d, bitoffs=%d\n", @@ -330,14 +331,13 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( assemble_forward_llc(m_rlc.block(index)); } - /* Check CV of last frame in buffer */ + /* Last frame in buffer: */ + block = m_rlc.block(m_window.mod_sns(m_window.v_r() - 1)); + rdbi = &block->block_info; + + /* Check if we already received all data TBF had to send: */ if (this->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */ && this->m_window.v_q() == this->m_window.v_r()) { /* if complete */ - struct gprs_rlc_data *block = - m_rlc.block(m_window.mod_sns(m_window.v_r() - 1)); - const struct gprs_rlc_data_block_info *rdbi = - &block->block_info; - LOGPTBFUL(this, LOGL_DEBUG, "No gaps in received block, last block: BSN=%d CV=%d\n", rdbi->bsn, rdbi->cv); @@ -351,13 +351,13 @@ int gprs_rlcmac_ul_tbf::rcv_data_block_acknowledged( /* If TLLI is included or if we received half of the window, we send * an ack/nack */ - maybe_schedule_uplink_acknack(rlc); + maybe_schedule_uplink_acknack(rlc, rdbi->cv == 0); return 0; } void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack( - const gprs_rlc_data_info *rlc) + const gprs_rlc_data_info *rlc, bool countdown_finished) { bool require_ack = false; bool have_ti = rlc->block_info[0].ti || @@ -373,10 +373,14 @@ void gprs_rlcmac_ul_tbf::maybe_schedule_uplink_acknack( LOGPTBFUL(this, LOGL_DEBUG, "Scheduling Ack/Nack, because TLLI is included.\n"); } - if (state_is(GPRS_RLCMAC_FINISHED)) { + if (countdown_finished) { require_ack = true; - LOGPTBFUL(this, LOGL_DEBUG, - "Scheduling final Ack/Nack, because all data was received and last block has CV==0.\n"); + if (state_is(GPRS_RLCMAC_FLOW)) + LOGPTBFUL(this, LOGL_DEBUG, + "Scheduling Ack/Nack, because some data is missing and last block has CV==0.\n"); + else if (state_is(GPRS_RLCMAC_FINISHED)) + LOGPTBFUL(this, LOGL_DEBUG, + "Scheduling final Ack/Nack, because all data was received and last block has CV==0.\n"); } if ((m_rx_counter % SEND_ACK_AFTER_FRAMES) == 0) { require_ack = true; diff --git a/src/tbf_ul.h b/src/tbf_ul.h index 85da4f61..c6df0cd8 100644 --- a/src/tbf_ul.h +++ b/src/tbf_ul.h @@ -21,6 +21,8 @@ #ifdef __cplusplus +#include + #include "tbf.h" /* * TBF instance @@ -97,7 +99,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { struct rate_ctr_group *m_ul_egprs_ctrs; protected: - void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc); + void maybe_schedule_uplink_acknack(const gprs_rlc_data_info *rlc, bool countdown_finished); /* Please note that all variables below will be reset when changing * from WAIT RELEASE back to FLOW state (re-use of TBF). diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 36f9ceda..3f2925a4 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -1459,6 +1459,7 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS pdch = &the_bts->bts_data()->trx[trx_no].pdch[ts_no]; pdch->rcv_block(&data[0], sizeof(data), *fn, &meas); + ul_tbf->create_ul_ack(*fn, ts_no); request_dl_rlc_block(ul_tbf, fn); diff --git a/tests/tbf/TbfTest.err b/tests/tbf/TbfTest.err index a1530c18..57787c5a 100644 --- a/tests/tbf/TbfTest.err +++ b/tests/tbf/TbfTest.err @@ -7193,6 +7193,9 @@ TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) restarting timer T3169 [acked TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) Got MCS-4 RLC data block: CV=0, BSN=64, SPB=0, PI=0, E=1, TI=0, bitoffs=33 TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) BSN 64 storing in window (1..192) TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) data_length=44, data=80 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 95 +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) Scheduling Ack/Nack, because some data is missing and last block has CV==0. +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) changes UL ACK state from GPRS_RLCMAC_UL_ACK_NONE to GPRS_RLCMAC_UL_ACK_SEND_ACK +TBF(TFI=0 TLLI=0xf1223344 DIR=UL STATE=FLOW EGPRS) changes UL ACK state from GPRS_RLCMAC_UL_ACK_SEND_ACK to GPRS_RLCMAC_UL_ACK_NONE Received RTS for PDCH: TRX=0 TS=7 FN=2654279 block_nr=10 scheduling USF=0 for required uplink resource of UL TFI=0 TBF(TFI=0 TLLI=0xf1223344 DIR=DL STATE=ASSIGN EGPRS) start Packet Downlink Assignment (PACCH) +++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++