From c0bc613f603c52943c010ffaa55ccd95872d9bd9 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Thu, 20 Jul 2023 10:43:20 +0200 Subject: [PATCH] llc: Introduce LL-ASSIGN.ind TS 24.007, TS 24.008, TS 44.064 nor TS 44.065 explain how the TLLI update happening during GMM RAU propagates to the SNDCP layer. GMM only has interfaces towards LLC and GRR, and uses LLGMM-Assign.Req and GMMRR-Assign.req to update the TLLI in the respective layers. This patch adds a new primitive in the LL interface (LLC->SNDCP) LL-Assign.ind to propagate the LLGM-Assign.req received from GMM towards SNDCP, so that it can use the new TLLI in order to address the specific MS. Change-Id: Icb858f5397414b6d4183c21f13d35c0166ca7635 --- include/osmocom/gprs/llc/llc_prim.h | 5 +++++ include/osmocom/gprs/llc/llc_private.h | 3 ++- src/llc/llc_ll.c | 22 ++++++++++++++++++++++ src/llc/llc_llgmm.c | 3 +++ tests/llc/llc_prim_test.c | 14 +++++++++++--- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/include/osmocom/gprs/llc/llc_prim.h b/include/osmocom/gprs/llc/llc_prim.h index c03f396..adcd22f 100644 --- a/include/osmocom/gprs/llc/llc_prim.h +++ b/include/osmocom/gprs/llc/llc_prim.h @@ -56,6 +56,7 @@ enum osmo_gprs_llc_ll_prim_type { OSMO_GPRS_LLC_LL_DATA, /* Req/Ind/Cnf: TLLI, L3-PDU, Ref, QoS, Radio Prio */ OSMO_GPRS_LLC_LL_UNITDATA, /* Req/Ind: TLLI, L3-PDU, QoS, Radio Prio, Ciph, ... */ OSMO_GPRS_LLC_LL_STATUS, /* Ind: TLLI, Cause */ + OSMO_GPRS_LLC_LL_ASSIGN, /* Ind: TLLI old, TLLI new; Osmocom specific */ }; extern const struct value_string osmo_gprs_llc_ll_prim_type_names[]; @@ -214,6 +215,10 @@ struct osmo_gprs_llc_ll_prim { struct { uint8_t cause; } status_ind; + /* OSMO_GPRS_LLC_LL_ASSIGN | Ind */ + struct { + uint32_t tlli_new; + } assign_ind; }; }; diff --git a/include/osmocom/gprs/llc/llc_private.h b/include/osmocom/gprs/llc/llc_private.h index 78e6e9f..44d32e2 100644 --- a/include/osmocom/gprs/llc/llc_private.h +++ b/include/osmocom/gprs/llc/llc_private.h @@ -297,6 +297,7 @@ struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_xid_ind(uint32_t tlli, enum os uint8_t *l3_par, unsigned int l3_par_len); struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_xid_cnf(uint32_t tlli, enum osmo_gprs_llc_sapi ll_sapi, uint8_t *l3_par, unsigned int l3_par_len); +struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_assign_ind(uint32_t old_tlli, uint32_t new_tlli); struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_unitdata_ind( uint32_t tlli, enum osmo_gprs_llc_sapi ll_sapi, uint8_t *l3_pdu, size_t l3_pdu_len); @@ -305,7 +306,7 @@ int gprs_llc_lle_submit_prim_ll_xid_ind(struct gprs_llc_lle *lle, int gprs_llc_lle_submit_prim_ll_xid_cnf(struct gprs_llc_lle *lle, const struct gprs_llc_xid_field *xid_field_response_l3, const struct gprs_llc_xid_field *xid_field_request_l3); - +int gprs_llc_llme_submit_prim_ll_assign_ind(uint32_t old_tlli, uint32_t new_tlli); /* llc_llgmm.c */ int gprs_llc_prim_llgmm_upper_down(struct osmo_gprs_llc_prim *llc_prim); diff --git a/src/llc/llc_ll.c b/src/llc/llc_ll.c index a13a7f5..b907299 100644 --- a/src/llc/llc_ll.c +++ b/src/llc/llc_ll.c @@ -40,6 +40,7 @@ const struct value_string osmo_gprs_llc_ll_prim_type_names[] = { { OSMO_GPRS_LLC_LL_DATA, "DATA" }, { OSMO_GPRS_LLC_LL_UNITDATA, "UNITDATA" }, { OSMO_GPRS_LLC_LL_STATUS, "STATUS" }, + { OSMO_GPRS_LLC_LL_ASSIGN, "ASSIGN" }, { 0, NULL } }; @@ -152,6 +153,17 @@ struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_unitdata_ind( return llc_prim; } +/* LL-ASSIGN.ind (MS/SGSN): Osmocom specific, used to inform TLLI update LLC->SNDCP */ +struct osmo_gprs_llc_prim *gprs_llc_prim_alloc_ll_assign_ind(uint32_t old_tlli, uint32_t new_tlli) +{ + struct osmo_gprs_llc_prim *llc_prim; + llc_prim = llc_prim_ll_alloc(OSMO_GPRS_LLC_LL_ASSIGN, PRIM_OP_INDICATION, 0); + llc_prim->ll.tlli = old_tlli; + llc_prim->ll.sapi = OSMO_GPRS_LLC_SAPI_SNDCP3; /* any SNDCP SAPI is good */ + llc_prim->ll.assign_ind.tlli_new = new_tlli; + return llc_prim; +} + /******************************** * Handling to upper layers: ********************************/ @@ -192,6 +204,16 @@ int gprs_llc_lle_submit_prim_ll_xid_cnf(struct gprs_llc_lle *lle, return gprs_llc_prim_call_up_cb(llc_prim_tx); } + +int gprs_llc_llme_submit_prim_ll_assign_ind(uint32_t old_tlli, uint32_t new_tlli) +{ + struct osmo_gprs_llc_prim *llc_prim_tx; + llc_prim_tx = gprs_llc_prim_alloc_ll_assign_ind(old_tlli, new_tlli); + OSMO_ASSERT(llc_prim_tx); + + return gprs_llc_prim_call_up_cb(llc_prim_tx); +} + /******************************** * Handling from upper layers: ********************************/ diff --git a/src/llc/llc_llgmm.c b/src/llc/llc_llgmm.c index d85a30e..f33d6de 100644 --- a/src/llc/llc_llgmm.c +++ b/src/llc/llc_llgmm.c @@ -207,6 +207,9 @@ static int llc_prim_handle_llgmm_assign_req(struct osmo_gprs_llc_prim *llc_prim) llme->old_tlli = old_tlli; llme->tlli = new_tlli; llme->state = OSMO_GPRS_LLC_LLMS_ASSIGNED; + /* Inform SNDCP about the TLLI change so it can update it too: */ + if (old_tlli != new_tlli) + gprs_llc_llme_submit_prim_ll_assign_ind(old_tlli, new_tlli); } else if (old_tlli != TLLI_UNASSIGNED && new_tlli == TLLI_UNASSIGNED) { /* TLLI Unassignment 8.3.3) */ llme->tlli = llme->old_tlli = 0; diff --git a/tests/llc/llc_prim_test.c b/tests/llc/llc_prim_test.c index bcba783..b9e2e0e 100644 --- a/tests/llc/llc_prim_test.c +++ b/tests/llc/llc_prim_test.c @@ -48,9 +48,17 @@ int test_llc_prim_up_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data) 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, - llc_prim->ll.tlli, osmo_gprs_llc_sapi_name(llc_prim->ll.sapi), - osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len)); + switch (OSMO_PRIM_HDR(&llc_prim->oph)) { + case OSMO_PRIM(OSMO_GPRS_LLC_LL_ASSIGN, PRIM_OP_INDICATION): + printf("%s(): Rx %s TLLI=0x%08x NEW_TLLI=x%08x\n", __func__, pdu_name, + llc_prim->ll.tlli, llc_prim->ll.assign_ind.tlli_new); + break; + default: + printf("%s(): Rx %s TLLI=0x%08x SAPI=%s l3=[%s]\n", __func__, pdu_name, + llc_prim->ll.tlli, osmo_gprs_llc_sapi_name(llc_prim->ll.sapi), + osmo_hexdump(llc_prim->ll.l3_pdu, llc_prim->ll.l3_pdu_len)); + break; + } break; default: printf("%s(): Unexpected Rx %s\n", __func__, pdu_name);