pespin has submitted this change. (
https://gerrit.osmocom.org/c/libosmo-gprs/+/33810 )
Change subject: gmm: Introduce GMMSM-Modify.ind primitive
......................................................................
gmm: Introduce GMMSM-Modify.ind primitive
TS 24.007 and TS 24.008 seem to lack providing an explicit way to pass
information between GMM and SM (GMMSM interface) when a RAU process
happens in GMM (rx RAU Accept).
This lack of primitive can easily be spotted by looking at TS 24.007
Appending C.15, or even better, at the 3rd page of "C.16(cont’d)" around
the "STOP Trams" timer, where the info is magically available in SM when
being received at GMM.
Change-Id: I81e207d44d88f18f0ee13fb413827606a6f830bc
---
M include/osmocom/gprs/gmm/gmm_prim.h
M include/osmocom/gprs/gmm/gmm_private.h
M src/gmm/gmm.c
M src/gmm/gmm_prim.c
M tests/gmm/gmm_prim_test.c
M tests/gmm/gmm_prim_test.err
M tests/gmm/gmm_prim_test.ok
7 files changed, 144 insertions(+), 8 deletions(-)
Approvals:
Jenkins Builder: Verified
osmith: Looks good to me, but someone else must approve
laforge: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
diff --git a/include/osmocom/gprs/gmm/gmm_prim.h b/include/osmocom/gprs/gmm/gmm_prim.h
index b774ef8..e066a15 100644
--- a/include/osmocom/gprs/gmm/gmm_prim.h
+++ b/include/osmocom/gprs/gmm/gmm_prim.h
@@ -203,6 +203,7 @@
OSMO_GPRS_GMM_GMMSM_ESTABLISH, /* Req, Cnf/Rej */
OSMO_GPRS_GMM_GMMSM_RELEASE, /* Ind */
OSMO_GPRS_GMM_GMMSM_UNITDATA, /* Req, Ind */
+ OSMO_GPRS_GMM_GMMSM_MODIFY, /* Ind, osmocom extension */
};
extern const struct value_string osmo_gprs_gmm_gmmsm_prim_type_names[];
static inline const char *osmo_gprs_gmm_gmmsm_prim_type_name(enum
osmo_gprs_gmm_gmmsm_prim_type val)
@@ -257,6 +258,19 @@
uint8_t *smpdu;
uint16_t smpdu_len;
} unitdata_ind;
+ /* OSMO_GPRS_GMM_GMMSM_MODIFY | Ind */
+ struct {
+ /* PLMNs MT-caps, attach-type. */
+ uint32_t allocated_ptmsi;
+ uint32_t allocated_ptmsi_sig;
+ uint32_t allocated_tlli;
+ struct gprs_ra_id rai;
+ bool pdp_ctx_status_present;
+ uint8_t pdp_ctx_status[2]; /* bitmask TS 24.008 10.5.7.1 */
+ bool rx_npdu_numbers_list_present;
+ uint8_t rx_npdu_numbers_list[17]; /* TS 24.008 10.5.5.11 */
+ uint8_t rx_npdu_numbers_list_len; /* bitmask TS 24.008 10.5.5.11 */
+ } modify_ind;
};
};
diff --git a/include/osmocom/gprs/gmm/gmm_private.h
b/include/osmocom/gprs/gmm/gmm_private.h
index 46795c8..2abd583 100644
--- a/include/osmocom/gprs/gmm/gmm_private.h
+++ b/include/osmocom/gprs/gmm/gmm_private.h
@@ -66,6 +66,7 @@
uint8_t radio_prio; /* TS 24.008 10.5.7.2 */
struct gprs_ra_id ra; /* TS 24.008 10.5.5.15 (decoded) */
+ bool pdp_ctx_status_present;
uint8_t pdp_ctx_status[2]; /* TS 24.008 10.5.7.1 */
bool rx_npdu_numbers_list_present;
uint8_t rx_npdu_numbers_list[17]; /* TS 24.008 10.5.5.11 */
@@ -111,7 +112,7 @@
struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmsm_establish_cnf(uint32_t id, uint8_t
cause);
struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmsm_release_ind(uint32_t id);
struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmsm_unitdata_ind(uint32_t id, uint8_t
*smpdu, unsigned int smpdu_len);
-
+struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmsm_modify_ind(uint32_t id);
/* gmm.c: */
struct gprs_gmm_entity *gprs_gmm_gmme_alloc(uint32_t ptmsi, const char *imsi);
void gprs_gmm_gmme_free(struct gprs_gmm_entity *gmme);
@@ -142,6 +143,7 @@
int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted,
uint8_t cause);
int gprs_gmm_submit_gmmsm_establish_cnf(struct gprs_gmm_entity *gmme, bool accepted,
uint8_t cause);
int gprs_gmm_submit_gmmsm_release_ind(struct gprs_gmm_entity *gmme);
+int gprs_gmm_submit_gmmsm_modify_ind(struct gprs_gmm_entity *gmme);
int gprs_gmm_submit_llgmm_assing_req(const struct gprs_gmm_entity *gmme);
/* misc.c */
diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c
index 6eaf461..e3afc18 100644
--- a/src/gmm/gmm.c
+++ b/src/gmm/gmm.c
@@ -498,6 +498,30 @@
return rc;
}
+/* Osmocom specific, see missing primitive in TS 24.007 Annex C.16 around "STOP
+ * Trams". It is used to propagate TLLI update to SM (and then to SNDCP). */
+int gprs_gmm_submit_gmmsm_modify_ind(struct gprs_gmm_entity *gmme)
+{
+ struct osmo_gprs_gmm_prim *gmm_prim;
+ int rc;
+
+ gmm_prim = gprs_gmm_prim_alloc_gmmsm_modify_ind(gmme->sess_id);
+ gmm_prim->gmmsm.modify_ind.allocated_ptmsi = gmme->ptmsi;
+ gmm_prim->gmmsm.modify_ind.allocated_ptmsi_sig = gmme->ptmsi_sig;
+ gmm_prim->gmmsm.modify_ind.allocated_tlli = gmme->tlli;
+ memcpy(&gmm_prim->gmmsm.modify_ind.rai, &gmme->ra, sizeof(gmme->ra));
+ gmm_prim->gmmsm.modify_ind.pdp_ctx_status_present = gmme->pdp_ctx_status_present;
+ if (gmm_prim->gmmsm.modify_ind.pdp_ctx_status_present)
+ memcpy(&gmm_prim->gmmsm.modify_ind.pdp_ctx_status, &gmme->pdp_ctx_status,
sizeof(gmme->pdp_ctx_status));
+ gmm_prim->gmmsm.modify_ind.rx_npdu_numbers_list_present =
gmme->rx_npdu_numbers_list_present;
+ gmm_prim->gmmsm.modify_ind.rx_npdu_numbers_list_len =
gmme->rx_npdu_numbers_list_len;
+ if (gmme->rx_npdu_numbers_list_len > 0)
+ memcpy(&gmm_prim->gmmsm.modify_ind.rx_npdu_numbers_list,
&gmme->rx_npdu_numbers_list, gmme->rx_npdu_numbers_list_len);
+
+ rc = gprs_gmm_prim_call_up_cb(gmm_prim);
+ return rc;
+}
+
static int gprs_gmm_submit_gmmrr_assing_req(struct gprs_gmm_entity *gmme)
{
struct osmo_gprs_gmm_prim *gmm_prim_tx;
@@ -1121,22 +1145,32 @@
/* 10.5.1.13 Equivalent PLMNs: TODO */
/* 10.5.7.1 PDP context status: TODO */
- if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_PDP_CTX_STATUS, 2))
+ if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_PDP_CTX_STATUS, 2)) {
memcpy(gmme->pdp_ctx_status, TLVP_VAL(&tp, GSM48_IE_GMM_PDP_CTX_STATUS), 2);
-
+ gmme->pdp_ctx_status_present = true;
+ } else {
+ gmme->pdp_ctx_status_present = false;
+ }
/* TODO: lots more Optional IEs */
}
- /* Submit LLGMM-ASSIGN-REQ as per TS 24.007 Annex C.1 */
+ /* Submit LLGMM-ASSIGN-REQ as per TS 24.007 Annex C.15 */
rc = gprs_gmm_submit_llgmm_assing_req(gmme);
if (rc < 0)
goto rejected;
- /* Submit GMMRR-ASSIGN-REQ as per TS 24.007 Annex C.1 */
+ /* Submit GMMRR-ASSIGN-REQ as per TS 24.007 Annex C.15 */
rc = gprs_gmm_submit_gmmrr_assing_req(gmme);
if (rc < 0)
goto rejected;
+ /* Submit GMMSM-MODIFY-REQ, see missing primitive in TS 24.007 Annex C.16 around
"STOP Trams" */
+ if (gmme->sess_id != GPRS_GMM_SESS_ID_UNASSIGNED) {
+ rc = gprs_gmm_submit_gmmsm_modify_ind(gmme);
+ if (rc < 0)
+ goto rejected;
+ }
+
rc = gprs_gmm_tx_rau_compl(gmme);
if (rc < 0)
goto rejected;
diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c
index 5a35ef2..3beaea8 100644
--- a/src/gmm/gmm_prim.c
+++ b/src/gmm/gmm_prim.c
@@ -64,6 +64,7 @@
{ OSMO_GPRS_GMM_GMMSM_ESTABLISH, "ESTABLISH" },
{ OSMO_GPRS_GMM_GMMSM_RELEASE, "RELEASE" },
{ OSMO_GPRS_GMM_GMMSM_UNITDATA, "UNITDATA" },
+ { OSMO_GPRS_GMM_GMMSM_MODIFY, "MODIFY" },
{ 0, NULL }
};
@@ -318,6 +319,16 @@
return gmm_prim;
}
+/* Osmocom specific, see missing primitive in TS 24.007 Annex C.16 around "STOP
+ * Trams". It is used to propagate TLLI update to SM (and then to SNDCP). */
+struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmsm_modify_ind(uint32_t id)
+{
+ struct osmo_gprs_gmm_prim *gmm_prim;
+ gmm_prim = gmm_prim_gmmsm_alloc(OSMO_GPRS_GMM_GMMSM_MODIFY, PRIM_OP_INDICATION, 0);
+ gmm_prim->gmmsm.sess_id = id;
+ return gmm_prim;
+}
+
/* 3GPP TS 24.007 9.5.1.5 GMMSM-UNITDATA-REQ:*/
struct osmo_gprs_gmm_prim *osmo_gprs_gmm_prim_alloc_gmmsm_unitdata_req(uint32_t id,
uint8_t *smpdu, unsigned int smpdu_len)
{
diff --git a/tests/gmm/gmm_prim_test.c b/tests/gmm/gmm_prim_test.c
index 2297518..c33bddc 100644
--- a/tests/gmm/gmm_prim_test.c
+++ b/tests/gmm/gmm_prim_test.c
@@ -237,10 +237,11 @@
switch (OSMO_PRIM_HDR(&gmm_prim->oph)) {
case OSMO_PRIM(OSMO_GPRS_GMM_GMMREG_ATTACH, PRIM_OP_CONFIRM):
if (gmm_prim->gmmreg.attach_cnf.accepted) {
- printf("%s(): Rx %s accepted=%u allocated_ptmsi=0x%08x
allocated_ptmsi_sig=0x%06x\n", __func__, pdu_name,
+ printf("%s(): Rx %s accepted=%u allocated_ptmsi=0x%08x
allocated_ptmsi_sig=0x%06x allocated_tlli=0x%08x\n", __func__, pdu_name,
gmm_prim->gmmreg.attach_cnf.accepted,
gmm_prim->gmmreg.attach_cnf.acc.allocated_ptmsi,
- gmm_prim->gmmreg.attach_cnf.acc.allocated_ptmsi_sig);
+ gmm_prim->gmmreg.attach_cnf.acc.allocated_ptmsi_sig,
+ gmm_prim->gmmreg.attach_cnf.acc.allocated_tlli);
} else {
printf("%s(): Rx %s accepted=%u rej_cause=%u\n", __func__, pdu_name,
gmm_prim->gmmreg.attach_cnf.accepted,
@@ -298,6 +299,13 @@
printf("%s(): Rx %s sess_id=%u\n", __func__, pdu_name,
gmm_prim->gmmsm.sess_id);
break;
+ case OSMO_PRIM(OSMO_GPRS_GMM_GMMSM_MODIFY, PRIM_OP_INDICATION):
+ printf("%s(): Rx %s sess_id=%u allocated_ptmsi=0x%08x allocated_ptmsi_sig=0x%06x
allocated_tlli=0x%08x\n", __func__, pdu_name,
+ gmm_prim->gmmsm.sess_id,
+ gmm_prim->gmmsm.modify_ind.allocated_ptmsi,
+ gmm_prim->gmmsm.modify_ind.allocated_ptmsi_sig,
+ gmm_prim->gmmsm.modify_ind.allocated_tlli);
+ break;
default:
printf("%s(): Unexpected Rx %s\n", __func__, pdu_name);
OSMO_ASSERT(0)
@@ -510,6 +518,7 @@
uint32_t ptmsi = 0x00001234;
uint32_t ptmsi_sig = 0x556677;
uint32_t rand_tlli = 0x80001234;
+ uint32_t tlli;
char *imsi = "1234567890";
char *imei = "42342342342342";
char *imeisv = "4234234234234275";
@@ -576,6 +585,27 @@
OSMO_ASSERT(rc == 0);
/* As a result, GMM submits GMMSM-UNITDATA.ind */
+ /* Wait for READY timer to expire: */
+ clock_override_add(44, 0); /* 44: See GMM Attach Accept (pdu_gmm_att_acc) fed above */
+ clock_debug("Expect T3314 (READY) timeout");
+ osmo_select_main(0);
+
+ clock_override_add(10*60, 0); /* 10*60: See GMM Attach Accept (pdu_gmm_att_acc) fed
above */
+ clock_debug("Expect T3312 (periodic RAU) timeout");
+ osmo_select_main(0);
+
+ /* Network sends GMM RAU Accept */
+ llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM,
(uint8_t *)pdu_gmm_rau_acc, sizeof(pdu_gmm_rau_acc));
+ OSMO_ASSERT(llc_prim);
+ rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim);
+ OSMO_ASSERT(rc == 0);
+ /* update the used ptmsi to align with what was assigned from the network: */
+ ptmsi = 0xec999002;
+ tlli = gprs_tmsi2tlli(ptmsi, TLLI_LOCAL);
+ (void)tlli;
+ /* As a result, GMM submits GMMSM-MODIFY.ind */
+ /* As a result, MS answers GMM RAU Complete */
+
/* DEACT: TODO */
printf("==== %s() [end] ====\n", __func__);
diff --git a/tests/gmm/gmm_prim_test.err b/tests/gmm/gmm_prim_test.err
index fa670cf..fa2d2a6 100644
--- a/tests/gmm/gmm_prim_test.err
+++ b/tests/gmm/gmm_prim_test.err
@@ -82,3 +82,19 @@
DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started
(expires in 44 seconds)
DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer expired
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 started (expires
in 600 seconds)
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3316 (Delete stored
RAND & SRES timer) expired
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) T3312 Periodic RAU timer
expired
+DLGLOBAL INFO GMM_MS{Registered}: Received Event RAU_REQUESTED
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Tx GMM RAU REQUEST
+DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) READY timer started
(expires in 44 seconds)
+DLGLOBAL INFO GMM_MS{Registered}: state_chg to RAUInitidated
+DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ea711b41:TLLI-ea711b41) Rx GMM RAU ACCEPT
upd_result=0x00
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) Tx GMM RAU COMPL
+DLGLOBAL INFO Rx from lower layers: GMRR-LLC_TRANSMITTED.indication
+DLGLOBAL INFO GMME(IMSI-1234567890:PTMSI-ec999002:TLLI-ec999002) READY timer started
(expires in 10 seconds)
+DLGLOBAL INFO GMM_MS{RAUInitidated}: Received Event RAU_ACCEPTED
+DLGLOBAL INFO GMM_MS{RAUInitidated}: state_chg to Registered
diff --git a/tests/gmm/gmm_prim_test.ok b/tests/gmm/gmm_prim_test.ok
index 6cf672a..62c58e3 100644
--- a/tests/gmm/gmm_prim_test.ok
+++ b/tests/gmm/gmm_prim_test.ok
@@ -8,7 +8,7 @@
test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0x80001234
new_TLLI=0xea711b41
test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0x80001234 new_tlli=0xea711b41
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 03 ]
-test_gmm_prim_up_cb(): Rx GMMREG-ATTACH.confirm accepted=1 allocated_ptmsi=0xea711b41
allocated_ptmsi_sig=0xffffffff
+test_gmm_prim_up_cb(): Rx GMMREG-ATTACH.confirm accepted=1 allocated_ptmsi=0xea711b41
allocated_ptmsi_sig=0xffffffff allocated_tlli=0xea711b41
sys={44.000000}, mono={44.000000}: clock_override_add
sys={44.000000}, mono={44.000000}: Expect T3314 (READY) timeout
sys={644.000000}, mono={644.000000}: clock_override_add
@@ -37,4 +37,15 @@
test_gmm_prim_up_cb(): Rx GMMSM-ESTABLISH.confirm sess_id=1234 accepted
test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[0a 28 29
30 ]
test_gmm_prim_up_cb(): Rx GMMSM-UNITDATA.indication sess_id=1234 sm_pdu=0a 28 29 30
+sys={44.000000}, mono={44.000000}: clock_override_add
+sys={44.000000}, mono={44.000000}: Expect T3314 (READY) timeout
+sys={644.000000}, mono={644.000000}: clock_override_add
+sys={644.000000}, mono={644.000000}: Expect T3312 (periodic RAU) timeout
+test_gmm_prim_llc_down_cb(): Rx LLGMM-SUSPEND.request TLLI=0xea711b41
+test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 08 03
32 f4 07 00 05 00 00 17 16 0a 00 e5 02 00 00 e1 ]
+test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xea711b41
new_TLLI=0xec999002
+test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request old_tlli=0xea711b41 new_tlli=0xec999002
+test_gmm_prim_up_cb(): Rx GMMSM-MODIFY.indication sess_id=1234 allocated_ptmsi=0xec999002
allocated_ptmsi_sig=0xffffffff allocated_tlli=0xec999002
+test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xec999002 SAPI=GMM l3=[08 0a ]
+test_gmm_prim_llc_down_cb(): Rx LLGMM-RESUME.request TLLI=0xec999002
==== test_gmm_prim_ms_gmmsm() [end] ====
--
To view, visit
https://gerrit.osmocom.org/c/libosmo-gprs/+/33810
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: libosmo-gprs
Gerrit-Branch: master
Gerrit-Change-Id: I81e207d44d88f18f0ee13fb413827606a6f830bc
Gerrit-Change-Number: 33810
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged