aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-06-13 13:00:53 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2022-06-13 13:51:55 +0200
commit3278f0fb3cb3b945f1358cf7fa4b236b860f9752 (patch)
tree946a897c5b0f7f3baf6dc58406107ec22e0dd4b8
parenttests/iuup: Showcase IuUP stack not answering subsequent Init msgs (diff)
downloadlibosmocore-3278f0fb3cb3b945f1358cf7fa4b236b860f9752.tar.xz
libosmocore-3278f0fb3cb3b945f1358cf7fa4b236b860f9752.zip
iuup: Fix Handling of subsequent Initialization msgs
Once the IuUP FSM moved away from Init state, it stopped handling Initialization messages received from peers and simply ignored them starting from that point. As a result, if the first IuUP Init ACK it sent to the peer was lost, the peer would keep retrying with more IuUP Init and getting no answer. In any case, it seems possible and desirable that a peer may send an IuUP Init at a later point, as pointed out vaguely in 3GPP TS 25.415. sec 6.5.2.1: """ Upon reception of a frame indicating that an Initialisation procedure is active in the peer Iu UP entity, the Iu UP protocol layer forwards the whole protocol information contained in the INITIALISATION control frame to the upper layers. It also stores the RAB sub-Flow Combination set (and thus replaces a possible previous set) in order to control during the transfer of user data, that the Iu UP payload is correctly formatted (e.g. RFCI matches the expected Iu UP frame payload total length). The peer Iu UP entity receiving the INITIALISATION control frame shall choose a version that it supports among the proposed versions indicated by the sender for which it has enough initialisation information. """ sec B.2.2 "Initialisation State": """ After sending a positive acknowledgement of the last INITIALISATION control frame, the Iu UP instance enters SMpSDU data transfer ready state. Note that CN does not know if the initialisation ACK was correctly received by the RNC (and Initialisation procedure successfully completed) until it receives RAB assignment response, or use data from the RNC. The CN must therefore be able to continue receiving INITIALISATION control frames by re-entering the Initialisation state (from Support Mode Data Transfer Ready State), if the CN has started to send user data before receiving the indication that Initialisation was successfully completed """ sec B.2.3 "Support Mode Data Transfer Ready State": """ In case of handover or relocation, Initialisation procedures may have to be performed and Iu UP instance may have to enter the initialisation state. """ Related: SYS#5995 Change-Id: I5cb740702805693cc7f0a550e2e093f9bfdd507c
-rw-r--r--src/gsm/iuup.c10
-rw-r--r--tests/iuup/iuup_test.c19
-rw-r--r--tests/iuup/iuup_test.ok3
3 files changed, 19 insertions, 13 deletions
diff --git a/src/gsm/iuup.c b/src/gsm/iuup.c
index 4c0a9482..ca7eb2b8 100644
--- a/src/gsm/iuup.c
+++ b/src/gsm/iuup.c
@@ -734,6 +734,7 @@ static void iuup_fsm_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
}
+/* 3GPP TS 25.415 B.2.3 "Support Mode Data Transfer Ready State" */
static void iuup_fsm_smpsdu_data(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct osmo_iuup_instance *iui = fi->priv;
@@ -745,6 +746,14 @@ static void iuup_fsm_smpsdu_data(struct osmo_fsm_inst *fi, uint32_t event, void
irp = data;
osmo_fsm_inst_state_chg(fi, IUUP_FSM_ST_NULL, 0, 0);
break;
+ case IUUP_FSM_EVT_INIT:
+ /* "In case of handover or relocation, Initialisation procedures
+ * may have to be performed and Iu UP instance may have to enter
+ * the initialisation state." */
+ itp = data;
+ if (!iuup_rx_initialization(iui, itp))
+ osmo_fsm_inst_state_chg(fi, IUUP_FSM_ST_INIT, 0, 0);
+ break;
case IUUP_FSM_EVT_IUUP_DATA_REQ:
/* Data coming down from RNL (user) towards TNL (transport) */
irp = data;
@@ -821,6 +830,7 @@ static const struct osmo_fsm_state iuup_fsm_states[] = {
},
[IUUP_FSM_ST_SMpSDU_DATA_XFER_READY] = {
.in_event_mask = S(IUUP_FSM_EVT_IUUP_CONFIG_REQ) |
+ S(IUUP_FSM_EVT_INIT) |
S(IUUP_FSM_EVT_IUUP_DATA_REQ) |
S(IUUP_FSM_EVT_IUUP_DATA_IND),
.out_state_mask = S(IUUP_FSM_ST_NULL) |
diff --git a/tests/iuup/iuup_test.c b/tests/iuup/iuup_test.c
index 5b553509..e40b9e77 100644
--- a/tests/iuup/iuup_test.c
+++ b/tests/iuup/iuup_test.c
@@ -541,12 +541,10 @@ static int _passive_init_retrans_user_prim_cb(struct osmo_prim_hdr *oph, void *c
switch (_passive_init_retrans_user_rx_prim) {
case 0:
- /* FIXME expected case: case 1: */
+ case 1:
OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_STATUS, PRIM_OP_INDICATION));
OSMO_ASSERT(irp->u.status.procedure == IUUP_PROC_INIT);
break;
- /* FIXME current case: */
- case 1:
case 2:
default:
OSMO_ASSERT(OSMO_PRIM_HDR(&irp->oph) == OSMO_PRIM(OSMO_IUUP_RNL_DATA, PRIM_OP_INDICATION));
@@ -603,14 +601,9 @@ void test_passive_init_retrans(void)
tnp->oph.msg->l2h = msgb_put(tnp->oph.msg, sizeof(iuup_initialization));
hdr14 = (struct iuup_pdutype14_hdr *)msgb_l2(tnp->oph.msg);
memcpy(hdr14, iuup_initialization, sizeof(iuup_initialization));
- /* FIXME: unexpected result, should be fixed: */
- OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) < 0); /* INIT not perrmited */
- OSMO_ASSERT(_passive_init_transport_rx_prim == 1); /* We receive an Init ACK */
- OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 1); /* We receive the Status-Init.ind */
- /* FIXME: expected result: */
- //OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
- //OSMO_ASSERT(_passive_init_transport_rx_prim == 2); /* We receive another Init ACK */
- //OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 2); /* We receive another Status-Init.ind */
+ OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 2); /* We receive another Init ACK */
+ OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 2); /* We receive another Status-Init.ind */
/* Send IuUP incoming data to the implementation: */
tnp = osmo_iuup_tnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_TNL_UNITDATA, PRIM_OP_INDICATION, IUUP_MSGB_SIZE);
@@ -619,7 +612,7 @@ void test_passive_init_retrans(void)
memcpy(hdr0, iuup_data, sizeof(iuup_data));
OSMO_ASSERT((rc = osmo_iuup_tnl_prim_up(iui, tnp)) == 0);
/* We receive it in RNL: */
- OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 2);
+ OSMO_ASSERT(_passive_init_retrans_user_rx_prim == 3);
/* Now in opposite direction, RNL->[IuuP]->TNL: */
rnp = osmo_iuup_rnl_prim_alloc(iuup_test_ctx, OSMO_IUUP_RNL_DATA, PRIM_OP_REQUEST, IUUP_MSGB_SIZE);
@@ -629,7 +622,7 @@ void test_passive_init_retrans(void)
rnp->oph.msg->l3h = msgb_put(rnp->oph.msg, sizeof(iuup_data) - 4);
memcpy(rnp->oph.msg->l3h, iuup_data + 4, sizeof(iuup_data) - 4);
OSMO_ASSERT((rc = osmo_iuup_rnl_prim_down(iui, rnp)) == 0);
- OSMO_ASSERT(_passive_init_transport_rx_prim == 2); /* We receive data in TNL */
+ OSMO_ASSERT(_passive_init_transport_rx_prim == 3); /* We receive data in TNL */
osmo_iuup_instance_free(iui);
}
diff --git a/tests/iuup/iuup_test.ok b/tests/iuup/iuup_test.ok
index 93f69547..57baba9c 100644
--- a/tests/iuup/iuup_test.ok
+++ b/tests/iuup/iuup_test.ok
@@ -48,6 +48,9 @@ _passive_init_retrans_user_prim_cb()
_passive_init_transport_prim_cb()
Transport: DL len=4: e4 00 24 00
_passive_init_retrans_user_prim_cb()
+_passive_init_transport_prim_cb()
+Transport: DL len=4: e4 00 24 00
+_passive_init_retrans_user_prim_cb()
User: UL len=31: 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40
_passive_init_transport_prim_cb()
Transport: DL len=35: 01 00 e3 ff 08 55 6d 94 4c 71 a1 a0 81 e7 ea d2 04 24 44 80 00 0e cd 82 b8 11 18 00 00 97 c4 79 4e 77 40