aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 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 <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);