Change in osmo-pcu[master]: nacc: Implement Pkt Cell Change Continue retransmission

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Wed Feb 3 08:34:04 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-pcu/+/22604 )

Change subject: nacc: Implement Pkt Cell Change Continue retransmission
......................................................................

nacc: Implement Pkt Cell Change Continue retransmission

Use the fact that the MS must answer the RRBP of the Pkt Cell Change
Continue with a CTRL ACK to find out whether the message was received
successfuly or a retransmission is potentially required.

3GPP TS 44.060:
"""
When the mobile station receives the PACKET CELL CHANGE ORDER or
the PACKET CELL CHANGE CONTINUE message the mobile station shall
transmit a PACKET CONTROL ACKNOWLEDGMENT message in the specified
uplink radio block if a valid RRBP field is received as part of the
message; the mobile station may then switch to a new cell.
"""

Related: SYS#4909
Change-Id: I7cc28922e71699598da0ef6eb90136a47d3c002f
---
M src/encoding.cpp
M src/encoding.h
M src/gprs_ms.c
M src/gprs_ms.h
M src/gprs_rlcmac_sched.cpp
M src/nacc_fsm.c
M src/nacc_fsm.h
M src/pdch.cpp
M src/tbf.cpp
M src/tbf.h
10 files changed, 105 insertions(+), 17 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/src/encoding.cpp b/src/encoding.cpp
index 38bc175..8bc8d15 100644
--- a/src/encoding.cpp
+++ b/src/encoding.cpp
@@ -1757,14 +1757,14 @@
 	block->u.Packet_Neighbour_Cell_Data.Container = *container;
 }
 
-void write_packet_cell_change_continue(RlcMacDownlink_t *block,
-		bool tfi_is_dl, uint8_t tfi, bool exist_id,
-		uint16_t arfcn, uint8_t bsic, uint8_t container_id)
+void write_packet_cell_change_continue(RlcMacDownlink_t *block, uint8_t poll, uint8_t rrbp,
+				       bool tfi_is_dl, uint8_t tfi, bool exist_id,
+				       uint16_t arfcn, uint8_t bsic, uint8_t container_id)
 {
 
 	block->PAYLOAD_TYPE = 0x1;  // RLC/MAC control block that does not include the optional octets of the RLC/MAC control header
-	block->RRBP         = 0;  // 0: N+13
-	block->SP           = 0; // RRBP field is not valid
+	block->RRBP         = rrbp;  // RRBP (e.g. N+13)
+	block->SP           = poll;  // RRBP field is valid?
 	block->USF          = 0x0;  // Uplink state flag
 
 	block->u.Packet_Cell_Change_Continue.MESSAGE_TYPE = MT_PACKET_CELL_CHANGE_CONTINUE;
diff --git a/src/encoding.h b/src/encoding.h
index 4ebfa35..89d057c 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -124,9 +124,9 @@
 		bool tfi_is_dl, uint8_t tfi, uint8_t container_id,
 		uint8_t container_idx, PNCDContainer_t *container);
 
-void write_packet_cell_change_continue(RlcMacDownlink_t *block,
-		bool tfi_is_dl, uint8_t tfi, bool exist_id,
-		uint16_t arfcn, uint8_t bsic, uint8_t container_id);
+void write_packet_cell_change_continue(RlcMacDownlink_t *block, uint8_t poll, uint8_t rrbp,
+				       bool tfi_is_dl, uint8_t tfi, bool exist_id,
+				       uint16_t arfcn, uint8_t bsic, uint8_t container_id);
 
 #ifdef __cplusplus
 }
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index 8078b10..ab1a067 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -958,13 +958,17 @@
 	return false;
 }
 
-struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
+struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts)
 {
 	int rc;
 	struct nacc_ev_create_rlcmac_msg_ctx data_ctx;
 
-	data_ctx.tbf = tbf;
-	data_ctx.msg = NULL;
+	data_ctx = (struct nacc_ev_create_rlcmac_msg_ctx) {
+			.tbf = tbf,
+			.fn = fn,
+			.ts = ts,
+			.msg = NULL,
+	};
 
 	rc = osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_CREATE_RLCMAC_MSG, &data_ctx);
 	if (rc != 0 || !data_ctx.msg)
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index c57bbf6..6674261 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -144,7 +144,7 @@
 
 int ms_nacc_start(struct GprsMs *ms, Packet_Cell_Change_Notification_t *notif);
 bool ms_nacc_rts(const struct GprsMs *ms);
-struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf);
+struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts);
 
 static inline bool ms_is_idle(const struct GprsMs *ms)
 {
diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp
index a8f65de..5f029a0 100644
--- a/src/gprs_rlcmac_sched.cpp
+++ b/src/gprs_rlcmac_sched.cpp
@@ -203,7 +203,7 @@
 			else if (tbf == tbfs->ul_ack)
 				msg = tbfs->ul_ack->create_ul_ack(fn, ts);
 			else if (tbf == tbfs->nacc) {
-				msg = ms_nacc_create_rlcmac_msg(tbf->ms(), tbf);
+				msg = ms_nacc_create_rlcmac_msg(tbf->ms(), tbf, fn, ts);
 			}
 
 			if (!msg) {
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index d160404..b479f9c 100644
--- a/src/nacc_fsm.c
+++ b/src/nacc_fsm.c
@@ -46,6 +46,7 @@
 	[NACC_ST_WAIT_REQUEST_SI] = { .T = PCU_TDEF_SI_RESOLVE_TO },
 	[NACC_ST_TX_NEIGHBOUR_DATA] = {},
 	[NACC_ST_TX_CELL_CHG_CONTINUE] = {},
+	[NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK] = {}, /* Timeout through event controlled by tbf::poll_timeout() */
 	[NACC_ST_DONE] = {},
 };
 
@@ -64,6 +65,8 @@
 	{ NACC_EV_RX_RAC_CI, "RX_RAC_CI" },
 	{ NACC_EV_RX_SI, "RX_SI" },
 	{ NACC_EV_CREATE_RLCMAC_MSG, "CREATE_RLCMAC_MSG" },
+	{ NACC_EV_RX_CELL_CHG_CONTINUE_ACK, "RX_CELL_CHG_CONTINUE_ACK"},
+	{ NACC_EV_TIMEOUT_CELL_CHG_CONTINUE, "TIMEOUT_CELL_CHG_CONTINUE" },
 	{ 0, NULL }
 };
 
