aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-03-29 18:15:30 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-03-31 17:39:50 +0200
commit86580e1966b7272cad75c845607e45b8347cf758 (patch)
tree3b65144d5888c3c1eed7fbb5de9ee2c86bdfdcda
parentb5ae0811d1667e792fc3a4e550384791f4bca4c9 (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.c2
-rw-r--r--src/pdch.cpp4
-rw-r--r--src/pdch_ul_controller.c5
-rw-r--r--src/pdch_ul_controller.h11
-rw-r--r--src/tbf.cpp30
-rw-r--r--src/tbf.h17
-rw-r--r--src/tbf_dl.cpp2
-rw-r--r--src/tbf_ul.cpp6
-rw-r--r--src/tbf_ul.h2
-rw-r--r--tests/ulc/PdchUlcTest.cpp12
10 files changed, 48 insertions, 43 deletions
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index df7cd7d..6384fd5 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 45c7c98..22bac0b 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 6848d97..8fb5582 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 d5fea4d..ff60d2f 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 a24f536..860b877 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 779bc26..83c1b70 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -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 44baa00..a59b03b 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 ba491f6..063d0ff 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 e3de1da..a2ad25e 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 3372d2f..84035d1 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);