From 950becb423bc41db42e80050272bdaaa4bbc8741 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 4 Oct 2023 15:30:14 -0400 Subject: [PATCH 01/12] Store allowed NSSAIs from NAS message Request default PDU session with first NSSAI from the list --- executables/nr-uesoftmodem.c | 1 + openair2/COMMON/as_message.h | 7 ++ openair2/COMMON/rrc_messages_def.h | 1 + openair2/COMMON/rrc_messages_types.h | 2 + openair3/NAS/NR_UE/nr_nas_msg_sim.c | 158 +++++++++++++++++++++++---- openair3/NAS/NR_UE/nr_nas_msg_sim.h | 7 ++ 6 files changed, 154 insertions(+), 22 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index c970b1d09d..b734d9569b 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -100,6 +100,7 @@ pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; +nr_nas_msg_snssai_t nas_allowed_nssai[8]; // not used in UE instance_t CUuniqInstance=0; diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h index 0848714c2c..c4724b5458 100644 --- a/openair2/COMMON/as_message.h +++ b/openair2/COMMON/as_message.h @@ -464,6 +464,13 @@ typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t; */ typedef ul_info_transfer_ind_t dl_info_transfer_ind_t; +typedef struct nas_pdu_session_req_s { + int pdusession_id; + int pdusession_type; + int sst; + int sd; +} nas_pdu_session_req_t; + /* * -------------------------------------------------------------------------- * Radio Access Bearer establishment diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 8609aa45d2..80e191db9f 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -82,3 +82,4 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr // eNB: RLC -> RRC messages MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) +MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, NasPduSessionReq, nas_pdu_session_req) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 037dfbe86c..c7fc58b6cb 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -92,6 +92,7 @@ #define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req #define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa +#define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { @@ -440,6 +441,7 @@ typedef nas_release_ind_t NasConnReleaseInd; typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef dl_info_transfer_ind_t NasDlDataInd; +typedef nas_pdu_session_req_t NasPduSessionReq; // eNB: realtime -> RRC messages typedef struct rrc_subframe_process_s { protocol_ctxt_t ctxt; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 015b2a8f9e..2fc5209f6f 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -58,6 +58,8 @@ uint32_t registration_request_len; extern char *baseNetAddress; extern uint16_t NB_UE_INST; static nr_ue_nas_t nr_ue_nas = {0}; +static nr_ue_nas_t nr_ue_nas; +extern nr_nas_msg_snssai_t nas_allowed_nssai[8]; static int nas_protected_security_header_encode( char *buffer, @@ -778,7 +780,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi initialNasMsg->data[2 + i] = mac[i]; } -static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg) +static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, nas_pdu_session_req_t *pdu_req) { //wait send RegistrationComplete usleep(100*150); @@ -790,11 +792,11 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * uint8_t *req_buffer = malloc(req_length); pdu_session_establishment_request_msg pdu_session_establish; pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE; - pdu_session_establish.pdusessionid = 10; + pdu_session_establish.pdusessionid = pdu_req->pdusession_id; pdu_session_establish.pti = 1; pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ; pdu_session_establish.maxdatarate = 0xffff; - pdu_session_establish.pdusessiontype = 0x91; + pdu_session_establish.pdusessiontype = pdu_req->pdusession_type; encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer); @@ -827,21 +829,21 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length; mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer; size += (2+req_length); - mm_msg->uplink_nas_transport.pdusessionid = 10; + mm_msg->uplink_nas_transport.pdusessionid = pdu_req->pdusession_id; mm_msg->uplink_nas_transport.requesttype = 1; size += 3; - const bool has_nssai_sd = nas->uicc->nssai_sd != 0xffffff; // 0xffffff means "no SD", TS 23.003 + const bool has_nssai_sd = pdu_req->sd != 0xffffff; // 0xffffff means "no SD", TS 23.003 const size_t nssai_len = has_nssai_sd ? 4 : 1; mm_msg->uplink_nas_transport.snssai.length = nssai_len; //Fixme: it seems there are a lot of memory errors in this: this value was on the stack, // but pushed in a itti message to another thread // this kind of error seems in many places in 5G NAS mm_msg->uplink_nas_transport.snssai.value = calloc(1, nssai_len); - mm_msg->uplink_nas_transport.snssai.value[0] = nas->uicc->nssai_sst; + mm_msg->uplink_nas_transport.snssai.value[0] = pdu_req->sst; if (has_nssai_sd) { - mm_msg->uplink_nas_transport.snssai.value[1] = (nas->uicc->nssai_sd >> 16) & 0xFF; - mm_msg->uplink_nas_transport.snssai.value[2] = (nas->uicc->nssai_sd >> 8) & 0xFF; - mm_msg->uplink_nas_transport.snssai.value[3] = (nas->uicc->nssai_sd) & 0xFF; + mm_msg->uplink_nas_transport.snssai.value[1] = (pdu_req->sd >> 16) & 0xFF; + mm_msg->uplink_nas_transport.snssai.value[2] = (pdu_req->sd >> 8) & 0xFF; + mm_msg->uplink_nas_transport.snssai.value[3] = (pdu_req->sd) & 0xFF; } size += 1 + 1 + nssai_len; int dnnSize=strlen(nas->uicc->dnnStr); @@ -912,6 +914,116 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i itti_send_msg_to_task(TASK_RRC_NRUE, instance, msg); } +static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len) +{ + int offset = 0; + int nssai_cnt = 0; + while (offset < len) { + int length = *(buf + offset); + nr_nas_msg_snssai_t *nssai = nssaiList + nssai_cnt; + nssai->sd = 0xFFFFFF; + + switch (length) { + case 1: + nssai->sst = *(buf + offset + 1); + offset += 2; + nssai_cnt++; + break; + + case 2: + nssai->sst = *(buf + offset + 1); + nssai->hplmn_sst = *(buf + offset + 2); + offset += 3; + nssai_cnt++; + break; + + case 4: + nssai->sst = *(buf + offset + 1); + nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); + offset += 5; + nssai_cnt++; + break; + + case 5: + nssai->sst = *(buf + offset + 1); + nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); + nssai->hplmn_sst = *(buf + offset + 5); + offset += 6; + nssai_cnt++; + break; + + case 8: + nssai->sst = *(buf + offset + 1); + nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); + nssai->hplmn_sst = *(buf + offset + 5); + nssai->hplmn_sd = 0xFFFFFF & (*(buf + offset + 8) | (*(buf + offset + 7) << 8) | (*(buf + offset + 6) << 16)); + offset += 9; + nssai_cnt++; + break; + + default: + LOG_E(NAS, "UE received unknown length in an allowed S-NSSAI\n"); + break; + } + } +} + +/* Extract Allowed NSSAI from Regestration Accept according to + 3GPP TS 24.501 Table 8.2.7.1.1 +*/ +static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_buffer, const uint32_t pdu_length) +{ + if ((pdu_buffer == NULL) || (pdu_length <= 0)) + return; + + int offset = 1 + 1 + 1 + 2; // Mandatory fields offset + if (((nas_msg_header_t *)(pdu_buffer))->choice.security_protected_nas_msg_header_t.security_header_type > 0) { + offset += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; + } + + bool unknown_IEI_found = false; + + /* optional fields */ + int length = 0; + while ((offset < pdu_length) && !unknown_IEI_found) { + int type = *(pdu_buffer + offset); + switch (type) { + case 0x77: // 5GS mobile identity + length = (*(pdu_buffer + offset + 1) << 8) | *(pdu_buffer + offset + 2); + offset += (length + 1 + 2); // 1: type, 2: length + break; + + case 0x4A: // PLMN list + case 0x54: // 5GS tracking area identity + length = *((uint8_t *)(pdu_buffer + offset + 1)); + offset += (length + 1 + 1); // 1: type, 2: length + break; + + case 0x15: // allowed NSSAI + length = *((uint8_t *)(pdu_buffer + offset + 1)); + parse_allowed_nssai(nssai, pdu_buffer + offset + 2, length); + offset += (length + 1 + 1); // 1: type, 2: length + break; + + default: + LOG_E(NAS, "This NAS IEI is not handled when extracting list of allowed NSSAI\n"); + unknown_IEI_found = true; + break; + } + } +} + +static void request_default_pdusession(int instance) +{ + MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ); + NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */ + NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; + /* take the first allowed S-NSSAI for default PDU session */ + NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[0].sst; + NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[0].sd; + itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p); +} + void *nas_nrue_task(void *args_p) { nr_ue_nas.uicc = checkUicc(0); @@ -975,6 +1087,18 @@ void *nas_nrue(void *args_p) /* TODO not processed by NAS currently */ break; + case NAS_PDU_SESSION_REQ: { + as_nas_info_t pduEstablishMsg = {0}; + nas_pdu_session_req_t *pduReq = &NAS_PDU_SESSION_REQ(msg_p); + nr_ue_nas_t *nas = get_ue_nas_info(0); + generatePduSessionEstablishRequest(nas, &pduEstablishMsg, pduReq); + if (pduEstablishMsg.length > 0) { + send_nas_uplink_data_req(instance, &pduEstablishMsg); + LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); + } + break; + } + case NAS_CONN_ESTABLI_CNF: { LOG_I(NAS, "[UE %ld] Received %s: errCode %u, length %u\n", @@ -990,6 +1114,7 @@ void *nas_nrue(void *args_p) LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); nr_ue_nas_t *nas = get_ue_nas_info(0); decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); + get_allowed_nssai(nas_allowed_nssai, pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); as_nas_info_t initialNasMsg = {0}; generateRegistrationComplete(nas, &initialNasMsg, NULL); @@ -998,12 +1123,7 @@ void *nas_nrue(void *args_p) LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - as_nas_info_t pduEstablishMsg = {0}; - generatePduSessionEstablishRequest(nas, &pduEstablishMsg); - if (pduEstablishMsg.length > 0) { - send_nas_uplink_data_req(instance, &pduEstablishMsg); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); - } + request_default_pdusession(instance); } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); } @@ -1081,13 +1201,7 @@ void *nas_nrue(void *args_p) send_nas_uplink_data_req(instance, &initialNasMsg); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - - as_nas_info_t pduEstablishMsg = {0}; - generatePduSessionEstablishRequest(nas, &pduEstablishMsg); - if (pduEstablishMsg.length > 0) { - send_nas_uplink_data_req(instance, &pduEstablishMsg); - LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); - } + request_default_pdusession(instance); break; case FGS_DEREGISTRATION_ACCEPT: LOG_I(NAS, "received deregistration accept\n"); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index fa4911c738..6ca20a00cd 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -171,6 +171,13 @@ typedef struct { fgs_sm_nas_msg_header_t sm_nas_msg_header; } dl_nas_transport_t; +typedef struct { + int sst; + int hplmn_sst; + int sd; + int hplmn_sd; +} nr_nas_msg_snssai_t; + nr_ue_nas_t *get_ue_nas_info(module_id_t module_id); void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas); void *nas_nrue_task(void *args_p); From 19551d12543c7a7f4d999026ece4eeeb3a736d79 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Nov 2023 18:53:16 -0400 Subject: [PATCH 02/12] Remove extern declaration from .c --- executables/nr-uesoftmodem.c | 1 - openair3/NAS/NR_UE/nr_nas_msg_sim.c | 2 +- openair3/NAS/NR_UE/nr_nas_msg_sim.h | 17 ++++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index b734d9569b..c970b1d09d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -100,7 +100,6 @@ pthread_cond_t sync_cond; pthread_mutex_t sync_mutex; int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; -nr_nas_msg_snssai_t nas_allowed_nssai[8]; // not used in UE instance_t CUuniqInstance=0; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 2fc5209f6f..23050fd29b 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -59,7 +59,7 @@ extern char *baseNetAddress; extern uint16_t NB_UE_INST; static nr_ue_nas_t nr_ue_nas = {0}; static nr_ue_nas_t nr_ue_nas; -extern nr_nas_msg_snssai_t nas_allowed_nssai[8]; +nr_nas_msg_snssai_t nas_allowed_nssai[8]; static int nas_protected_security_header_encode( char *buffer, diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 6ca20a00cd..83222b7fd5 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -73,6 +73,16 @@ #define PAYLOAD_CONTAINER_LENGTH_MIN 3 #define PAYLOAD_CONTAINER_LENGTH_MAX 65537 +/* List of allowed NSSAI from NAS messaging. */ +typedef struct { + int sst; + int hplmn_sst; + int sd; + int hplmn_sd; +} nr_nas_msg_snssai_t; + +extern nr_nas_msg_snssai_t nas_allowed_nssai[8]; + /* Security Key for SA UE */ typedef struct { uint8_t kausf[32]; @@ -171,13 +181,6 @@ typedef struct { fgs_sm_nas_msg_header_t sm_nas_msg_header; } dl_nas_transport_t; -typedef struct { - int sst; - int hplmn_sst; - int sd; - int hplmn_sd; -} nr_nas_msg_snssai_t; - nr_ue_nas_t *get_ue_nas_info(module_id_t module_id); void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas); void *nas_nrue_task(void *args_p); From dc95e838eb08aa4564cf34442dbada3daacbe598 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Nov 2023 19:38:43 -0400 Subject: [PATCH 03/12] Improve NSSAI parsing use review suggestions from Laurent --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 76 +++++++++++++++-------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 23050fd29b..b896996c36 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -916,48 +916,47 @@ static void send_nas_uplink_data_req(instance_t instance, const as_nas_info_t *i static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t *buf, const uint32_t len) { - int offset = 0; int nssai_cnt = 0; - while (offset < len) { - int length = *(buf + offset); + const uint8_t *end = buf + len; + while (buf < end) { + const int length = *buf++; nr_nas_msg_snssai_t *nssai = nssaiList + nssai_cnt; - nssai->sd = 0xFFFFFF; + nssai->sd = 0xffffff; switch (length) { case 1: - nssai->sst = *(buf + offset + 1); - offset += 2; + nssai->sst = *buf++; nssai_cnt++; break; case 2: - nssai->sst = *(buf + offset + 1); - nssai->hplmn_sst = *(buf + offset + 2); - offset += 3; + nssai->sst = *buf++; + nssai->hplmn_sst = *buf++; nssai_cnt++; break; case 4: - nssai->sst = *(buf + offset + 1); - nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); - offset += 5; + nssai->sst = *buf++; + nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + buf += 3; nssai_cnt++; break; case 5: - nssai->sst = *(buf + offset + 1); - nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); - nssai->hplmn_sst = *(buf + offset + 5); - offset += 6; + nssai->sst = *buf++; + nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + buf += 3; + nssai->hplmn_sst = *buf++; nssai_cnt++; break; case 8: - nssai->sst = *(buf + offset + 1); - nssai->sd = 0xFFFFFF & (*(buf + offset + 4) | (*(buf + offset + 3) << 8) | (*(buf + offset + 2) << 16)); - nssai->hplmn_sst = *(buf + offset + 5); - nssai->hplmn_sd = 0xFFFFFF & (*(buf + offset + 8) | (*(buf + offset + 7) << 8) | (*(buf + offset + 6) << 16)); - offset += 9; + nssai->sst = *buf++; + nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + buf += 3; + nssai->hplmn_sst = *buf++; + nssai->hplmn_sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + buf += 3; nssai_cnt++; break; @@ -968,6 +967,14 @@ static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t } } +static inline uint16_t ntohs_unaligned(const uint8_t *v) +{ + // sanitize may complain on unaligned access, even if it works on Intel/AMD + uint16_t tmp; + memcpy(&tmp, v, sizeof(tmp)); + return ntohs(tmp); +} + /* Extract Allowed NSSAI from Regestration Accept according to 3GPP TS 24.501 Table 8.2.7.1.1 */ @@ -976,38 +983,33 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b if ((pdu_buffer == NULL) || (pdu_length <= 0)) return; - int offset = 1 + 1 + 1 + 2; // Mandatory fields offset + const uint8_t *end = pdu_buffer + pdu_length; + pdu_buffer += 1 + 1 + 1 + 2; // Mandatory fields offset if (((nas_msg_header_t *)(pdu_buffer))->choice.security_protected_nas_msg_header_t.security_header_type > 0) { - offset += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; + pdu_buffer += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; } - bool unknown_IEI_found = false; - /* optional fields */ - int length = 0; - while ((offset < pdu_length) && !unknown_IEI_found) { - int type = *(pdu_buffer + offset); + while (pdu_buffer < end) { + const int type = *pdu_buffer++; switch (type) { case 0x77: // 5GS mobile identity - length = (*(pdu_buffer + offset + 1) << 8) | *(pdu_buffer + offset + 2); - offset += (length + 1 + 2); // 1: type, 2: length + pdu_buffer += ntohs_unaligned(pdu_buffer) + sizeof(uint16_t); break; case 0x4A: // PLMN list case 0x54: // 5GS tracking area identity - length = *((uint8_t *)(pdu_buffer + offset + 1)); - offset += (length + 1 + 1); // 1: type, 2: length + pdu_buffer += *pdu_buffer + 1; // offset length + 1 byte which contains the length break; case 0x15: // allowed NSSAI - length = *((uint8_t *)(pdu_buffer + offset + 1)); - parse_allowed_nssai(nssai, pdu_buffer + offset + 2, length); - offset += (length + 1 + 1); // 1: type, 2: length + const int length = *pdu_buffer++; + parse_allowed_nssai(nssai, pdu_buffer, length); break; default: - LOG_E(NAS, "This NAS IEI is not handled when extracting list of allowed NSSAI\n"); - unknown_IEI_found = true; + LOG_W(NAS, "This NAS IEI is not handled when extracting list of allowed NSSAI\n"); + pdu_buffer = end; break; } } From 21b269fa99e16304f4cd441e41c8a9f0664dd609 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Nov 2023 20:35:12 -0400 Subject: [PATCH 04/12] Create macro to do ntoh for 3 bytes use it in NSSAI parsing function --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 9 +++++---- openair3/UTILS/conversions.h | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index b896996c36..48b814eb27 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -52,6 +52,7 @@ #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" #include "openair3/SECU/nas_stream_eia2.h" +#include "openair3/UTILS/conversions.h" uint8_t *registration_request_buf; uint32_t registration_request_len; @@ -937,14 +938,14 @@ static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t case 4: nssai->sst = *buf++; - nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + nssai->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai_cnt++; break; case 5: nssai->sst = *buf++; - nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + nssai->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai->hplmn_sst = *buf++; nssai_cnt++; @@ -952,10 +953,10 @@ static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t case 8: nssai->sst = *buf++; - nssai->sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + nssai->sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai->hplmn_sst = *buf++; - nssai->hplmn_sd = 0xffffff & (buf[2] | buf[1] << 8 | buf[0] << 16); + nssai->hplmn_sd = 0xffffff & ntoh_int24_buf(buf); buf += 3; nssai_cnt++; break; diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index bf24c9f4ee..e188909713 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -41,6 +41,9 @@ # define hton_int16(x) (x) #endif +#define ntoh_int24_buf(bUF) \ + ((*bUF << 16) | ((*(bUF + 1)) << 8) | (*(bUF + 2))) + #define IN_ADDR_TO_BUFFER(X,bUFF) INT32_TO_BUFFER((X).s_addr,(char*)bUFF) #define IN6_ADDR_TO_BUFFER(X,bUFF) \ From 128bd3d3db11a18b89f6c199467035ddb94398dc Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Nov 2023 20:50:37 -0400 Subject: [PATCH 05/12] Create macro to ntoh_int16 buffer input --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 10 +--------- openair3/UTILS/conversions.h | 3 +++ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 48b814eb27..d9f5fb7d18 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -968,14 +968,6 @@ static void parse_allowed_nssai(nr_nas_msg_snssai_t nssaiList[8], const uint8_t } } -static inline uint16_t ntohs_unaligned(const uint8_t *v) -{ - // sanitize may complain on unaligned access, even if it works on Intel/AMD - uint16_t tmp; - memcpy(&tmp, v, sizeof(tmp)); - return ntohs(tmp); -} - /* Extract Allowed NSSAI from Regestration Accept according to 3GPP TS 24.501 Table 8.2.7.1.1 */ @@ -995,7 +987,7 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b const int type = *pdu_buffer++; switch (type) { case 0x77: // 5GS mobile identity - pdu_buffer += ntohs_unaligned(pdu_buffer) + sizeof(uint16_t); + pdu_buffer += ntoh_int16_buf(pdu_buffer) + sizeof(uint16_t); break; case 0x4A: // PLMN list diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index e188909713..dc275071c5 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -44,6 +44,9 @@ #define ntoh_int24_buf(bUF) \ ((*bUF << 16) | ((*(bUF + 1)) << 8) | (*(bUF + 2))) +#define ntoh_int16_buf(bUF) \ + ((*(bUF) << 8) | (*(bUF + 1))) + #define IN_ADDR_TO_BUFFER(X,bUFF) INT32_TO_BUFFER((X).s_addr,(char*)bUFF) #define IN6_ADDR_TO_BUFFER(X,bUFF) \ From 8f79b4aeed62851eb15b3d063a69554e3939551e Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 1 Nov 2023 20:57:11 -0400 Subject: [PATCH 06/12] Remove redundant typedef --- openair2/COMMON/rrc_messages_def.h | 2 +- openair2/COMMON/rrc_messages_types.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 80e191db9f..be21688a0e 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -82,4 +82,4 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr // eNB: RLC -> RRC messages MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) -MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, NasPduSessionReq, nas_pdu_session_req) +MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index c7fc58b6cb..2810dcfdd6 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -441,7 +441,6 @@ typedef nas_release_ind_t NasConnReleaseInd; typedef ul_info_transfer_cnf_t NasUlDataCnf; typedef dl_info_transfer_ind_t NasDlDataInd; -typedef nas_pdu_session_req_t NasPduSessionReq; // eNB: realtime -> RRC messages typedef struct rrc_subframe_process_s { protocol_ctxt_t ctxt; From 3ae665388a432b9718dde49cdd913b5edb3d35ea Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 2 Nov 2023 10:28:51 -0400 Subject: [PATCH 07/12] Declare variable outside of case: label --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index d9f5fb7d18..0c97177a9c 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -985,6 +985,7 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b /* optional fields */ while (pdu_buffer < end) { const int type = *pdu_buffer++; + int length = 0; switch (type) { case 0x77: // 5GS mobile identity pdu_buffer += ntoh_int16_buf(pdu_buffer) + sizeof(uint16_t); @@ -996,7 +997,7 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b break; case 0x15: // allowed NSSAI - const int length = *pdu_buffer++; + length = *pdu_buffer++; parse_allowed_nssai(nssai, pdu_buffer, length); break; From 8b118fd875246e05cd1b63a8dc1baa1fd661bbc8 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Mon, 6 Nov 2023 11:34:49 -0500 Subject: [PATCH 08/12] Remove hardcoding of default NSSAI selection Check if NSSAI from config exists in allowed NSSAI list. Don't request PDU session if not present in the list. --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 33 +++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 0c97177a9c..82a0e6bd1d 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -977,11 +977,11 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b return; const uint8_t *end = pdu_buffer + pdu_length; - pdu_buffer += 1 + 1 + 1 + 2; // Mandatory fields offset if (((nas_msg_header_t *)(pdu_buffer))->choice.security_protected_nas_msg_header_t.security_header_type > 0) { pdu_buffer += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; } + pdu_buffer += 1 + 1 + 1 + 2; // Mandatory fields offset /* optional fields */ while (pdu_buffer < end) { const int type = *pdu_buffer++; @@ -1009,17 +1009,26 @@ static void get_allowed_nssai(nr_nas_msg_snssai_t nssai[8], const uint8_t *pdu_b } } -static void request_default_pdusession(int instance) +static void request_default_pdusession(int instance, int nssai_idx) { MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ); NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */ NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; - /* take the first allowed S-NSSAI for default PDU session */ - NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[0].sst; - NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[0].sd; + NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[nssai_idx].sst; + NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[nssai_idx].sd; itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p); } +static int get_user_nssai_idx(const nr_nas_msg_snssai_t allowed_nssai[8], const nr_ue_nas_t *nas) +{ + for (int i = 0; i < 8; i++) { + const nr_nas_msg_snssai_t *nssai = allowed_nssai + i; + if ((nas->uicc->nssai_sst == nssai->sst) && (nas->uicc->nssai_sd == nssai->sd)) + return i; + } + return -1; +} + void *nas_nrue_task(void *args_p) { nr_ue_nas.uicc = checkUicc(0); @@ -1119,7 +1128,12 @@ void *nas_nrue(void *args_p) LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - request_default_pdusession(instance); + const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas); + if (nssai_idx < 0) { + LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n"); + } else { + request_default_pdusession(instance, nssai_idx); + } } else if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length); } @@ -1197,7 +1211,12 @@ void *nas_nrue(void *args_p) send_nas_uplink_data_req(instance, &initialNasMsg); LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } - request_default_pdusession(instance); + const int nssai_idx = get_user_nssai_idx(nas_allowed_nssai, nas); + if (nssai_idx < 0) { + LOG_E(NAS, "NSSAI parameters not match with allowed NSSAI. Couldn't request PDU session.\n"); + } else { + request_default_pdusession(instance, nssai_idx); + } break; case FGS_DEREGISTRATION_ACCEPT: LOG_I(NAS, "received deregistration accept\n"); From 3979879e9e06e9421e256fcf5326f7340c24587d Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 10 Nov 2023 08:59:06 -0500 Subject: [PATCH 09/12] Replace buffer conversion with macro --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 82a0e6bd1d..59bab0e0e5 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -841,11 +841,8 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * // this kind of error seems in many places in 5G NAS mm_msg->uplink_nas_transport.snssai.value = calloc(1, nssai_len); mm_msg->uplink_nas_transport.snssai.value[0] = pdu_req->sst; - if (has_nssai_sd) { - mm_msg->uplink_nas_transport.snssai.value[1] = (pdu_req->sd >> 16) & 0xFF; - mm_msg->uplink_nas_transport.snssai.value[2] = (pdu_req->sd >> 8) & 0xFF; - mm_msg->uplink_nas_transport.snssai.value[3] = (pdu_req->sd) & 0xFF; - } + if (has_nssai_sd) + INT24_TO_BUFFER(pdu_req->sd, &mm_msg->uplink_nas_transport.snssai.value[1]); size += 1 + 1 + nssai_len; int dnnSize=strlen(nas->uicc->dnnStr); mm_msg->uplink_nas_transport.dnn.value=calloc(1,dnnSize+1); From 6bf954d35dd2138567e3faebdbd7da799558fad5 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 10 Nov 2023 09:00:38 -0500 Subject: [PATCH 10/12] Cast buffer intputs of order reversing macros --- openair3/UTILS/conversions.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index dc275071c5..f12b22a67b 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -34,18 +34,18 @@ (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8) # define ntoh_int32_buf(bUF) \ - ((*(bUF)) << 24) | ((*((bUF) + 1)) << 16) | ((*((bUF) + 2)) << 8) \ - | (*((bUF) + 3)) + ((*((uint8_t*)bUF)) << 24) | ((*((uint8_t*)bUF + 1)) << 16) | ((*((uint8_t*)bUF + 2)) << 8) \ + | (*((uint8_t*)bUF + 3)) #else # define hton_int32(x) (x) # define hton_int16(x) (x) #endif #define ntoh_int24_buf(bUF) \ - ((*bUF << 16) | ((*(bUF + 1)) << 8) | (*(bUF + 2))) + ((*(uint8_t*)bUF << 16) | ((*((uint8_t*)bUF + 1)) << 8) | (*((uint8_t*)bUF + 2))) #define ntoh_int16_buf(bUF) \ - ((*(bUF) << 8) | (*(bUF + 1))) + ((*((uint8_t*)bUF) << 8) | (*((uint8_t*)bUF + 1))) #define IN_ADDR_TO_BUFFER(X,bUFF) INT32_TO_BUFFER((X).s_addr,(char*)bUFF) From f69f419a13567f2165497eb585210ef6226895ee Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Fri, 10 Nov 2023 09:06:17 -0500 Subject: [PATCH 11/12] Remove duplicate declaration --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 59bab0e0e5..08899a0539 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -59,7 +59,6 @@ uint32_t registration_request_len; extern char *baseNetAddress; extern uint16_t NB_UE_INST; static nr_ue_nas_t nr_ue_nas = {0}; -static nr_ue_nas_t nr_ue_nas; nr_nas_msg_snssai_t nas_allowed_nssai[8]; static int nas_protected_security_header_encode( From d61c4f1042c2794ebc2dc5fc37cf83e1c506826b Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Thu, 16 Nov 2023 13:05:21 -0500 Subject: [PATCH 12/12] Change global variable to local --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 2 +- openair3/NAS/NR_UE/nr_nas_msg_sim.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 08899a0539..f83f1138b6 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -59,7 +59,7 @@ uint32_t registration_request_len; extern char *baseNetAddress; extern uint16_t NB_UE_INST; static nr_ue_nas_t nr_ue_nas = {0}; -nr_nas_msg_snssai_t nas_allowed_nssai[8]; +static nr_nas_msg_snssai_t nas_allowed_nssai[8]; static int nas_protected_security_header_encode( char *buffer, diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 83222b7fd5..b1a1d25d1e 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -81,8 +81,6 @@ typedef struct { int hplmn_sd; } nr_nas_msg_snssai_t; -extern nr_nas_msg_snssai_t nas_allowed_nssai[8]; - /* Security Key for SA UE */ typedef struct { uint8_t kausf[32];