@@ -156,12 +159,21 @@
 
 /* TS 44 060 11.2.2a Packet Cell Change Continue */
 static struct msgb *create_packet_cell_chg_continue(const struct nacc_fsm_ctx *ctx,
-						    const struct gprs_rlcmac_tbf *tbf)
+						    const struct nacc_ev_create_rlcmac_msg_ctx *data,
+						    uint32_t *new_poll_fn)
 {
 	struct msgb *msg;
 	int rc;
 	RlcMacDownlink_t *mac_control_block;
+	struct gprs_rlcmac_tbf *tbf = data->tbf;
 	struct GprsMs *ms = tbf_ms(tbf);
+	unsigned int rrbp;
+
+	rc = tbf_check_polling(tbf, data->fn, data->ts, new_poll_fn, &rrbp);
+	if (rc < 0) {
+		LOGP(DTBF, LOGL_ERROR, "Failed registering poll for Pkt Cell Chg Continue (%d)\n", rc);
+		return NULL;
+	}
 
 	msg = msgb_alloc(GSM_MACBLOCK_LEN, "pkt_cell_chg_continue");
 	if (!msg)
@@ -180,7 +192,7 @@
 	uint8_t tfi_is_dl = tbf_direction(tbf) == GPRS_RLCMAC_DL_TBF;
 	uint8_t tfi = tbf_tfi(tbf);
 	uint8_t container_id = 0;
-	write_packet_cell_change_continue(mac_control_block, tfi_is_dl, tfi, true,
+	write_packet_cell_change_continue(mac_control_block, 1, rrbp, tfi_is_dl, tfi, true,
 			ctx->neigh_key.tgt_arfcn, ctx->neigh_key.tgt_bsic, container_id);
 	LOGP(DNACC, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Cell Change Continue +++++++++++++++++++++++++\n");
 	rc = encode_gsm_rlcmac_downlink(&bv, mac_control_block);
@@ -191,6 +203,7 @@
 	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);
 	return msg;
 
 free_ret:
@@ -458,7 +471,24 @@
 	switch (event) {
 	case NACC_EV_CREATE_RLCMAC_MSG:
 		data_ctx = (struct nacc_ev_create_rlcmac_msg_ctx *)data;
-		data_ctx->msg = create_packet_cell_chg_continue(ctx, data_ctx->tbf);
+		data_ctx->msg = create_packet_cell_chg_continue(ctx, data_ctx, &ctx->continue_poll_fn);
+		if (data_ctx->msg) {
+			ctx->continue_poll_ts = data_ctx->ts;
+			nacc_fsm_state_chg(fi, NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK);
+		}
+		break;
+	default:
+		OSMO_ASSERT(0);
+	}
+}
+
+static void st_wait_cell_chg_continue_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case NACC_EV_TIMEOUT_CELL_CHG_CONTINUE:
+		nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+		break;
+	case NACC_EV_RX_CELL_CHG_CONTINUE_ACK:
 		nacc_fsm_state_chg(fi, NACC_ST_DONE);
 		break;
 	default:
@@ -543,10 +573,20 @@
 			X(NACC_EV_RX_SI) |
 			X(NACC_EV_CREATE_RLCMAC_MSG),
 		.out_state_mask =
-			X(NACC_ST_DONE),
+			X(NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK),
 		.name = "TX_CELL_CHG_CONTINUE",
 		.action = st_cell_chg_continue,
 	},
+	[NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK] = {
+		.in_event_mask =
+			X(NACC_EV_RX_CELL_CHG_CONTINUE_ACK) |
+			X(NACC_EV_TIMEOUT_CELL_CHG_CONTINUE),
+		.out_state_mask =
+			X(NACC_ST_TX_CELL_CHG_CONTINUE) |
+			X(NACC_ST_DONE),
+		.name = "WAIT_CELL_CHG_CONTINUE_ACK",
+		.action = st_wait_cell_chg_continue_ack,
+	},
 	[NACC_ST_DONE] = {
 		.in_event_mask = 0,
 		.out_state_mask = 0,
diff --git a/src/nacc_fsm.h b/src/nacc_fsm.h
index 9107daf..7b0adfd 100644
--- a/src/nacc_fsm.h
+++ b/src/nacc_fsm.h
@@ -32,6 +32,8 @@
 	NACC_EV_RX_RAC_CI, /* no data passed, RAC_CI became available in neigh_cache */
 	NACC_EV_RX_SI, /* data: struct si_cache_entry* */
 	NACC_EV_CREATE_RLCMAC_MSG, /* data: struct nacc_ev_create_rlcmac_msg_ctx* */
+	NACC_EV_RX_CELL_CHG_CONTINUE_ACK,
+	NACC_EV_TIMEOUT_CELL_CHG_CONTINUE, /* Poll Timeout */
 };
 
 enum nacc_fsm_states {
@@ -40,6 +42,7 @@
 	NACC_ST_WAIT_REQUEST_SI,
 	NACC_ST_TX_NEIGHBOUR_DATA,
 	NACC_ST_TX_CELL_CHG_CONTINUE,
+	NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK,
 	NACC_ST_DONE,
 };
 
@@ -53,11 +56,15 @@
 	struct si_cache_value si_info; /* SI info resolved from SGSN, to be sent to MS */
 	size_t si_info_bytes_sent; /* How many bytes out of si_info->si_len were already sent to MS */
 	size_t container_idx; /* Next container_idx to assign when sending Packet Neighbor Data message */
