pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-gprs/+/32507 )
Change subject: gmm, rlcmac: Properly handle P-TMSI vs TLLI ......................................................................
gmm, rlcmac: Properly handle P-TMSI vs TLLI
Change-Id: I44c95b3bc973b9dfcc79daf6b529fd2826f574e8 --- M include/osmocom/gprs/gmm/gmm_prim.h M include/osmocom/gprs/gmm/gmm_private.h M include/osmocom/gprs/rlcmac/rlcmac_prim.h M src/gmm/gmm.c M src/gmm/gmm_prim.c M src/rlcmac/rlcmac_prim.c M tests/gmm/Makefile.am M tests/gmm/gmm_prim_test.c M tests/gmm/gmm_prim_test.err M tests/gmm/gmm_prim_test.ok M tests/rlcmac/rlcmac_prim_test.c 11 files changed, 244 insertions(+), 92 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 fixeria: Looks good to me, approved
diff --git a/include/osmocom/gprs/gmm/gmm_prim.h b/include/osmocom/gprs/gmm/gmm_prim.h index 1f277d5..8a777e2 100644 --- a/include/osmocom/gprs/gmm/gmm_prim.h +++ b/include/osmocom/gprs/gmm/gmm_prim.h @@ -156,7 +156,8 @@ * Same as struct osmo_gprs_rlcmac_gmmrr_prim. */ struct osmo_gprs_gmm_gmmrr_prim { - /* Common fields (none) */ + /* Common fields */ + uint32_t tlli; union { /* OSMO_GPRS_GMM_GMMRR_ASSIGN | Req */ struct { @@ -164,7 +165,6 @@ } assign_req; /* OSMO_GPRS_GMM_GMMRR_PAGE | Ind */ struct { - uint32_t tlli; } page_ind; }; }; diff --git a/include/osmocom/gprs/gmm/gmm_private.h b/include/osmocom/gprs/gmm/gmm_private.h index 21c7467..f233eb3 100644 --- a/include/osmocom/gprs/gmm/gmm_private.h +++ b/include/osmocom/gprs/gmm/gmm_private.h @@ -55,6 +55,8 @@ struct gprs_gmm_ms_fsm_ctx ms_fsm; uint32_t ptmsi; uint32_t old_ptmsi; + uint32_t tlli; + uint32_t old_tlli; char imsi[OSMO_IMSI_BUF_SIZE]; char imei[GSM23003_IMEI_NUM_DIGITS + 1]; char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; @@ -78,16 +80,20 @@ struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmreg_attach_cnf(void); struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmreg_detach_cnf(void);
-struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmrr_assign_req(uint32_t new_tlli); +struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmrr_assign_req(uint32_t old_tlli, uint32_t new_tlli);
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_gmmrr_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);
/* gmm.c: */ -struct gprs_gmm_entity *gprs_gmm_gmme_alloc(void); +struct gprs_gmm_entity *gprs_gmm_gmme_alloc(uint32_t ptmsi, const char *imsi); void gprs_gmm_gmme_free(struct gprs_gmm_entity *gmme); +struct gprs_gmm_entity *gprs_gmm_gmme_find_or_create_by_ptmsi_imsi(uint32_t ptmsi, const char *imsi); +struct gprs_gmm_entity *gprs_gmm_find_gmme_by_ptmsi(uint32_t ptmsi); +struct gprs_gmm_entity *gprs_gmm_find_gmme_by_imsi(const char *imsi); struct gprs_gmm_entity *gprs_gmm_find_gmme_by_tlli(uint32_t tlli); +uint32_t gprs_gmm_alloc_rand_tlli(void); int gprs_gmm_rx(struct gprs_gmm_entity *gmme, struct gsm48_hdr *gh, unsigned int len); int gprs_gmm_tx_att_req(struct gprs_gmm_entity *gmme, enum osmo_gprs_gmm_attach_type attach_type, diff --git a/include/osmocom/gprs/rlcmac/rlcmac_prim.h b/include/osmocom/gprs/rlcmac/rlcmac_prim.h index 9c0bb3c..2d7a899 100644 --- a/include/osmocom/gprs/rlcmac/rlcmac_prim.h +++ b/include/osmocom/gprs/rlcmac/rlcmac_prim.h @@ -79,7 +79,8 @@ * Same as struct osmo_gprs_gmm_gmmrr_prim. */ struct osmo_gprs_rlcmac_gmmrr_prim { - /* Common fields (none) */ + /* Common fields */ + uint32_t tlli; union { /* OSMO_GPRS_RLCMAC_GMMRR_ASSIGN | Req */ struct { @@ -87,7 +88,6 @@ } assign_req; /* OSMO_GPRS_RLCMAC_GMMRR_PAGE | Ind */ struct { - uint32_t tlli; } page_ind; }; }; @@ -192,7 +192,7 @@
/* Alloc primitive for GMMRR SAP: */ struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req( - uint32_t new_tlli); + uint32_t old_tlli, uint32_t new_tlli);
/* Alloc primitive for L1CTL SAP: */ struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(uint32_t fn, uint8_t *data); diff --git a/src/gmm/gmm.c b/src/gmm/gmm.c index 5174a5e..1a01996 100644 --- a/src/gmm/gmm.c +++ b/src/gmm/gmm.c @@ -136,7 +136,7 @@ osmo_fsm_inst_dispatch(gmme->ms_fsm.fi, ev, NULL); }
-struct gprs_gmm_entity *gprs_gmm_gmme_alloc(void) +struct gprs_gmm_entity *gprs_gmm_gmme_alloc(uint32_t ptmsi, const char *imsi) { struct gprs_gmm_entity *gmme;
@@ -149,6 +149,22 @@ return NULL; }
+ gmme->ptmsi = ptmsi; + gmme->old_ptmsi = GSM_RESERVED_TMSI; + gmme->old_tlli = GPRS_GMM_TLLI_UNASSIGNED; + OSMO_STRLCPY_ARRAY(gmme->imsi, imsi); + + /* TS 24.008 4.7.1.4.1: + * - If the MS has stored a valid P-TMSI, the MS shall derive a foreign TLLI + * from that P-TMSI + * - When the MS has not stored a valid P-TMSI, i.e. the MS is not + * attached to GPRS, the MS shall use a randomly selected random TLLI + */ + if (gmme->ptmsi == GSM_RESERVED_TMSI) + gmme->tlli = gprs_gmm_alloc_rand_tlli(); + else + gmme->tlli = gprs_tmsi2tlli(gmme->ptmsi, TLLI_FOREIGN); + /* Initialize timers to default values. They may be overwritten by the * network later on: */ gmme->t3302 = osmo_tdef_get(g_gmm_ctx->T_defs, 3302, OSMO_TDEF_S, -1); @@ -170,17 +186,86 @@ talloc_free(gmme); }
+struct gprs_gmm_entity *gprs_gmm_gmme_find_or_create_by_ptmsi_imsi(uint32_t ptmsi, const char *imsi) +{ + struct gprs_gmm_entity *gmme = NULL; + + if (ptmsi != GSM_RESERVED_TMSI) + gmme = gprs_gmm_find_gmme_by_ptmsi(ptmsi); + if (!gmme) { + gmme = gprs_gmm_find_gmme_by_imsi(imsi); + if (!gmme) + gmme = gprs_gmm_gmme_alloc(ptmsi, imsi); + } + OSMO_ASSERT(gmme); + return gmme; +} + +struct gprs_gmm_entity *gprs_gmm_find_gmme_by_ptmsi(uint32_t ptmsi) +{ + struct gprs_gmm_entity *gmme; + + llist_for_each_entry(gmme, &g_gmm_ctx->gmme_list, list) { + if (gmme->ptmsi == ptmsi || gmme->old_ptmsi == ptmsi) + return gmme; + } + return NULL; +} + +struct gprs_gmm_entity *gprs_gmm_find_gmme_by_imsi(const char *imsi) +{ + struct gprs_gmm_entity *gmme; + + llist_for_each_entry(gmme, &g_gmm_ctx->gmme_list, list) { + if (strncmp(gmme->imsi, imsi, ARRAY_SIZE(gmme->imsi)) == 0) + return gmme; + } + return NULL; +} + struct gprs_gmm_entity *gprs_gmm_find_gmme_by_tlli(uint32_t tlli) { struct gprs_gmm_entity *gmme;
llist_for_each_entry(gmme, &g_gmm_ctx->gmme_list, list) { - if (gmme->ptmsi == tlli || gmme->old_ptmsi == tlli) + if (gmme->tlli == tlli || gmme->old_tlli == tlli) return gmme; } return NULL; }
+uint32_t gprs_gmm_alloc_rand_tlli(void) +{ + /* 3GPP TS 23.003 Table 1: Type of TLLI = Random TLLI_ + * | 31 | 30 | 29 | 28 | 27 | 26 to 0 | + * 0 | 1 | 1 | 1 | 1 | R | => prefix = 0x78000000 + */ + uint32_t tlli; + int max_retries = 134217728; /* 2^27 */ + int rc = 0; + + do { + rc = osmo_get_rand_id((uint8_t *) &tlli, sizeof(tlli)); + if (rc < 0) + goto failed; + + /* Remove first bits 27-31: */ + tlli &= ~0xf8000000; + /* Apply proper prefix: */ + tlli |= 0x78000000; + + if (!gprs_gmm_find_gmme_by_tlli(tlli)) { + LOGGMM(LOGL_INFO, "Allocated new random TLLI=0x%08x\n", tlli); + return tlli; + } + } while (max_retries--); + + rc = -ERANGE; +failed: + LOGGMM(LOGL_ERROR, "Failed to allocate a TLLI: %d (%s)\n", rc, strerror(-rc)); + return GPRS_GMM_TLLI_UNASSIGNED; +} + int gprs_gmm_submit_gmmreg_attach_cnf(struct gprs_gmm_entity *gmme, bool accepted, uint8_t cause) { struct osmo_gprs_gmm_prim *gmm_prim_tx; @@ -226,7 +311,7 @@ struct osmo_gprs_gmm_prim *gmm_prim_tx; int rc;
- gmm_prim_tx = gprs_gmm_prim_alloc_gmmrr_assign_req(gmme->ptmsi); + gmm_prim_tx = gprs_gmm_prim_alloc_gmmrr_assign_req(gmme->old_tlli, gmme->tlli);
rc = gprs_gmm_prim_call_down_cb(gmm_prim_tx); return rc; @@ -237,8 +322,8 @@ struct osmo_gprs_llc_prim *llc_prim_tx; int rc;
- llc_prim_tx = osmo_gprs_llc_prim_alloc_llgm_assign_req(gmme->old_ptmsi); - llc_prim_tx->llgmm.assign_req.tlli_new = gmme->ptmsi; + llc_prim_tx = osmo_gprs_llc_prim_alloc_llgm_assign_req(gmme->old_tlli); + llc_prim_tx->llgmm.assign_req.tlli_new = gmme->tlli; llc_prim_tx->llgmm.assign_req.gea = gmme->gea; memcpy(llc_prim_tx->llgmm.assign_req.kc, gmme->kc, ARRAY_SIZE(gmme->kc));
@@ -257,7 +342,7 @@ LOGGMME(gmme, LOGL_INFO, "Tx GMM IDENTITY RESPONSE\n");
llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( - gmme->ptmsi, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); msg = llc_prim->oph.msg; msg->l3h = msg->tail; rc = gprs_gmm_build_identity_resp(gmme, mi_type, msg); @@ -290,7 +375,7 @@ LOGGMME(gmme, LOGL_INFO, "Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE\n");
llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( - gmme->ptmsi, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); msg = llc_prim->oph.msg; msg->l3h = msg->tail; rc = gprs_gmm_build_ciph_auth_resp(gmme, imeisv_requested, ac_ref_nr, sres, msg); @@ -322,9 +407,9 @@ int rc; struct msgb *msg;
- LOGGMME(gmme, LOGL_INFO, "Tx GMM ATTACH REQUEST (new P-TMSI=0x%08x)\n", gmme->ptmsi); + LOGGMME(gmme, LOGL_INFO, "Tx GMM ATTACH REQUEST (new TLLI=0x%08x)\n", gmme->tlli); llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( - gmme->ptmsi, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); msg = llc_prim->oph.msg; msg->l3h = msg->tail; rc = gprs_gmm_build_attach_req(gmme, @@ -359,7 +444,7 @@ LOGGMME(gmme, LOGL_INFO, "Tx GMM ATTACH COMPL\n");
llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( - gmme->ptmsi, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); msg = llc_prim->oph.msg; msg->l3h = msg->tail; rc = gprs_gmm_build_attach_compl(gmme, msg); @@ -393,7 +478,7 @@
LOGGMME(gmme, LOGL_INFO, "Tx GMM DETACH REQUEST (MO)\n"); llc_prim = osmo_gprs_llc_prim_alloc_ll_unitdata_req( - gmme->ptmsi, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); + gmme->tlli, OSMO_GPRS_LLC_SAPI_GMM, NULL, GPRS_GMM_ALLOC_SIZE); msg = llc_prim->oph.msg; msg->l3h = msg->tail; rc = gprs_gmm_build_detach_req(gmme, detach_type, poweroff_type, msg); @@ -451,6 +536,11 @@ } gmme->old_ptmsi = gmme->ptmsi; gmme->ptmsi = mi.tmsi; + /* TS 24.008 4.7.1.4.1:"Upon receipt of the assigned P-TMSI, the MS + * shall derive the local TLLI from this P-TMSI and shall use it for + * addressing at lower layers": */ + gmme->old_tlli = gmme->tlli; + gmme->tlli = gprs_tmsi2tlli(gmme->ptmsi, TLLI_LOCAL); }
if (TLVP_PRES_LEN(&tp, GSM48_IE_GMM_TIMER_T3302, 1)) @@ -538,7 +628,8 @@ /* TODO: submit GMMSM-RELEASE-IND */
/* Submit LLGMM-ASSIGN-REQ as per TS 24.007 Annex C.3 */ - gmme->ptmsi = GPRS_GMM_TLLI_UNASSIGNED; + gmme->old_tlli = gmme->tlli; + gmme->tlli = GPRS_GMM_TLLI_UNASSIGNED; rc = gprs_gmm_submit_llgmm_assing_req(gmme); if (rc < 0) goto rejected; diff --git a/src/gmm/gmm_prim.c b/src/gmm/gmm_prim.c index b1119fe..e3e6fa6 100644 --- a/src/gmm/gmm_prim.c +++ b/src/gmm/gmm_prim.c @@ -244,10 +244,11 @@ }
/* 3GPP TS 24.007 9.3.2.1 GMMRR-ASSIGN-REQ:*/ -struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmrr_assign_req(uint32_t new_tlli) +struct osmo_gprs_gmm_prim *gprs_gmm_prim_alloc_gmmrr_assign_req(uint32_t old_tlli, uint32_t new_tlli) { struct osmo_gprs_gmm_prim *gmm_prim; gmm_prim = gmm_prim_gmmrr_alloc(OSMO_GPRS_GMM_GMMRR_ASSIGN, PRIM_OP_REQUEST, 0); + gmm_prim->gmmrr.tlli = old_tlli; gmm_prim->gmmrr.assign_req.new_tlli = new_tlli; return gmm_prim; } @@ -257,7 +258,7 @@ { struct osmo_gprs_gmm_prim *gmm_prim; gmm_prim = gmm_prim_gmmrr_alloc(OSMO_GPRS_GMM_GMMRR_PAGE, PRIM_OP_INDICATION, 0); - gmm_prim->gmmrr.page_ind.tlli = tlli; + gmm_prim->gmmrr.tlli = tlli; return gmm_prim; }
@@ -359,14 +360,10 @@ int rc; struct gprs_gmm_entity *gmme;
- gmme = llist_first_entry_or_null(&g_gmm_ctx->gmme_list, struct gprs_gmm_entity, list); - if (!gmme) { - gmme = gprs_gmm_gmme_alloc(); - OSMO_ASSERT(gmme); - } - gmme->ptmsi = gmm_prim->gmmreg.attach_req.ptmsi; - if (gmm_prim->gmmreg.attach_req.imsi[0] != '\0') - OSMO_STRLCPY_ARRAY(gmme->imsi, gmm_prim->gmmreg.attach_req.imsi); + gmme = gprs_gmm_gmme_find_or_create_by_ptmsi_imsi(gmm_prim->gmmreg.attach_req.ptmsi, + gmm_prim->gmmreg.attach_req.imsi); + OSMO_ASSERT(gmme); + if (gmm_prim->gmmreg.attach_req.imei[0] != '\0') OSMO_STRLCPY_ARRAY(gmme->imei, gmm_prim->gmmreg.attach_req.imei); if (gmm_prim->gmmreg.attach_req.imeisv[0] != '\0') @@ -383,10 +380,10 @@ static int gprs_gmm_prim_handle_gmmreg_detach_req(struct osmo_gprs_gmm_prim *gmm_prim) { int rc; - struct gprs_gmm_entity *gmme = gprs_gmm_find_gmme_by_tlli(gmm_prim->gmmreg.detach_req.ptmsi); + struct gprs_gmm_entity *gmme = gprs_gmm_find_gmme_by_ptmsi(gmm_prim->gmmreg.detach_req.ptmsi);
if (!gmme) { - LOGGMM(LOGL_ERROR, "Rx GMMREG-DETACH.req for unknown PTMSI=0x%08x\n", + LOGGMM(LOGL_ERROR, "Rx GMMREG-DETACH.req for unknown P-TMSI=0x%08x\n", gmm_prim->gmmreg.detach_req.ptmsi); return -EINVAL; } @@ -420,14 +417,9 @@ int rc; struct gprs_gmm_entity *gmme;
- gmme = llist_first_entry_or_null(&g_gmm_ctx->gmme_list, struct gprs_gmm_entity, list); - if (!gmme) { - gmme = gprs_gmm_gmme_alloc(); - OSMO_ASSERT(gmme); - } - gmme->ptmsi = gmm_prim->gmmsm.establish_req.ptmsi; - if (gmm_prim->gmmsm.establish_req.imsi[0] != '\0') - OSMO_STRLCPY_ARRAY(gmme->imsi, gmm_prim->gmmsm.establish_req.imsi); + gmme = gprs_gmm_gmme_find_or_create_by_ptmsi_imsi(gmm_prim->gmmsm.establish_req.ptmsi, + gmm_prim->gmmsm.establish_req.imsi); + OSMO_ASSERT(gmme); if (gmm_prim->gmmsm.establish_req.imei[0] != '\0') OSMO_STRLCPY_ARRAY(gmme->imei, gmm_prim->gmmsm.establish_req.imei); if (gmm_prim->gmmsm.establish_req.imeisv[0] != '\0') diff --git a/src/rlcmac/rlcmac_prim.c b/src/rlcmac/rlcmac_prim.c index e6f151a..3a05d4e 100644 --- a/src/rlcmac/rlcmac_prim.c +++ b/src/rlcmac/rlcmac_prim.c @@ -204,10 +204,11 @@ }
/* 3GPP TS 24.007 9.3.2.1 GMMRR-ASSIGN-REQ:*/ -struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(uint32_t new_tlli) +struct osmo_gprs_rlcmac_prim *osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(uint32_t old_tlli, uint32_t new_tlli) { struct osmo_gprs_rlcmac_prim *rlcmac_prim; rlcmac_prim = rlcmac_prim_gmmrr_alloc(OSMO_GPRS_RLCMAC_GMMRR_ASSIGN, PRIM_OP_REQUEST, 0); + rlcmac_prim->gmmrr.tlli = old_tlli; rlcmac_prim->gmmrr.assign_req.new_tlli = new_tlli; return rlcmac_prim; } @@ -217,7 +218,7 @@ { struct osmo_gprs_rlcmac_prim *rlcmac_prim; rlcmac_prim = rlcmac_prim_gmmrr_alloc(OSMO_GPRS_RLCMAC_GMMRR_PAGE, PRIM_OP_INDICATION, 0); - rlcmac_prim->gmmrr.page_ind.tlli = tlli; + rlcmac_prim->gmmrr.tlli = tlli; return rlcmac_prim; }
@@ -387,20 +388,48 @@ static int rlcmac_prim_handle_gmmrr_assign_req(struct osmo_gprs_rlcmac_prim *rlcmac_prim) { struct gprs_rlcmac_entity *gre; - - gre = gprs_rlcmac_find_entity_by_tlli(rlcmac_prim->gmmrr.assign_req.new_tlli); - if (!gre) { - LOGRLCMAC(LOGL_INFO, "GMMRR-ASSIGN.req: creating new entity TLLI=0x%08x\n", - rlcmac_prim->gmmrr.assign_req.new_tlli); - gre = gprs_rlcmac_entity_alloc(rlcmac_prim->gmmrr.assign_req.new_tlli); + uint32_t old_tlli = rlcmac_prim->gmmrr.tlli; + uint32_t new_tlli = rlcmac_prim->gmmrr.assign_req.new_tlli; + int rc = 0; + if (old_tlli == GPRS_RLCMAC_TLLI_UNASSIGNED) { + /* Case "create" */ + if (new_tlli == GPRS_RLCMAC_TLLI_UNASSIGNED) { + LOGRLCMAC(LOGL_ERROR, "GMMRR-ASSIGN.req: both old and new TLLIs are unassigned\n"); + rc = -EINVAL; + goto free_ret; + } + if ((gre = gprs_rlcmac_find_entity_by_tlli(new_tlli))) { + LOGRLCMAC(LOGL_ERROR, "GMMRR-ASSIGN.req: GRE with new TLLI=0x%08x already exists\n", new_tlli); + rc = -EINVAL; + goto free_ret; + } + LOGRLCMAC(LOGL_INFO, "GMMRR-ASSIGN.req: creating new entity TLLI=0x%08x\n", new_tlli); + gre = gprs_rlcmac_entity_alloc(new_tlli); OSMO_ASSERT(gre); + } else if (new_tlli == GPRS_RLCMAC_TLLI_UNASSIGNED) { + /* Case "destroy" */ + gre = gprs_rlcmac_find_entity_by_tlli(old_tlli); + if (!gre) { + LOGRLCMAC(LOGL_ERROR, "GMMRR-ASSIGN.req: GRE with TLLI=0x%08x not found\n", old_tlli); + rc = -ENOENT; + goto free_ret; + } + gprs_rlcmac_entity_free(gre); } else { - LOGRLCMAC(LOGL_INFO, "GMMRR-ASSIGN.req: TLLI=0x%08x already exists\n", - rlcmac_prim->gmmrr.assign_req.new_tlli); + /* Case "update", both old_tlli and new_tlli are valid */ + gre = gprs_rlcmac_find_entity_by_tlli(old_tlli); + if (!gre) { + LOGRLCMAC(LOGL_ERROR, "GMMRR-ASSIGN.req: GRE with TLLI=0x%08x not found\n", old_tlli); + rc = -ENOENT; + goto free_ret; + } + LOGGRE(gre, LOGL_INFO, "Update TLLI 0x%08x -> 0x%08x\n", old_tlli, new_tlli); + gre->tlli = new_tlli; }
+free_ret: msgb_free(rlcmac_prim->oph.msg); - return 0; + return rc; }
static int gprs_rlcmac_prim_gmmrr_upper_down(struct osmo_gprs_rlcmac_prim *rlcmac_prim) diff --git a/tests/gmm/Makefile.am b/tests/gmm/Makefile.am index fb3396d..c4adb2d 100644 --- a/tests/gmm/Makefile.am +++ b/tests/gmm/Makefile.am @@ -29,3 +29,8 @@ $(LIBOSMOCORE_LIBS) \ $(LIBOSMOGSM_LIBS) \ $(NULL) + +gmm_prim_test_LDFLAGS = \ + -Wl,--wrap=osmo_get_rand_id \ + -no-install \ + $(NULL) diff --git a/tests/gmm/gmm_prim_test.c b/tests/gmm/gmm_prim_test.c index 1b91640..b260f54 100644 --- a/tests/gmm/gmm_prim_test.c +++ b/tests/gmm/gmm_prim_test.c @@ -137,6 +137,15 @@ 0x08, 0x06, 0x00 };
+/* override, requires '-Wl,--wrap=osmo_get_rand_id' */ +int __real_osmo_get_rand_id(uint8_t *data, size_t len); +int __wrap_osmo_get_rand_id(uint8_t *data, size_t len) +{ + memset(data, 0x00, len); + return 0; +} + + int test_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data) { const char *pdu_name = osmo_gprs_gmm_prim_name(gmm_prim); @@ -196,7 +205,9 @@ case OSMO_GPRS_GMM_SAP_GMMRR: OSMO_ASSERT(OSMO_PRIM_HDR(&gmm_prim->oph) == OSMO_PRIM(OSMO_GPRS_GMM_GMMRR_ASSIGN, PRIM_OP_REQUEST)); - printf("%s(): Rx %s new_tlli=0x%08x\n", __func__, pdu_name, gmm_prim->gmmrr.assign_req.new_tlli); + printf("%s(): Rx %s old_tlli=0x%08x new_tlli=0x%08x\n", + __func__, pdu_name, + gmm_prim->gmmrr.tlli, gmm_prim->gmmrr.assign_req.new_tlli); break; default: printf("%s(): Unexpected Rx %s\n", __func__, pdu_name); @@ -211,7 +222,15 @@
switch (llc_prim->oph.sap) { case OSMO_GPRS_LLC_SAP_LLGMM: - printf("%s(): Rx %s TLLI=0x%08x\n", __func__, pdu_name, llc_prim->llgmm.tlli); + switch (OSMO_PRIM_HDR(&llc_prim->oph)) { + case OSMO_PRIM(OSMO_GPRS_LLC_LLGMM_ASSIGN, PRIM_OP_REQUEST): + printf("%s(): Rx %s old_TLLI=0x%08x new_TLLI=0x%08x\n", + __func__, pdu_name, + llc_prim->llgmm.tlli, llc_prim->llgmm.assign_req.tlli_new); + break; + default: + printf("%s(): Rx %s TLLI=0x%08x\n", __func__, pdu_name, llc_prim->llgmm.tlli); + } break; case OSMO_GPRS_LLC_SAP_LL: printf("%s(): Rx %s TLLI=0x%08x SAPI=%s l3=[%s]\n", __func__, pdu_name, @@ -231,8 +250,8 @@ struct osmo_gprs_gmm_prim *gmm_prim; struct osmo_gprs_llc_prim *llc_prim; int rc; - uint32_t ptmsi = 0x00000000; - uint32_t tlli = 0x00000000; + uint32_t ptmsi = 0x00001234; + uint32_t rand_tlli = 0x80001234; char *imsi = "1234567890"; char *imei = "42342342342342"; char *imeisv = "4234234234234275"; @@ -259,21 +278,21 @@ OSMO_ASSERT(rc == 0);
/* Network answers with GMM Identity Req: */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_identity_req, sizeof(pdu_gmm_identity_req)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_identity_req, sizeof(pdu_gmm_identity_req)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); /* As a result, MS answers GMM Identity Resp */
/* Network sends GMM Ciph Auth Req */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_auth_ciph_req, sizeof(pdu_gmm_auth_ciph_req)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_auth_ciph_req, sizeof(pdu_gmm_auth_ciph_req)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); /* As a result, MS answers GMM Ciph Auth Resp */
/* Network sends GMM Attach Accept */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_att_acc, sizeof(pdu_gmm_att_acc)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_att_acc, sizeof(pdu_gmm_att_acc)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); @@ -292,7 +311,7 @@ OSMO_ASSERT(rc == 0);
/* Network sends GMM Detach Accept */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_detach_acc, sizeof(pdu_gmm_detach_acc)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_detach_acc, sizeof(pdu_gmm_detach_acc)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); @@ -307,8 +326,8 @@ struct osmo_gprs_gmm_prim *gmm_prim; struct osmo_gprs_llc_prim *llc_prim; int rc; - uint32_t ptmsi = 0x00000000; - uint32_t tlli = 0x00000000; + uint32_t ptmsi = 0x00001234; + uint32_t rand_tlli = 0x80001234; char *imsi = "1234567890"; char *imei = "42342342342342"; char *imeisv = "4234234234234275"; @@ -337,21 +356,21 @@ /* MS sends GMM Attach Req first since its not eyt attached */
/* Network answers with GMM Identity Req: */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_identity_req, sizeof(pdu_gmm_identity_req)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_identity_req, sizeof(pdu_gmm_identity_req)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); /* As a result, MS answers GMM Identity Resp */
/* Network sends GMM Ciph Auth Req */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_auth_ciph_req, sizeof(pdu_gmm_auth_ciph_req)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_auth_ciph_req, sizeof(pdu_gmm_auth_ciph_req)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); /* As a result, MS answers GMM Ciph Auth Resp */
/* Network sends GMM Attach Accept */ - llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_att_acc, sizeof(pdu_gmm_att_acc)); + llc_prim = gprs_llc_prim_alloc_ll_unitdata_ind(rand_tlli, OSMO_GPRS_LLC_SAPI_GMM, (uint8_t *)pdu_gmm_att_acc, sizeof(pdu_gmm_att_acc)); OSMO_ASSERT(llc_prim); rc = osmo_gprs_gmm_prim_llc_lower_up(llc_prim); OSMO_ASSERT(rc == 0); diff --git a/tests/gmm/gmm_prim_test.err b/tests/gmm/gmm_prim_test.err index 12d39da..d81765b 100644 --- a/tests/gmm/gmm_prim_test.err +++ b/tests/gmm/gmm_prim_test.err @@ -3,16 +3,16 @@ DLGLOBAL INFO GMM_MS{Null}: Received Event ENABLE_GPRS_MODE DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM ATTACH REQUEST (new P-TMSI=0x00000000) +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234) DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM IDENTITY REQUEST mi_type=IMEI -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM IDENTITY RESPONSE +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM IDENTITY REQUEST mi_type=IMEI +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM IDENTITY RESPONSE DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM AUTHENTICATION AND CIPHERING REQUEST -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM ATTACH ACCEPT +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM ATTACH ACCEPT DLGLOBAL INFO GMME(PTMSI-ea711b41) Tx GMM ATTACH COMPL DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered @@ -24,23 +24,23 @@ DLGLOBAL DEBUG GMME(PTMSI-ea711b41) Rx GMM DETACH ACCEPT (MO) force_standby_indicated=false DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: Received Event DETACH_ACCEPTED DLGLOBAL INFO GMM_MS{DeregisteredInitiated}: state_chg to Deregistered -DLGLOBAL DEBUG GMME(PTMSI-ffffffff) free() +DLGLOBAL DEBUG GMME(PTMSI-ea711b41) free() DLGLOBAL INFO GMM_MS{Deregistered}: Deallocated DLGLOBAL INFO Rx from upper layers: GMMSM-ESTABLISH.request DLGLOBAL INFO GMM_MS{Null}: Allocated DLGLOBAL INFO GMM_MS{Null}: Received Event ENABLE_GPRS_MODE DLGLOBAL INFO GMM_MS{Null}: state_chg to Deregistered DLGLOBAL INFO GMM_MS{Deregistered}: Received Event ATTACH_REQUESTED -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM ATTACH REQUEST (new P-TMSI=0x00000000) +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM ATTACH REQUEST (new TLLI=0x80001234) DLGLOBAL INFO GMM_MS{Deregistered}: state_chg to RegisteredInitiated DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM IDENTITY REQUEST mi_type=IMEI -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM IDENTITY RESPONSE +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM IDENTITY REQUEST mi_type=IMEI +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM IDENTITY RESPONSE DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM AUTHENTICATION AND CIPHERING REQUEST -DLGLOBAL INFO GMME(PTMSI-00000000) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM AUTHENTICATION AND CIPHERING REQUEST +DLGLOBAL INFO GMME(PTMSI-00001234) Tx GMM GMM AUTHENTICATION AND CIPHERING RESPONSE DLGLOBAL INFO Rx from lower layers: LL-UNITDATA.indication -DLGLOBAL DEBUG GMME(PTMSI-00000000) Rx GMM ATTACH ACCEPT +DLGLOBAL DEBUG GMME(PTMSI-00001234) Rx GMM ATTACH ACCEPT DLGLOBAL INFO GMME(PTMSI-ea711b41) Tx GMM ATTACH COMPL DLGLOBAL INFO GMM_MS{RegisteredInitiated}: Received Event ATTACH_ACCEPTED DLGLOBAL INFO GMM_MS{RegisteredInitiated}: state_chg to Registered diff --git a/tests/gmm/gmm_prim_test.ok b/tests/gmm/gmm_prim_test.ok index f003efc..e371b93 100644 --- a/tests/gmm/gmm_prim_test.ok +++ b/tests/gmm/gmm_prim_test.ok @@ -1,23 +1,23 @@ ==== test_gmm_prim_ms_gmmreg() [start] ==== -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 00 00 00 f0 00 00 00 00 00 e1 ] -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ] -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 13 02 ] -test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request TLLI=0x00000000 -test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request TLLI=0x00000000 -test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request new_tlli=0xea711b41 +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 e1 ] +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ] +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 13 02 ] +test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xffffffff new_TLLI=0x80001234 +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 test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0xea711b41 SAPI=GMM l3=[08 05 20 0a 00 05 f4 ea 71 1b 41 ] -test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request TLLI=0x00000000 +test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xea711b41 new_TLLI=0xffffffff test_gmm_prim_up_cb(): Rx GMMREG-DETACH.confirm detach_type='GPRS detach' ==== test_gmm_prim_ms_gmmreg() [end] ==== ==== test_gmm_prim_ms_gmmsm() [start] ==== -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 00 00 00 f0 00 00 00 00 00 e1 ] -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ] -test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x00000000 SAPI=GMM l3=[08 13 02 ] -test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request TLLI=0x00000000 -test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request TLLI=0x00000000 -test_gmm_prim_down_cb(): Rx GMRR-ASSIGN.request new_tlli=0xea711b41 +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 01 04 97 07 00 00 01 0a 00 05 f4 00 00 12 34 00 f0 00 00 00 00 00 e1 ] +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 16 08 42 32 24 43 32 24 43 f2 ] +test_gmm_prim_llc_down_cb(): Rx LL-UNITDATA.request TLLI=0x80001234 SAPI=GMM l3=[08 13 02 ] +test_gmm_prim_llc_down_cb(): Rx LLGMM-ASSIGN.request old_TLLI=0xffffffff new_TLLI=0x80001234 +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 GMMSM-ESTABLISH.confirm sess_id=1234 accepted=1 rej_cause=0 ==== test_gmm_prim_ms_gmmsm() [end] ==== diff --git a/tests/rlcmac/rlcmac_prim_test.c b/tests/rlcmac/rlcmac_prim_test.c index 604546d..5633da2 100644 --- a/tests/rlcmac/rlcmac_prim_test.c +++ b/tests/rlcmac/rlcmac_prim_test.c @@ -427,7 +427,8 @@
switch (rlcmac_prim->oph.sap) { case OSMO_GPRS_RLCMAC_SAP_GMMRR: - printf("%s(): Rx %s TLLI=0x%08x\n", __func__, pdu_name, rlcmac_prim->gmmrr.page_ind.tlli); + printf("%s(): Rx %s TLLI=0x%08x\n", __func__, pdu_name, + rlcmac_prim->gmmrr.tlli); break; case OSMO_GPRS_RLCMAC_SAP_GRR: printf("%s(): Rx %s TLLI=0x%08x ll=[%s]\n", __func__, pdu_name, @@ -911,7 +912,7 @@ uint8_t rrbp = GPRS_RLCMAC_RRBP_N_plus_17_18;
/* Notify RLCMAC about our TLLI */ - rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(tlli); + rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(GPRS_RLCMAC_TLLI_UNASSIGNED, tlli); rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_dl_tbf) == GSM_MACBLOCK_LEN); @@ -961,7 +962,7 @@ uint8_t usf_li[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1, 2 };
/* Notify RLCMAC about our TLLI */ - rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(tlli); + rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_gmmrr_assign_req(GPRS_RLCMAC_TLLI_UNASSIGNED, tlli); rc = osmo_gprs_rlcmac_prim_upper_down(rlcmac_prim);
OSMO_ASSERT(sizeof(ccch_imm_ass_pkt_dl_tbf) == GSM_MACBLOCK_LEN);