From 48a307e172b508240a15e8ab5a7c60a24b2b5e1e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 5 Jun 2024 11:24:13 +0200 Subject: [PATCH] Use 5G-S-TMSI in RRC connection setup procedures * Use the 5G-S-TMSI stored in RRC to be used as UE identity * Use 5G-S-TMSI part 1 in RRCSetupRequest encoding (TS 38.331 clause 5.3.3.3) * Set the ng-5G-S-TMSI-Value in RRCSetupComplete to ng-5G-S-TMSI-Part2 (5.3.3.4 of 3GPP TS 38.331) * current and only scenario: RRCSetup is received in response to an RRCSetupRequest --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 52 ++++++++++++++++++++++++----- openair2/RRC/NR/MESSAGES/asn1_msg.h | 4 ++- openair2/RRC/NR_UE/rrc_UE.c | 6 +++- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index b66625e6b2..e3df557d3d 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -765,7 +765,7 @@ int do_RRCReconfiguration(const gNB_RRC_UE_t *UE, return((enc_rval.encoded+7)/8); } -int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv) +int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI) { NR_UL_CCCH_Message_t ul_ccch_msg = {0}; ul_ccch_msg.message.present = NR_UL_CCCH_MessageType_PR_c1; @@ -773,24 +773,34 @@ int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv) c1->present = NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest; asn1cCalloc(c1->choice.rrcSetupRequest, rrcSetupRequest); - if (1) { + if (fiveG_S_TMSI == UINT64_MAX) { + /* set the ue-Identity to a random value */ rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_randomValue; BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.randomValue; str->size = 5; str->bits_unused = 1; - str->buf = CALLOC(1, str->size); + str->buf = calloc_or_fail(str->size, sizeof(str->buf[0])); str->buf[0] = rv[0]; str->buf[1] = rv[1]; str->buf[2] = rv[2]; str->buf[3] = rv[3]; str->buf[4] = rv[4] & 0xfe; } else { + uint64_t fiveG_S_TMSI_part1 = fiveG_S_TMSI & ((1ULL << 39) - 1); + /** set the ue-Identity to ng-5G-S-TMSI-Part1 + * ng-5G-S-TMSI-Part1: the rightmost 39 bits of 5G-S-TMSI + * BIT STRING (SIZE (39)) - 3GPP TS 38.331 */ + LOG_D(NR_RRC, "5G-S-TMSI: %lu, set the ue-Identity to ng-5G-S-TMSI-Part1 %lu\n", fiveG_S_TMSI, fiveG_S_TMSI_part1); rrcSetupRequest->rrcSetupRequest.ue_Identity.present = NR_InitialUE_Identity_PR_ng_5G_S_TMSI_Part1; BIT_STRING_t *str = &rrcSetupRequest->rrcSetupRequest.ue_Identity.choice.ng_5G_S_TMSI_Part1; - str->size = 1; - str->bits_unused = 0; - str->buf = CALLOC(1, str->size); - str->buf[0] = 0x12; + str->size = 5; + str->bits_unused = 1; + str->buf = calloc_or_fail(str->size, sizeof(str->buf[0])); + str->buf[0] = (fiveG_S_TMSI_part1 >> 31) & 0xff; + str->buf[1] = (fiveG_S_TMSI_part1 >> 23) & 0xff; + str->buf[2] = (fiveG_S_TMSI_part1 >> 15) & 0xff; + str->buf[3] = (fiveG_S_TMSI_part1 >> 7) & 0xff; + str->buf[4] = (fiveG_S_TMSI_part1 << 1) & 0xff; } rrcSetupRequest->rrcSetupRequest.establishmentCause = NR_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; @@ -872,6 +882,8 @@ int do_RRCSetupComplete(uint8_t *buffer, size_t buffer_size, const uint8_t Transaction_id, uint8_t sel_plmn_id, + bool is_rrc_connection_setup, + uint64_t fiveG_s_tmsi, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { @@ -887,7 +899,31 @@ int do_RRCSetupComplete(uint8_t *buffer, NR_RRCSetupComplete_IEs_t *ies = RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete; ies->selectedPLMN_Identity = sel_plmn_id; ies->registeredAMF = NULL; - ies->ng_5G_S_TMSI_Value = NULL; + /* RRCSetup is received in response to an RRCSetupRequest + * set the ng-5G-S-TMSI-Value to ng-5G-S-TMSI-Part2 + * i.e. the leftmost 9 bits of 5G-S-TMSI (5.3.3.4 of 3GPP TS 38.331) */ + if (fiveG_s_tmsi != UINT64_MAX) { + if (is_rrc_connection_setup) { + ies->ng_5G_S_TMSI_Value = calloc_or_fail(1, sizeof(*ies->ng_5G_S_TMSI_Value)); + ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI_Part2; + BIT_STRING_t *str = &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI_Part2; + str->size = 2; + str->bits_unused = 7; + str->buf = calloc_or_fail(str->size, sizeof(str->buf[0])); + uint16_t fiveG_s_tmsi_part2 = (fiveG_s_tmsi >> 39) & ((1ULL << 9) - 1); + str->buf[0] = (fiveG_s_tmsi_part2 >> (8 - str->bits_unused)) & 0xFF; + str->buf[1] = (fiveG_s_tmsi_part2 << str->bits_unused) & 0xFF; + LOG_D(NR_RRC, "5G-S-TMSI part 2 %d in RRCSetupComplete (5G-S-TMSI %ld)\n", fiveG_s_tmsi_part2, fiveG_s_tmsi); + } else { + ies->ng_5G_S_TMSI_Value = CALLOC(1, sizeof(struct NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value)); + ies->ng_5G_S_TMSI_Value->present = NR_RRCSetupComplete_IEs__ng_5G_S_TMSI_Value_PR_ng_5G_S_TMSI; + FIVEG_S_TMSI_TO_BIT_STRING(fiveG_s_tmsi, &ies->ng_5G_S_TMSI_Value->choice.ng_5G_S_TMSI); + LOG_D(NR_RRC, "5G-S-TMSI %lu in RRCSetupComplete\n", fiveG_s_tmsi); + } + } else { + LOG_D(NR_RRC, "5G-S-TMSI is not available!\n"); + ies->ng_5G_S_TMSI_Value = NULL; + } memset(&ies->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(&ies->dedicatedNAS_Message, dedicatedInfoNAS, dedicatedInfoNASLength); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index d7642ca663..a6c5e25aec 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -119,12 +119,14 @@ int do_RRCSetupComplete(uint8_t *buffer, size_t buffer_size, const uint8_t Transaction_id, uint8_t sel_plmn_id, + bool is_rrc_connection_setup, + uint64_t fiveG_S_TMSI, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS); int do_NR_HandoverPreparationInformation(const uint8_t *uecap_buf, int uecap_buf_size, uint8_t *buf, int buf_size); -int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv); +int do_RRCSetupRequest(uint8_t *buffer, size_t buffer_size, uint8_t *rv, uint64_t fiveG_S_TMSI_part1); int do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id); diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 9575fa1940..6b8a12e4cc 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -276,7 +276,7 @@ static void nr_rrc_ue_prepare_RRCSetupRequest(NR_UE_RRC_INST_t *rrc) } uint8_t buf[1024]; - int len = do_RRCSetupRequest(buf, sizeof(buf), rv); + int len = do_RRCSetupRequest(buf, sizeof(buf), rv, rrc->fiveG_S_TMSI); nr_rlc_srb_recv_sdu(rrc->ue_id, 0, buf, len); } @@ -1140,13 +1140,17 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const initialNasMsg.nas_data = malloc_or_fail(initialNasMsg.length); memcpy(initialNasMsg.nas_data, nr_nas_attach_req_imsi_dummy_NSA_case, initialNasMsg.length); } + // Encode RRCSetupComplete int size = do_RRCSetupComplete(buffer, sizeof(buffer), Transaction_id, rrc->selected_plmn_identity, + rrc->ra_trigger == RRC_CONNECTION_SETUP, + rrc->fiveG_S_TMSI, (const uint32_t)initialNasMsg.length, (const char*)initialNasMsg.nas_data); + // Free dynamically allocated data (heap allocated in both SA and NSA) free(initialNasMsg.nas_data);