+	uint32_t continue_poll_fn; /* Scheduled poll FN to CTRL ACK the Pkt Cell Chg Continue */
+	uint8_t continue_poll_ts; /* Scheduled poll TS to CTRL ACK the Pkt Cell Chg Continue */
 };
 
 /* passed as data in NACC_EV_CREATE_RLCMAC_MSG */
 struct nacc_ev_create_rlcmac_msg_ctx {
 	struct gprs_rlcmac_tbf *tbf; /* target tbf to create messages for */
+	uint32_t fn; /* FN where the created DL ctrl block is to be sent */
+	uint8_t ts; /* TS where the created DL ctrl block is to be sent */
 	struct msgb *msg; /* to be filled by FSM during event processing */
 };
 
diff --git a/src/pdch.cpp b/src/pdch.cpp
index 2028ba2..787208c 100644
--- a/src/pdch.cpp
+++ b/src/pdch.cpp
@@ -47,6 +47,7 @@
 
 #include "coding_scheme.h"
 #include "gsm_rlcmac.h"
+#include "nacc_fsm.h"
 }
 
 #include <errno.h>
@@ -394,6 +395,19 @@
 
 		return;
 	}
+	if (ms->nacc && ms->nacc->fi->state == NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK &&
+	    ms->nacc->continue_poll_fn == fn && ms->nacc->continue_poll_ts == ts_no) {
+		osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_CELL_CHG_CONTINUE_ACK, NULL);
+		/* Don't assume MS is no longer reachable (hence don't free) after this: TS 44.060
+		 * "When the mobile station receives the PACKET CELL CHANGE ORDER
+		 * or the PACKET CELL CHANGE CONTINUE message the mobile station
+		 * shall transmit a PACKET CONTROL ACKNOWLEDGMENT message in the
+		 * specified uplink radio block if a valid RRBP field is
+		 * received as part of the message; the mobile station _MAY_ then
+		 * switch to a new cell."
+		 */
+		return;
+	}
 	LOGP(DRLCMAC, LOGL_ERROR, "Error: received PACET CONTROL ACK "
 		"at no request\n");
 }
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 35bd81d..7caa2ce 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -49,6 +49,7 @@
 
 #include "gsm_rlcmac.h"
 #include "coding_scheme.h"
+#include "nacc_fsm.h"
 }
 
 #include <errno.h>
@@ -614,6 +615,10 @@
 		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:
+		LOGPTBFDL(this, LOGL_DEBUG, "Scheduled 'Packet Cell Change Continue' polling on %s (FN=%d, TS=%d)\n",
+			  chan, poll_fn, poll_ts);
+		break;
 	}
 }
 
@@ -690,6 +695,11 @@
 		}
 		/* reschedule DL assignment */
 		dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS;
+	} else if (m_ms->nacc && m_ms->nacc->fi->state == NACC_ST_WAIT_CELL_CHG_CONTINUE_ACK &&
+		   m_ms->nacc->continue_poll_fn == poll_fn && m_ms->nacc->continue_poll_ts == poll_ts) {
+		/* Timeout waiting for CTRL ACK acking Pkt Cell Change Continue */
+		osmo_fsm_inst_dispatch(m_ms->nacc->fi, NACC_EV_TIMEOUT_CELL_CHG_CONTINUE, NULL);
+		return;
 	} else if (direction == GPRS_RLCMAC_DL_TBF) {
 		gprs_rlcmac_dl_tbf *dl_tbf = as_dl_tbf(this);
 
@@ -1203,3 +1213,13 @@
 {
 	return tbf->tfi();
 }
+
+int tbf_check_polling(const struct gprs_rlcmac_tbf *tbf, uint32_t fn, uint8_t ts, uint32_t *poll_fn, unsigned int *rrbp)
+{
+	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)
+{
+	return tbf->set_polling(new_poll_fn, ts, t);
+}
diff --git a/src/tbf.h b/src/tbf.h
index 1d28afb..989ec08 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -68,6 +68,7 @@
 	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 {
@@ -206,6 +207,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);
 #ifdef __cplusplus
 }
 #endif

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-pcu/+/22604
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I7cc28922e71699598da0ef6eb90136a47d3c002f
Gerrit-Change-Number: 22604
Gerrit-PatchSet: 6
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210203/9382a728/attachment.htm>


More information about the gerrit-log mailing list