diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c index df7cd7d5..6384fd59 100644 --- a/src/nacc_fsm.c +++ b/src/nacc_fsm.c @@ -206,7 +206,7 @@ static struct msgb *create_packet_cell_chg_continue(const struct nacc_fsm_ctx *c LOGP(DNACC, LOGL_DEBUG, "------------------------- TX : Packet Cell Change Continue -------------------------\n"); rate_ctr_inc(&bts_rate_counters(ms->bts)->ctr[CTR_PKT_CELL_CHG_CONTINUE]); talloc_free(mac_control_block); - tbf_set_polling(tbf, *new_poll_fn, data->ts, GPRS_RLCMAC_POLL_CELL_CHG_CONTINUE); + tbf_set_polling(tbf, *new_poll_fn, data->ts, PDCH_ULC_POLL_CELL_CHG_CONTINUE); return msg; free_ret: diff --git a/src/pdch.cpp b/src/pdch.cpp index 45c7c984..22bac0bd 100644 --- a/src/pdch.cpp +++ b/src/pdch.cpp @@ -306,6 +306,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, uint32_t tlli = packet->TLLI; GprsMs *ms = bts_ms_by_tlli(bts(), tlli, GSM_RESERVED_TMSI); gprs_rlcmac_ul_tbf *ul_tbf; + enum pdch_ulc_tbf_poll_reason reason; struct pdch_ulc_node *poll; poll = pdch_ulc_get_node(ulc, fn); @@ -325,6 +326,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, return; } tbf = poll->tbf_poll.poll_tbf; + reason = poll->tbf_poll.reason; /* Reset N3101 counter: */ tbf->n_reset(N3101); @@ -337,7 +339,7 @@ void gprs_rlcmac_pdch::rcv_control_ack(Packet_Control_Acknowledgement_t *packet, /* check if this control ack belongs to packet uplink ack */ ul_tbf = as_ul_tbf(tbf); - if (ul_tbf && ul_tbf->handle_ctrl_ack()) { + if (ul_tbf && ul_tbf->handle_ctrl_ack(reason)) { LOGPTBF(tbf, LOGL_DEBUG, "[UPLINK] END\n"); if (ul_tbf->ctrl_ack_to_toggle()) LOGPTBF(tbf, LOGL_NOTICE, "Recovered uplink ack for UL\n"); diff --git a/src/pdch_ul_controller.c b/src/pdch_ul_controller.c index 6848d97a..8fb5582f 100644 --- a/src/pdch_ul_controller.c +++ b/src/pdch_ul_controller.c @@ -220,11 +220,12 @@ int pdch_ulc_reserve_tbf_usf(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcm return pdch_ulc_add_node(ulc, item); } -int pdch_ulc_reserve_tbf_poll(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_tbf *tbf) +int pdch_ulc_reserve_tbf_poll(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_tbf *tbf, enum pdch_ulc_tbf_poll_reason reason) { struct pdch_ulc_node *item = _alloc_node(ulc, fn); item->type = PDCH_ULC_NODE_TBF_POLL; item->tbf_poll.poll_tbf = tbf; + item->tbf_poll.reason = reason; return pdch_ulc_add_node(ulc, item); } @@ -317,7 +318,7 @@ void pdch_ulc_expire_fn(struct pdch_ulc *ulc, uint32_t fn) LOGPDCH(ulc->pdch, DRLCMAC, LOGL_NOTICE, "Timeout for registered POLL (FN=%u): %s\n", item->fn, tbf_name(item->tbf_poll.poll_tbf)); - tbf_poll_timeout(item->tbf_poll.poll_tbf); + tbf_poll_timeout(item->tbf_poll.poll_tbf, item->tbf_poll.reason); break; case PDCH_ULC_NODE_SBA: sba = item->sba.sba; diff --git a/src/pdch_ul_controller.h b/src/pdch_ul_controller.h index d5fea4d0..ff60d2f3 100644 --- a/src/pdch_ul_controller.h +++ b/src/pdch_ul_controller.h @@ -52,6 +52,14 @@ enum PdchUlcNode { }; extern const struct value_string pdch_ul_node_names[]; +enum pdch_ulc_tbf_poll_reason { + PDCH_ULC_POLL_UL_ASS, /* Expect CTRL ACK for UL ASS we transmit */ + PDCH_ULC_POLL_DL_ASS, /* Expect CTRL ACK for DL ASS we transmit */ + PDCH_ULC_POLL_UL_ACK, /* Expect CTRL ACK for UL ACK/NACK we transmit */ + PDCH_ULC_POLL_DL_ACK, /* Expect DL ACK/NACK requested by RRBP */ + PDCH_ULC_POLL_CELL_CHG_CONTINUE, /* Expect CTRL ACK for Pkt cell Change Continue we transmit */ +}; + struct pdch_ulc_node { struct rb_node node; /*! entry in pdch_ulc->tree_root */ uint32_t fn; @@ -62,6 +70,7 @@ struct pdch_ulc_node { } tbf_usf; struct { struct gprs_rlcmac_tbf *poll_tbf; + enum pdch_ulc_tbf_poll_reason reason; } tbf_poll; struct { struct gprs_rlcmac_sba *sba; @@ -73,7 +82,7 @@ struct pdch_ulc_node { struct pdch_ulc *pdch_ulc_alloc(struct gprs_rlcmac_pdch *pdch, void *ctx); int pdch_ulc_reserve_tbf_usf(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_ul_tbf *ul_tbf); -int pdch_ulc_reserve_tbf_poll(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_tbf *tbf); +int pdch_ulc_reserve_tbf_poll(struct pdch_ulc *ulc, uint32_t fn, struct gprs_rlcmac_tbf *tbf, enum pdch_ulc_tbf_poll_reason reason); int pdch_ulc_reserve_sba(struct pdch_ulc *ulc, struct gprs_rlcmac_sba *sba); bool pdch_ulc_fn_is_free(struct pdch_ulc *ulc, uint32_t fn); diff --git a/src/tbf.cpp b/src/tbf.cpp index a24f536c..860b8773 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -572,7 +572,7 @@ int gprs_rlcmac_tbf::check_polling(uint32_t fn, uint8_t ts, return 0; } -void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t) +void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason reason) { const char *chan = "UNKNOWN"; @@ -588,7 +588,7 @@ void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum gprs_rl chan, new_poll_fn, ts); /* schedule polling */ - if (pdch_ulc_reserve_tbf_poll(trx->pdch[ts].ulc, new_poll_fn, this) < 0) { + if (pdch_ulc_reserve_tbf_poll(trx->pdch[ts].ulc, new_poll_fn, this, reason) < 0) { LOGPTBFDL(this, LOGL_ERROR, "Failed scheduling poll on %s (FN=%d, TS=%d)\n", chan, poll_fn, ts); return; @@ -597,37 +597,37 @@ void gprs_rlcmac_tbf::set_polling(uint32_t new_poll_fn, uint8_t ts, enum gprs_rl poll_fn = new_poll_fn; poll_ts = ts; - switch (t) { - case GPRS_RLCMAC_POLL_UL_ASS: + switch (reason) { + case PDCH_ULC_POLL_UL_ASS: ul_ass_state = GPRS_RLCMAC_UL_ASS_WAIT_ACK; LOGPTBFDL(this, LOGL_INFO, "Scheduled UL Assignment polling on %s (FN=%d, TS=%d)\n", chan, poll_fn, poll_ts); break; - case GPRS_RLCMAC_POLL_DL_ASS: + case PDCH_ULC_POLL_DL_ASS: dl_ass_state = GPRS_RLCMAC_DL_ASS_WAIT_ACK; LOGPTBFDL(this, LOGL_INFO, "Scheduled DL Assignment polling on %s (FN=%d, TS=%d)\n", chan, poll_fn, poll_ts); break; - case GPRS_RLCMAC_POLL_UL_ACK: + case PDCH_ULC_POLL_UL_ACK: ul_ack_state = GPRS_RLCMAC_UL_ACK_WAIT_ACK; LOGPTBFUL(this, LOGL_DEBUG, "Scheduled UL Acknowledgement polling on %s (FN=%d, TS=%d)\n", chan, poll_fn, poll_ts); break; - case GPRS_RLCMAC_POLL_DL_ACK: + case PDCH_ULC_POLL_DL_ACK: LOGPTBFDL(this, LOGL_DEBUG, "Scheduled DL Acknowledgement polling on %s (FN=%d, TS=%d)\n", chan, poll_fn, poll_ts); break; - case GPRS_RLCMAC_POLL_CELL_CHG_CONTINUE: + case PDCH_ULC_POLL_CELL_CHG_CONTINUE: LOGPTBFDL(this, LOGL_DEBUG, "Scheduled 'Packet Cell Change Continue' polling on %s (FN=%d, TS=%d)\n", chan, poll_fn, poll_ts); break; } } -void gprs_rlcmac_tbf::poll_timeout() +void gprs_rlcmac_tbf::poll_timeout(enum pdch_ulc_tbf_poll_reason reason) { uint16_t pgroup; gprs_rlcmac_ul_tbf *ul_tbf = as_ul_tbf(this); @@ -637,7 +637,7 @@ void gprs_rlcmac_tbf::poll_timeout() poll_state = GPRS_RLCMAC_POLL_NONE; - if (ul_tbf && ul_tbf->handle_ctrl_ack()) { + if (ul_tbf && ul_tbf->handle_ctrl_ack(reason)) { if (!ul_tbf->ctrl_ack_to_toggle()) { LOGPTBF(this, LOGL_NOTICE, "Timeout for polling PACKET CONTROL ACK for PACKET UPLINK ACK: %s\n", @@ -945,7 +945,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts) bts_do_rate_ctr_inc(bts, CTR_PKT_DL_ASSIGNMENT); if (poll_ass_dl) { - set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ASS); + set_polling(new_poll_fn, ts, PDCH_ULC_POLL_DL_ASS); } else { dl_ass_state = GPRS_RLCMAC_DL_ASS_NONE; TBF_SET_STATE(new_dl_tbf, GPRS_RLCMAC_FLOW); @@ -1048,7 +1048,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts) LOGP(DTBF, LOGL_DEBUG, "------------------------- TX : Packet Uplink Assignment -------------------------\n"); bts_do_rate_ctr_inc(bts, CTR_PKT_UL_ASSIGNMENT); - set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ASS); + set_polling(new_poll_fn, ts, PDCH_ULC_POLL_UL_ASS); talloc_free(mac_control_block); return msg; @@ -1222,12 +1222,12 @@ int tbf_check_polling(const struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts return tbf->check_polling(fn, ts, poll_fn, rrbp); } -void tbf_set_polling(struct gprs_rlcmac_tbf *tbf, uint32_t new_poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t) +void tbf_set_polling(struct gprs_rlcmac_tbf *tbf, uint32_t new_poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason t) { return tbf->set_polling(new_poll_fn, ts, t); } -void tbf_poll_timeout(struct gprs_rlcmac_tbf *tbf) +void tbf_poll_timeout(struct gprs_rlcmac_tbf *tbf, enum pdch_ulc_tbf_poll_reason reason) { - tbf->poll_timeout(); + tbf->poll_timeout(reason); } diff --git a/src/tbf.h b/src/tbf.h index 779bc263..83c1b707 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -46,6 +46,7 @@ extern "C" { #include #include "coding_scheme.h" +#include #ifdef __cplusplus } #endif @@ -63,14 +64,6 @@ enum gprs_rlcmac_tbf_state { GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */ }; -enum gprs_rlcmac_tbf_poll_type { - GPRS_RLCMAC_POLL_UL_ASS, - GPRS_RLCMAC_POLL_DL_ASS, - GPRS_RLCMAC_POLL_UL_ACK, - GPRS_RLCMAC_POLL_DL_ACK, - GPRS_RLCMAC_POLL_CELL_CHG_CONTINUE, -}; - enum gprs_rlcmac_tbf_poll_state { GPRS_RLCMAC_POLL_NONE = 0, GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ @@ -208,8 +201,8 @@ bool tbf_is_tfi_assigned(const struct gprs_rlcmac_tbf *tbf); uint8_t tbf_tfi(const struct gprs_rlcmac_tbf *tbf); int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); int tbf_check_polling(const struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts, uint32_t *poll_fn, unsigned int *rrbp); -void tbf_set_polling(struct gprs_rlcmac_tbf *tbf, uint32_t new_poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t); -void tbf_poll_timeout(struct gprs_rlcmac_tbf *tbf); +void tbf_set_polling(struct gprs_rlcmac_tbf *tbf, uint32_t new_poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason t); +void tbf_poll_timeout(struct gprs_rlcmac_tbf *tbf, enum pdch_ulc_tbf_poll_reason reason); #ifdef __cplusplus } #endif @@ -267,8 +260,8 @@ struct gprs_rlcmac_tbf { int check_polling(uint32_t fn, uint8_t ts, uint32_t *poll_fn, unsigned int *rrbp) const; - void set_polling(uint32_t poll_fn, uint8_t ts, enum gprs_rlcmac_tbf_poll_type t); - void poll_timeout(); + void set_polling(uint32_t poll_fn, uint8_t ts, enum pdch_ulc_tbf_poll_reason reason); + void poll_timeout(enum pdch_ulc_tbf_poll_reason reason); /** tlli handling */ uint32_t tlli() const; diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp index 44baa005..a59b03b3 100644 --- a/src/tbf_dl.cpp +++ b/src/tbf_dl.cpp @@ -975,7 +975,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block( rc = check_polling(fn, ts, &new_poll_fn, &rrbp); if (rc >= 0) { - set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_DL_ACK); + set_polling(new_poll_fn, ts, PDCH_ULC_POLL_DL_ACK); m_tx_counter = 0; /* start timer whenever we send the final block */ diff --git a/src/tbf_ul.cpp b/src/tbf_ul.cpp index ba491f6d..063d0ff2 100644 --- a/src/tbf_ul.cpp +++ b/src/tbf_ul.cpp @@ -275,10 +275,10 @@ bool gprs_rlcmac_ul_tbf::ctrl_ack_to_toggle() return false; /* GPRS_RLCMAC_FLAG_TO_UL_ACK was unset, now set */ } -bool gprs_rlcmac_ul_tbf::handle_ctrl_ack() +bool gprs_rlcmac_ul_tbf::handle_ctrl_ack(enum pdch_ulc_tbf_poll_reason reason) { /* check if this control ack belongs to packet uplink ack */ - if (ul_ack_state_is(GPRS_RLCMAC_UL_ACK_WAIT_ACK)) { + if (reason == PDCH_ULC_POLL_UL_ACK && ul_ack_state_is(GPRS_RLCMAC_UL_ACK_WAIT_ACK)) { TBF_SET_ACK_STATE(this, GPRS_RLCMAC_UL_ACK_NONE); return true; } @@ -324,7 +324,7 @@ struct msgb *gprs_rlcmac_ul_tbf::create_ul_ack(uint32_t fn, uint8_t ts) m_contention_resolution_done = 1; if (final) { - set_polling(new_poll_fn, ts, GPRS_RLCMAC_POLL_UL_ACK); + set_polling(new_poll_fn, ts, PDCH_ULC_POLL_UL_ACK); /* waiting for final acknowledge */ m_final_ack_sent = 1; } else diff --git a/src/tbf_ul.h b/src/tbf_ul.h index e3de1dad..a2ad25ea 100644 --- a/src/tbf_ul.h +++ b/src/tbf_ul.h @@ -57,7 +57,7 @@ struct gprs_rlcmac_ul_tbf : public gprs_rlcmac_tbf { gprs_rlc_window *window(); struct msgb *create_ul_ack(uint32_t fn, uint8_t ts); bool ctrl_ack_to_toggle(); - bool handle_ctrl_ack(); + bool handle_ctrl_ack(enum pdch_ulc_tbf_poll_reason reason); /* blocks were acked */ int rcv_data_block_acknowledged( const struct gprs_rlc_data_info *rlc, diff --git a/tests/ulc/PdchUlcTest.cpp b/tests/ulc/PdchUlcTest.cpp index 3372d2f0..84035d17 100644 --- a/tests/ulc/PdchUlcTest.cpp +++ b/tests/ulc/PdchUlcTest.cpp @@ -88,16 +88,16 @@ static void test_reserve_multiple() node = pdch_ulc_get_node(pdch->ulc, sba2->fn); OSMO_ASSERT(node->type == PDCH_ULC_NODE_SBA && node->sba.sba == sba2); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, sba1->fn, tbf1); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, sba1->fn, tbf1, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == -EEXIST); OSMO_ASSERT(pdch_ulc_get_tbf_poll(pdch->ulc, sba1->fn) == NULL); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, sba2->fn, tbf1); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, sba2->fn, tbf1, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == -EEXIST); OSMO_ASSERT(pdch_ulc_get_tbf_poll(pdch->ulc, sba2->fn) == NULL); /* Now Reserve correctly TBF1 */ OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf1_poll_fn1) == true); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf1_poll_fn1, tbf1); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf1_poll_fn1, tbf1, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == 0); OSMO_ASSERT(pdch_ulc_get_tbf_poll(pdch->ulc, tbf1_poll_fn1) == tbf1); OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf1_poll_fn1) == false); @@ -107,7 +107,7 @@ static void test_reserve_multiple() /* Now reserve correctly TBF2 */ OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf2_poll_fn1) == true); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf2_poll_fn1, tbf2); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf2_poll_fn1, tbf2, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == 0); OSMO_ASSERT(pdch_ulc_get_tbf_poll(pdch->ulc, tbf2_poll_fn1) == tbf2); OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf2_poll_fn1) == false); @@ -117,7 +117,7 @@ static void test_reserve_multiple() /* Now Reserve TBF1 for POLL again on a later FN, which is totally expected: */ OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf1_poll_fn2) == true); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf1_poll_fn2, tbf1); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, tbf1_poll_fn2, tbf1, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == 0); OSMO_ASSERT(pdch_ulc_get_tbf_poll(pdch->ulc, tbf1_poll_fn2) == tbf1); OSMO_ASSERT(pdch_ulc_fn_is_free(pdch->ulc, tbf1_poll_fn2) == false); @@ -182,7 +182,7 @@ static void test_fn_wrap_around() fn = start_fn; while (fn < 40 || fn >= start_fn) { printf("*** RESERVE FN=%" PRIu32 ":\n", fn); - rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, fn, tbf1); + rc = pdch_ulc_reserve_tbf_poll(pdch->ulc, fn, tbf1, PDCH_ULC_POLL_UL_ASS); OSMO_ASSERT(rc == 0); print_ulc_nodes(pdch->ulc); fn = fn_next_block(fn);