dexter has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-pcu/+/33538 )
Change subject: nacc_fsm: Add support for NACC with UTRAN and E-UTRAN cells
......................................................................
nacc_fsm: Add support for NACC with UTRAN and E-UTRAN cells
The NACC procedure in OsmoPCU currently only supports NACC with GERAN
cells. When an UTRAN or E-UTRAN cell is proposed in the
PacketCellChangeNotification, then the FSM is immediately terminated,
meaning that the NACC procedure can not commence.
When the NACC procedure is carried out for UTRAN or E-UTRAN cells, the
PCU will not send any system information to the UE. Instead it
immediately sends a PacketCellChangeContinue message. This also means
that we do not carry out any RAN Information Requests in the background.
This patch adds logic to detect if the proprosed cell is an UTRAN or
E-UTRAN cell and the adds a new transition to the FSM so that a short
route to NACC_ST_TX_CELL_CHG_CONTINUE can be taken.
Related: OS#6044
Change-Id: I96280f0ec5955ed3cb17641bf4118496c929bdac
---
M src/nacc_fsm.c
M src/nacc_fsm.h
M src/neigh_cache.h
3 files changed, 133 insertions(+), 20 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/38/33538/1
diff --git a/src/nacc_fsm.c b/src/nacc_fsm.c
index c513423..ad4590b 100644
--- a/src/nacc_fsm.c
+++ b/src/nacc_fsm.c
@@ -191,7 +191,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, 1, rrbp, tfi_is_dl, tfi, true,
+ write_packet_cell_change_continue(mac_control_block, 1, rrbp, tfi_is_dl, tfi,
ctx->neigh_key_valid,
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);
@@ -270,19 +270,91 @@
return 0;
}
-static int fill_neigh_key_from_bts_pkt_cell_chg_not(struct neigh_cache_entry_key
*neigh_key,
+/* Classify the RAT type of the cell that is proposed in the
PacketCellChangeNotification. In case the RAT is GERAN,
+ * also extract neighbour key information to provide system information */
+#define NACC_GERAN_CELL 0
+#define NACC_UTRAN_CELL 1
+#define NACC_EUTRAN_CELL 2
+static int fill_neigh_key_from_bts_pkt_cell_chg_not(struct nacc_fsm_ctx *ctx,
const struct gprs_rlcmac_bts *bts,
- const Packet_Cell_Change_Notification_t *notif)
+ const Packet_Cell_Change_Notification_t * notif)
{
+ const Target_Cell_GSM_Notif_t *notif_gsm;
+ const Target_Cell_3G_Notif_t *notif_3g;
+ const Target_Cell_4G_Notif_t *notif_4g;
+
+ memset(&ctx->neigh_key, 0, sizeof(ctx->neigh_key));
+ ctx->neigh_key_valid = false;
+
switch (notif->Target_Cell.UnionType) {
- case 0: /* GSM */
- neigh_key->local_lac = bts->cgi_ps.rai.lac.lac;
- neigh_key->local_ci = bts->cgi_ps.cell_identity;
- neigh_key->tgt_arfcn = notif->Target_Cell.u.Target_Cell_GSM_Notif.ARFCN;
- neigh_key->tgt_bsic = notif->Target_Cell.u.Target_Cell_GSM_Notif.BSIC;
- return 0;
+ case 0: /* GSM */
+ notif_gsm = ¬if->Target_Cell.u.Target_Cell_GSM_Notif;
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=GSM, ARFCN=%u,
BSIC=%u\n",
+ notif_gsm->ARFCN, notif_gsm->BSIC);
+
+ ctx->neigh_key.local_lac = bts->cgi_ps.rai.lac.lac;
+ ctx->neigh_key.local_ci = bts->cgi_ps.cell_identity;
+ ctx->neigh_key.tgt_arfcn = notif_gsm->ARFCN;
+ ctx->neigh_key.tgt_bsic = notif_gsm->BSIC;
+ ctx->neigh_key_valid = true;
+ return NACC_GERAN_CELL;
default:
- return -ENOTSUP;
+ switch (notif->Target_Cell.u.Target_Other_RAT_Notif.UnionType) {
+ case 0: /* UTRAN */
+ notif_3g =
¬if->Target_Cell.u.Target_Other_RAT_Notif.u.Target_Cell_3G_Notif;
+ if (notif_3g->Exist_FDD_Description) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=UTRAN, FDD-ARFCN=%u\n",
+ notif_3g->FDD_Target_Cell_Notif.FDD_ARFCN);
+ } else if (notif_3g->Exist_TDD_Description) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=UTRAN, TDD-ARFCN=%u\n",
+ notif_3g->TDD_Target_Cell.TDD_ARFCN);
+ }
+ return NACC_UTRAN_CELL;
+ default:
+ switch
(notif->Target_Cell.u.Target_Other_RAT_Notif.u.Target_Other_RAT_2_Notif.UnionType) {
+ case 0: /* E-UTRAN (and older RAT) */
+ notif_4g =
+
¬if->Target_Cell.u.Target_Other_RAT_Notif.u.Target_Other_RAT_2_Notif.u.
+ Target_Cell_4G_Notif;
+ notif_3g = ¬if_4g->Target_Cell_3G_Notif;
+ if (notif_4g->Exist_Arfcn) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=GSM, ARFCN=%u,
BSIC=%u\n",
+ notif_4g->Arfcn, notif_4g->bsic);
+ ctx->neigh_key.local_lac = bts->cgi_ps.rai.lac.lac;
+ ctx->neigh_key.local_ci = bts->cgi_ps.cell_identity;
+ ctx->neigh_key.tgt_arfcn = notif_4g->Arfcn;
+ ctx->neigh_key.tgt_bsic = notif_4g->bsic;
+ ctx->neigh_key_valid = true;
+ return NACC_GERAN_CELL;
+ }
+ if (notif_4g->Exist_3G_Target_Cell) {
+ if (notif_3g->Exist_FDD_Description) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=UTRAN,
FDD-ARFCN=%u\n",
+ notif_3g->FDD_Target_Cell_Notif.FDD_ARFCN);
+ } else if (notif_3g->Exist_TDD_Description) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=UTRAN,
TDD-ARFCN=%u\n",
+ notif_3g->TDD_Target_Cell.TDD_ARFCN);
+ }
+ return NACC_UTRAN_CELL;
+ }
+ if (notif_4g->Exist_Eutran_Target_Cell) {
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: RAT=E-UTRAN, EARFCN=%u,
CI=%u\n",
+ notif_4g->Target_EUTRAN_Cell.EARFCN,
+ notif_4g->Target_EUTRAN_Cell.Physical_Layer_Cell_Identity);
+ return NACC_EUTRAN_CELL;
+ }
+
+ /* TODO: do something meaningful with an Eutran_Ccn_Measurement_Report, in case it
is
+ * provided. */
+
+ LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell: (none, invalid)\n");
+ return -EINVAL;
+ default:
+ LOGPFSML(ctx->fi, LOGL_NOTICE,
+ "TargetCell: RAT=CSG-UTRAN|CSG-EUTRAN, (not supported)\n");
+ return -ENOTSUP; /* TODO: Add support */
+ }
+ }
}
}
@@ -316,14 +388,23 @@
{
struct gprs_rlcmac_bts *bts = ctx->ms->bts;
struct neigh_cache_entry_key neigh_key;
+ int rc;
- if (fill_neigh_key_from_bts_pkt_cell_chg_not(&neigh_key, bts, notif) < 0) {
- LOGPFSML(ctx->fi, LOGL_NOTICE, "TargetCell type=0x%x not supported\n",
- notif->Target_Cell.UnionType);
+ rc = fill_neigh_key_from_bts_pkt_cell_chg_not(ctx, bts, notif);
+ if (rc < 0) {
if (ctx->fi->state != NACC_ST_TX_CELL_CHG_CONTINUE)
nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);
return;
+ } else if (rc == NACC_UTRAN_CELL || rc == NACC_EUTRAN_CELL) {
+ /* When the proposed call is an UTRAN or EUTRAN cell, we won't provide any system
information
+ * to the UE. Instead we will send the PacketCellChangeContinue message immediately.
This also
+ * applies in the case of re-transmissions. See also: 3GPP TS 48.018, section 8c.6.1.
*/
+ LOGPFSML(ctx->fi, LOGL_NOTICE,
+ "Target cell is an UTRAN or EUTRAN cell => no system information
provided.\n");
+ nacc_fsm_state_chg(ctx->fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+ return;
}
+
/* If tgt cell changed, restart resolving it */
if (!neigh_cache_entry_key_eq(&ctx->neigh_key, &neigh_key)) {
ctx->neigh_key = neigh_key;
@@ -341,17 +422,23 @@
struct nacc_fsm_ctx *ctx = (struct nacc_fsm_ctx *)fi->priv;
struct gprs_rlcmac_bts *bts = ctx->ms->bts;
Packet_Cell_Change_Notification_t *notif;
+ int rc;
switch (event) {
case NACC_EV_RX_CELL_CHG_NOTIFICATION:
notif = (Packet_Cell_Change_Notification_t *)data;
- if (fill_neigh_key_from_bts_pkt_cell_chg_not(&ctx->neigh_key, bts, notif) <
0) {
- LOGPFSML(fi, LOGL_NOTICE, "TargetCell type=0x%x not supported\n",
- notif->Target_Cell.UnionType);
+ rc = fill_neigh_key_from_bts_pkt_cell_chg_not(ctx, bts, notif);
+ if (rc < 0)
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);
- } else {
+ else if (rc == NACC_UTRAN_CELL || rc == NACC_EUTRAN_CELL) {
+ /* When the proposed call is an UTRAN or EUTRAN cell, we won't provide any system
information
+ * to the UE. Instead we will send the PacketCellChangeContinue message immediately.
+ * see also: 3GPP TS 48.018, section 8c.6.1. */
+ LOGPFSML(ctx->fi, LOGL_NOTICE,
+ "Target cell is an UTRAN or EUTRAN cell => no system information
provided.\n");
+ nacc_fsm_state_chg(fi, NACC_ST_TX_CELL_CHG_CONTINUE);
+ } else
nacc_fsm_state_chg(fi, NACC_ST_WAIT_RESOLVE_RAC_CI);
- }
break;
default:
OSMO_ASSERT(0);
@@ -382,7 +469,6 @@
}
/* CGI-PS not in cache, resolve it using BSC Neighbor Resolution CTRL interface */
-
LOGPFSML(fi, LOGL_DEBUG, "No CGI-PS found in cache, resolving "
NEIGH_CACHE_ENTRY_KEY_FMT "...\n",
NEIGH_CACHE_ENTRY_KEY_ARGS(&ctx->neigh_key));
@@ -622,7 +708,8 @@
.in_event_mask =
X(NACC_EV_RX_CELL_CHG_NOTIFICATION),
.out_state_mask =
- X(NACC_ST_WAIT_RESOLVE_RAC_CI),
+ X(NACC_ST_WAIT_RESOLVE_RAC_CI) |
+ X(NACC_ST_TX_CELL_CHG_CONTINUE),
.name = "INITIAL",
.action = st_initial,
},
diff --git a/src/nacc_fsm.h b/src/nacc_fsm.h
index ec6db2e..e6a9524 100644
--- a/src/nacc_fsm.h
+++ b/src/nacc_fsm.h
@@ -47,6 +47,7 @@
struct osmo_fsm_inst *fi;
struct GprsMs* ms; /* back pointer */
struct neigh_cache_entry_key neigh_key; /* target cell info from MS */
+ bool neigh_key_valid; /* target cell info from MS is valid */
struct osmo_cell_global_id_ps cgi_ps; /* target cell info resolved from req_{arfcn+bsic}
*/
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 */
diff --git a/src/neigh_cache.h b/src/neigh_cache.h
index 76706ab..9d4c63f 100644
--- a/src/neigh_cache.h
+++ b/src/neigh_cache.h
@@ -65,6 +65,7 @@
struct neigh_cache_entry *neigh_cache_add(struct neigh_cache *cache,
const struct neigh_cache_entry_key *key,
const struct osmo_cell_global_id_ps *value);
+/* TODO: This function seems to be used only in neigh_cache.c, make it static? */
struct neigh_cache_entry *neigh_cache_lookup_entry(struct neigh_cache *cache,
const struct neigh_cache_entry_key *key);
const struct osmo_cell_global_id_ps *neigh_cache_lookup_value(struct neigh_cache *cache,
--
To view, visit
https://gerrit.osmocom.org/c/osmo-pcu/+/33538
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I96280f0ec5955ed3cb17641bf4118496c929bdac
Gerrit-Change-Number: 33538
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Gerrit-MessageType: newchange