diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-03-29 18:15:30 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2021-03-31 17:39:50 +0200 |
commit | 86580e1966b7272cad75c845607e45b8347cf758 (patch) | |
tree | 3b65144d5888c3c1eed7fbb5de9ee2c86bdfdcda | |
parent | b5ae0811d1667e792fc3a4e550384791f4bca4c9 (diff) |
pdch_ulc: Store TBF poll reason
This allows easily checking the initial reason to trigger the poll when
either it is received or times out.
Later on this reason can be transformed into an FSM event and sent to
the related FSM.
Related: OS#5020
Change-Id: Ie8fefd1f47ad674ce597a8065b15284088956bde
-rw-r--r-- | src/nacc_fsm.c | 2 | ||||
-rw-r--r-- | src/pdch.cpp | 4 | ||||
-rw-r--r-- | src/pdch_ul_controller.c | 5 | ||||
-rw-r--r-- | src/pdch_ul_controller.h | 11 | ||||
-rw-r--r-- | src/tbf.cpp | 30 | ||||
-rw-r--r-- | src/tbf.h | 17 | ||||
-rw-r--r-- | src/tbf_dl.cpp | 2 | ||||
-rw-r--r-- | src/tbf_ul.cpp | 6 | ||||
-rw-r--r-- | src/tbf_ul.h | 2 | ||||
-rw-r--r-- | tests/ulc/PdchUlcTest.cpp | 12 |
10 files changed, 48 insertions, 43 deletions
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); } @@ -46,6 +46,7 @@ extern "C" { #include <osmocom/gsm/gsm48.h> #include "coding_scheme.h" +#include <pdch_ul_controller.h> #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); |