From d73a9148de07b03f368c1c000690b2be2a7d4fb3 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 12 Nov 2025 17:32:04 +0100 Subject: [PATCH] Refactor: add common helper functions to construct 5G-S-TMSI * 5G-S-TMSI construction is defined in 3GPP TS 23.003 and relevant at both gNB and UE side * Add helper functions to be later used in NG Paging * Adopt in NAS UE --- common/utils/nr/nr_common.c | 32 ++++++++++++++++++++++++++++++++ common/utils/nr/nr_common.h | 6 ++++++ openair3/NAS/NR_UE/nr_nas_msg.c | 3 ++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 96b8681cff..cfbb09e939 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -1487,3 +1487,35 @@ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2) } return beta_dmrs_pusch; } + +/** @brief Construct full 5G-S-TMSI from 5G-S-TMSI components + * @param amf_set_id AMF Set ID (10 bits) + * @param amf_pointer AMF Pointer (6 bits) + * @param m_tmsi 5G-TMSI (32 bits) + * @return Full 5G-S-TMSI (48 bits) + * @note The 5G-S-TMSI is constructed as a 48-bit value: + * - Bits 38-47: AMF Set ID (10 bits) + * - Bits 32-37: AMF Pointer (6 bits) + * - Bits 0-31: 5G-TMSI (32 bits) + * @ref 3GPP TS 23.003 */ +uint64_t nr_construct_5g_s_tmsi(uint16_t amf_set_id, uint8_t amf_pointer, uint32_t m_tmsi) +{ + // Construct full 5G-S-TMSI: <5G-TMSI (32 bits)> + return ((uint64_t)amf_set_id << 38) | ((uint64_t)amf_pointer << 32) | m_tmsi; +} + +/** @brief Construct 5G-S-TMSI-Part1 from 5G-S-TMSI components + * @param amf_set_id AMF Set ID (10 bits) + * @param amf_pointer AMF Pointer (6 bits) + * @param m_tmsi 5G-TMSI (32 bits) + * @return 5G-S-TMSI-Part1 (rightmost 39 bits of the full 5G-S-TMSI) + * @note 5G-S-TMSI-Part1 is the rightmost 39 bits of the full 5G-S-TMSI: + * - Bits 32-37: AMF Pointer (6 bits) + * - Bits 0-31: 5G-TMSI (32 bits) + * @ref 3GPP TS 23.003 */ +uint64_t nr_construct_5g_s_tmsi_part1(uint16_t amf_set_id, uint8_t amf_pointer, uint32_t m_tmsi) +{ + // Construct full 5G-S-TMSI and extract Part1: rightmost 39 bits + uint64_t full_s_tmsi = nr_construct_5g_s_tmsi(amf_set_id, amf_pointer, m_tmsi); + return full_s_tmsi & ((1ULL << 39) - 1); +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index e62d66658c..42ea232140 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -357,6 +357,12 @@ frequency_range_t get_freq_range_from_band(uint16_t band); */ float get_beta_dmrs(int num_cdm_groups_no_data, bool is_type2); +/** @brief Construct full 5G-S-TMSI from 5G-S-TMSI components */ +uint64_t nr_construct_5g_s_tmsi(uint16_t amf_set_id, uint8_t amf_pointer, uint32_t m_tmsi); + +/** @brief Construct 5G-S-TMSI-Part1 from 5G-S-TMSI components */ +uint64_t nr_construct_5g_s_tmsi_part1(uint16_t amf_set_id, uint8_t amf_pointer, uint32_t m_tmsi); + #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) #define BOUNDED_EVAL(a, b, c) (min(c, max(a, b))) diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 8f4f9bd280..64f9feef54 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -38,6 +38,7 @@ #include #include #include "common/utils/ds/byte_array.h" +#include "common/utils/nr/nr_common.h" #include "AuthenticationResponseParameter.h" #include "FGCNasMessageContainer.h" #include "FGSDeregistrationRequestUEOriginating.h" @@ -1787,7 +1788,7 @@ static void send_nas_5gmm_ind(instance_t instance, const Guti5GSMobileIdentity_t MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_5GMM_IND); nas_5gmm_ind_t *ind = &NAS_5GMM_IND(msg); LOG_I(NR_RRC, "5G-GUTI: AMF pointer %u, AMF Set ID %u, 5G-TMSI %u \n", guti->amfpointer, guti->amfsetid, guti->tmsi); - ind->fiveG_STMSI = ((uint64_t)guti->amfsetid << 38) | ((uint64_t)guti->amfpointer << 32) | guti->tmsi; + ind->fiveG_STMSI = nr_construct_5g_s_tmsi(guti->amfsetid, guti->amfpointer, guti->tmsi); itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); }