From 8a7321db110386ec2e97a24d4a269ed1b40ea0ec Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 29 Oct 2024 11:28:02 +0100 Subject: [PATCH 1/9] Rename FGS Service Request/Reject/Accept type for consistency with FGS naming style --- openair3/NAS/COMMON/NR_NAS_defs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index f49852f62c..5549e5e1e2 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -72,9 +72,9 @@ typedef enum { TYPE_DEF(FGS_DEREGISTRATION_ACCEPT_UE_ORIGINATING, 0x46) \ TYPE_DEF(DeregistrationrequestUEterminated, 0x47) \ TYPE_DEF(DeregistrationacceptUEterminated, 0x48) \ - TYPE_DEF(Servicerequest, 0x4c) \ - TYPE_DEF(Servicereject, 0x4d) \ - TYPE_DEF(Serviceaccept, 0x4e) \ + TYPE_DEF(FGS_SERVICE_REQUEST, 0x4c) \ + TYPE_DEF(FGS_SERVICE_REJECT, 0x4d) \ + TYPE_DEF(FGS_SERVICE_ACCEPT, 0x4e) \ TYPE_DEF(Controlplaneservicerequest, 0x4f) \ TYPE_DEF(Networkslicespecificauthenticationcommand, 0x50) \ TYPE_DEF(Networkslicespecificauthenticationcomplete, 0x51) \ From 5c3953b6845303bb7cee44e54fea414686918f2c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 8 Nov 2024 17:02:53 +0100 Subject: [PATCH 2/9] Cleanup test5Gnas.c and MAC references in NR_NAS_defs.h (undefined functions prototypes) --- CMakeLists.txt | 6 ------ openair3/NAS/COMMON/NR_NAS_defs.h | 13 ------------ openair3/NAS/COMMON/nr_common.c | 1 + openair3/TEST/test5Gnas.c | 35 ------------------------------- 4 files changed, 1 insertion(+), 54 deletions(-) delete mode 100644 openair3/TEST/test5Gnas.c diff --git a/CMakeLists.txt b/CMakeLists.txt index edd9c18657..ef1045726c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1897,12 +1897,6 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) -add_executable(test5Gnas - ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c -) -target_link_libraries (test5Gnas LIB_5GNAS_GNB minimal_lib ) - - # lte-softmodem is both eNB and UE implementation ################################################### diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index 5549e5e1e2..1ced950a4d 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -25,7 +25,6 @@ #include #include -#include /* TS 24.007 possible L3 formats: TableĀ 11.1: Formats of information elements @@ -381,18 +380,6 @@ int resToresStar(uint8_t *msg, const uicc_t* uicc); int identityResponse(void **msg, nr_user_nas_t *UE); int authenticationResponse(void **msg, nr_user_nas_t *UE); -void UEprocessNAS(void *msg,nr_user_nas_t *UE); -void SGSabortUE(void *msg, NRUEcontext_t *UE) ; -void SGSregistrationReq(void *msg, NRUEcontext_t *UE); -void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE); -void SGSauthenticationResp(void *msg, NRUEcontext_t *UE); -void SGSidentityResp(void *msg, NRUEcontext_t *UE); -void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE); -void SGSregistrationComplete(void *msg, NRUEcontext_t *UE); -void processNAS(void *msg, NRUEcontext_t *UE); -int identityRequest(void **msg, NRUEcontext_t *UE); -int authenticationRequest(void **msg, NRUEcontext_t *UE); -int securityModeCommand(void **msg, NRUEcontext_t *UE); void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size); #endif diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c index 0a7aae2a17..6c935df4f1 100644 --- a/openair3/NAS/COMMON/nr_common.c +++ b/openair3/NAS/COMMON/nr_common.c @@ -21,6 +21,7 @@ * contact@openairinterface.org */ +#include #include #include #include diff --git a/openair3/TEST/test5Gnas.c b/openair3/TEST/test5Gnas.c deleted file mode 100644 index 86b4326f94..0000000000 --- a/openair3/TEST/test5Gnas.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include - -volatile int oai_exit; -configmodule_interface_t *uniqCfg = NULL; - -int main(int argc, char **argv) { - if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - - logInit(); - char *resp; - nr_user_nas_t UErrc= {0}; - NRUEcontext_t UEnas= {0}; - // Network generate identity request after a sucessfull radio attach - int size=identityRequest((void **)&resp, &UEnas); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Request:\n" ); - // UE process the message that it has received from phy layer in a "DL transfer" message - UEprocessNAS(resp, &UErrc); - // UE Scheduler should later call the response - size=identityResponse((void **)&resp, &UErrc); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Response:\n" ); - // Now the gNB process the identity response - processNAS(resp, &UEnas); - // gNB scheduler should call the next query - size=authenticationRequest((void **)&resp, &UEnas); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication request:\n" ); - // as above - UEprocessNAS(resp, &UErrc); - size=authenticationResponse((void **)&resp, &UErrc); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication response:\n" ); - processNAS(resp, &UEnas); - return 0; -} From bf7761131d4f138930302b745adfb10670d05248 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 8 Nov 2024 15:54:51 +0100 Subject: [PATCH 3/9] Refactor NAS Key Set Identifier enc/dec functions * simplified the code while keeping same functionality * reduced the number of functions (from 4 to 2) * clang-formatted --- openair3/NAS/COMMON/EMM/MSG/AttachRequest.c | 5 +- .../COMMON/EMM/MSG/AuthenticationRequest.c | 5 +- openair3/NAS/COMMON/EMM/MSG/DetachRequest.c | 5 +- .../COMMON/EMM/MSG/ExtendedServiceRequest.c | 7 +- .../FGSDeregistrationRequestUEOriginating.c | 3 +- .../NAS/COMMON/EMM/MSG/RegistrationRequest.c | 7 +- .../NAS/COMMON/EMM/MSG/SecurityModeCommand.c | 5 +- .../EMM/MSG/TrackingAreaUpdateRequest.c | 23 +++--- openair3/NAS/COMMON/IES/NasKeySetIdentifier.c | 75 ++++++------------- openair3/NAS/COMMON/IES/NasKeySetIdentifier.h | 8 +- openair3/NAS/COMMON/NR_NAS_defs.h | 1 + 11 files changed, 60 insertions(+), 84 deletions(-) diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachRequest.c b/openair3/NAS/COMMON/EMM/MSG/AttachRequest.c index 7448a33419..8edac423c3 100644 --- a/openair3/NAS/COMMON/EMM/MSG/AttachRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/AttachRequest.c @@ -47,7 +47,7 @@ int decode_attach_request(attach_request_msg *attach_request, uint8_t *buffer, u LOG_FUNC_RETURN(decoded_result); } - if ((decoded_result = decode_u8_nas_key_set_identifier(&attach_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) { + if ((decoded_result = decode_nas_key_set_identifier(&attach_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4)) < 0) { // return decoded_result; LOG_FUNC_RETURN(decoded_result); } @@ -299,7 +299,8 @@ int encode_attach_request(attach_request_msg *attach_request, uint8_t *buffer, u /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, ATTACH_REQUEST_MINIMUM_LENGTH, len); - *(buffer + encoded) = ((encode_u8_nas_key_set_identifier(&attach_request->naskeysetidentifier) & 0x0f) << 4) | (encode_u8_eps_attach_type(&attach_request->epsattachtype) & 0x0f); + *(buffer + encoded) = ((encode_nas_key_set_identifier(&attach_request->naskeysetidentifier, 0) & 0x0f) << 4) + | (encode_u8_eps_attach_type(&attach_request->epsattachtype) & 0x0f); encoded++; if ((encode_result = diff --git a/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c b/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c index 0914353478..71477f3aeb 100644 --- a/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/AuthenticationRequest.c @@ -38,7 +38,8 @@ int decode_authentication_request(authentication_request_msg *authentication_req CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, AUTHENTICATION_REQUEST_MINIMUM_LENGTH, len); /* Decoding mandatory fields */ - if ((decoded_result = decode_u8_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme, 0, *(buffer + decoded), len - decoded)) < 0) + if ((decoded_result = decode_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme, 0, *(buffer + decoded))) + < 0) return decoded_result; decoded++; @@ -64,7 +65,7 @@ int encode_authentication_request(authentication_request_msg *authentication_req /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, AUTHENTICATION_REQUEST_MINIMUM_LENGTH, len); - *(buffer + encoded) = ((encode_u8_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme) & 0x0f) << 4) | 0x00; + *(buffer + encoded) = ((encode_nas_key_set_identifier(&authentication_request->naskeysetidentifierasme, 0) & 0x0f) << 4) | 0x00; encoded++; if ((encode_result = diff --git a/openair3/NAS/COMMON/EMM/MSG/DetachRequest.c b/openair3/NAS/COMMON/EMM/MSG/DetachRequest.c index 1697ea17e2..8a63ea71c8 100644 --- a/openair3/NAS/COMMON/EMM/MSG/DetachRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/DetachRequest.c @@ -41,7 +41,7 @@ int decode_detach_request(detach_request_msg *detach_request, uint8_t *buffer, u if ((decoded_result = decode_u8_detach_type(&detach_request->detachtype, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) return decoded_result; - if ((decoded_result = decode_u8_nas_key_set_identifier(&detach_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) + if ((decoded_result = decode_nas_key_set_identifier(&detach_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4)) < 0) return decoded_result; decoded++; @@ -62,7 +62,8 @@ int encode_detach_request(detach_request_msg *detach_request, uint8_t *buffer, u /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, DETACH_REQUEST_MINIMUM_LENGTH, len); - *(buffer + encoded) = ((encode_u8_nas_key_set_identifier(&detach_request->naskeysetidentifier) << 4) | (encode_u8_detach_type(&detach_request->detachtype) & 0x0f)); + *(buffer + encoded) = ((encode_nas_key_set_identifier(&detach_request->naskeysetidentifier, 0) << 4) + | (encode_u8_detach_type(&detach_request->detachtype) & 0x0f)); encoded++; if ((encode_result = encode_eps_mobile_identity(&detach_request->gutiorimsi, diff --git a/openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.c b/openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.c index a7ff89245b..99a556c7f3 100644 --- a/openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/ExtendedServiceRequest.c @@ -41,7 +41,9 @@ int decode_extended_service_request(extended_service_request_msg *extended_servi if ((decoded_result = decode_u8_service_type(&extended_service_request->servicetype, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) return decoded_result; - if ((decoded_result = decode_u8_nas_key_set_identifier(&extended_service_request->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) + if ((decoded_result = + decode_nas_key_set_identifier(&extended_service_request->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f)) + < 0) return decoded_result; decoded++; @@ -62,7 +64,8 @@ int encode_extended_service_request(extended_service_request_msg *extended_servi /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, EXTENDED_SERVICE_REQUEST_MINIMUM_LENGTH, len); - *(buffer + encoded) = ((encode_u8_service_type(&extended_service_request->servicetype) & 0x0f) << 4) | (encode_u8_nas_key_set_identifier(&extended_service_request->naskeysetidentifier) & 0x0f); + *(buffer + encoded) = ((encode_u8_service_type(&extended_service_request->servicetype) & 0x0f) << 4) + | (encode_nas_key_set_identifier(&extended_service_request->naskeysetidentifier, 0) & 0x0f); encoded++; if ((encode_result = diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c b/openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c index 0d9a4bbac2..af8dfd8c20 100644 --- a/openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c +++ b/openair3/NAS/COMMON/EMM/MSG/FGSDeregistrationRequestUEOriginating.c @@ -33,6 +33,7 @@ #include #include "FGSDeregistrationRequestUEOriginating.h" +#include "NR_NAS_defs.h" int encode_fgs_deregistration_request_ue_originating(fgs_deregistration_request_ue_originating_msg *drr, uint8_t *buffer, @@ -45,7 +46,7 @@ int encode_fgs_deregistration_request_ue_originating(fgs_deregistration_request_ | ((dt->access_type & 0x3) << 4); int encode_result; - if ((encode_result = encode_nas_key_set_identifier(&drr->naskeysetidentifier, 0, buffer + encoded, len - encoded)) < 0) + if ((encode_result = encode_nas_key_set_identifier(&drr->naskeysetidentifier, IEI_NULL)) < 0) return encode_result; encoded++; diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c index 3d177c396a..cf18e46ca2 100644 --- a/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationRequest.c @@ -35,6 +35,7 @@ #include "nas_log.h" #include "RegistrationRequest.h" +#include "NR_NAS_defs.h" int decode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len) { @@ -51,7 +52,8 @@ int decode_registration_request(registration_request_msg *registration_request, LOG_FUNC_RETURN(decoded_result); } - if ((decoded_result = decode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) { + if ((decoded_result = decode_nas_key_set_identifier(®istration_request->naskeysetidentifier, IEI_NULL, *(buffer + decoded) >> 4)) + < 0) { // return decoded_result; LOG_FUNC_RETURN(decoded_result); } @@ -75,7 +77,8 @@ int encode_registration_request(registration_request_msg *registration_request, int encoded = 0; int encode_result = 0; - *(buffer + encoded) = ((encode_u8_nas_key_set_identifier(®istration_request->naskeysetidentifier) & 0x0f) << 4) | (encode_5gs_registration_type(®istration_request->fgsregistrationtype) & 0x0f); + *(buffer + encoded) = ((encode_nas_key_set_identifier(®istration_request->naskeysetidentifier, IEI_NULL) & 0x0f) << 4) + | (encode_5gs_registration_type(®istration_request->fgsregistrationtype) & 0x0f); encoded++; if ((encode_result = diff --git a/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c b/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c index 25181d8e79..2e936e6a94 100644 --- a/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c +++ b/openair3/NAS/COMMON/EMM/MSG/SecurityModeCommand.c @@ -43,7 +43,8 @@ int decode_security_mode_command(security_mode_command_msg *security_mode_comman else decoded += decoded_result; - if ((decoded_result = decode_u8_nas_key_set_identifier(&security_mode_command->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) + if ((decoded_result = decode_nas_key_set_identifier(&security_mode_command->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f)) + < 0) return decoded_result; decoded++; @@ -124,7 +125,7 @@ int encode_security_mode_command(security_mode_command_msg *security_mode_comman else encoded += encode_result; - *(buffer + encoded) = (encode_u8_nas_key_set_identifier(&security_mode_command->naskeysetidentifier) & 0x0f); + *(buffer + encoded) = (encode_nas_key_set_identifier(&security_mode_command->naskeysetidentifier, 0) & 0x0f); encoded++; if ((encode_result = diff --git a/openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.c b/openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.c index 49632057c0..83968bc2c6 100644 --- a/openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.c +++ b/openair3/NAS/COMMON/EMM/MSG/TrackingAreaUpdateRequest.c @@ -41,7 +41,9 @@ int decode_tracking_area_update_request(tracking_area_update_request_msg *tracki if ((decoded_result = decode_u8_eps_update_type(&tracking_area_update_request->epsupdatetype, 0, *(buffer + decoded) >> 4, len - decoded)) < 0) return decoded_result; - if ((decoded_result = decode_u8_nas_key_set_identifier(&tracking_area_update_request->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f, len - decoded)) < 0) + if ((decoded_result = + decode_nas_key_set_identifier(&tracking_area_update_request->naskeysetidentifier, 0, *(buffer + decoded) & 0x0f)) + < 0) return decoded_result; decoded++; @@ -61,10 +63,10 @@ int decode_tracking_area_update_request(tracking_area_update_request_msg *tracki switch(ieiDecoded) { case TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_IEI: - if ((decoded_result = - decode_nas_key_set_identifier(&tracking_area_update_request->noncurrentnativenaskeysetidentifier, - TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_IEI, - buffer + decoded, len - decoded)) <= 0) + if ((decoded_result = decode_nas_key_set_identifier(&tracking_area_update_request->noncurrentnativenaskeysetidentifier, + TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_IEI, + *(buffer + decoded))) + <= 0) return decoded_result; decoded += decoded_result; @@ -293,8 +295,8 @@ int encode_tracking_area_update_request(tracking_area_update_request_msg *tracki /* Checking IEI and pointer */ CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, TRACKING_AREA_UPDATE_REQUEST_MINIMUM_LENGTH, len); - *(buffer + encoded) = ((encode_u8_eps_update_type(&tracking_area_update_request->epsupdatetype) & 0x0f) << 4) | (encode_u8_nas_key_set_identifier( - &tracking_area_update_request->naskeysetidentifier) & 0x0f); + *(buffer + encoded) = ((encode_u8_eps_update_type(&tracking_area_update_request->epsupdatetype) & 0x0f) << 4) + | (encode_nas_key_set_identifier(&tracking_area_update_request->naskeysetidentifier, 0) & 0x0f); encoded++; if ((encode_result = @@ -306,10 +308,9 @@ int encode_tracking_area_update_request(tracking_area_update_request_msg *tracki if ((tracking_area_update_request->presencemask & TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_PRESENT) == TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_PRESENT) { - if ((encode_result = - encode_nas_key_set_identifier(&tracking_area_update_request->noncurrentnativenaskeysetidentifier, - TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_IEI, - buffer + encoded, len - encoded)) < 0) + if ((encode_result = encode_nas_key_set_identifier(&tracking_area_update_request->noncurrentnativenaskeysetidentifier, + TRACKING_AREA_UPDATE_REQUEST_NONCURRENT_NATIVE_NAS_KEY_SET_IDENTIFIER_IEI)) + < 0) // Return in case of error return encode_result; else diff --git a/openair3/NAS/COMMON/IES/NasKeySetIdentifier.c b/openair3/NAS/COMMON/IES/NasKeySetIdentifier.c index a547675675..82fe69d79e 100644 --- a/openair3/NAS/COMMON/IES/NasKeySetIdentifier.c +++ b/openair3/NAS/COMMON/IES/NasKeySetIdentifier.c @@ -28,67 +28,34 @@ #include "TLVDecoder.h" #include "NasKeySetIdentifier.h" -int decode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t *buffer, uint32_t len) +/** + * @brief Decode the NAS key set identifier from one byte + */ +int decode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t value) { - int decoded = 0; - CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, NAS_KEY_SET_IDENTIFIER_MINIMUM_LENGTH, len); - if (iei > 0) { - CHECK_IEI_DECODER((*buffer & 0xf0), iei); + CHECK_IEI_DECODER((value & 0xf0), iei); } - naskeysetidentifier->tsc = (*(buffer + decoded) >> 3) & 0x1; - naskeysetidentifier->naskeysetidentifier = *(buffer + decoded) & 0x7; - decoded++; + naskeysetidentifier->tsc = (value >> 3) & 0x1; + naskeysetidentifier->naskeysetidentifier = value & 0x7; + +#if defined(NAS_DEBUG) + dump_nas_key_set_identifier_xml(naskeysetidentifier, iei); +#endif + + return 1; // 1 octet +} + +/** + * @brief Encode the NAS key set identifier in one byte + */ +uint8_t encode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei) +{ #if defined (NAS_DEBUG) dump_nas_key_set_identifier_xml(naskeysetidentifier, iei); #endif - return decoded; -} - -int decode_u8_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t value, uint32_t len) -{ - int decoded = 0; - uint8_t *buffer = &value; - naskeysetidentifier->tsc = (*(buffer + decoded) >> 3) & 0x1; - naskeysetidentifier->naskeysetidentifier = *(buffer + decoded) & 0x7; - decoded++; -#if defined (NAS_DEBUG) - dump_nas_key_set_identifier_xml(naskeysetidentifier, iei); -#endif - return decoded; -} - -int encode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t *buffer, uint32_t len) -{ - uint8_t encoded = 0; - /* Checking length and pointer */ - CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, NAS_KEY_SET_IDENTIFIER_MINIMUM_LENGTH, len); -#if defined (NAS_DEBUG) - dump_nas_key_set_identifier_xml(naskeysetidentifier, iei); -#endif - *(buffer + encoded) = 0x00 | (iei & 0xf0) | - ((naskeysetidentifier->tsc & 0x1) << 3) | - (naskeysetidentifier->naskeysetidentifier & 0x7); - encoded++; - return encoded; -} - -uint8_t encode_u8_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier) -{ - uint8_t bufferReturn; - uint8_t *buffer = &bufferReturn; - uint8_t encoded = 0; - uint8_t iei = 0; -#if defined (NAS_DEBUG) - dump_nas_key_set_identifier_xml(naskeysetidentifier, 0); -#endif - *(buffer + encoded) = 0x00 | (iei & 0xf0) | - ((naskeysetidentifier->tsc & 0x1) << 3) | - (naskeysetidentifier->naskeysetidentifier & 0x7); - encoded++; - - return bufferReturn; + return ((iei & 0xf0) | (naskeysetidentifier->tsc & 0x1) << 3) | (naskeysetidentifier->naskeysetidentifier & 0x7); } void dump_nas_key_set_identifier_xml(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei) diff --git a/openair3/NAS/COMMON/IES/NasKeySetIdentifier.h b/openair3/NAS/COMMON/IES/NasKeySetIdentifier.h index 09daf13a56..5f6b445fc4 100644 --- a/openair3/NAS/COMMON/IES/NasKeySetIdentifier.h +++ b/openair3/NAS/COMMON/IES/NasKeySetIdentifier.h @@ -39,15 +39,11 @@ typedef struct NasKeySetIdentifier_tag { uint8_t naskeysetidentifier:3; } NasKeySetIdentifier; -int encode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t *buffer, uint32_t len); +uint8_t encode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei); void dump_nas_key_set_identifier_xml(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei); -uint8_t encode_u8_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier); - -int decode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t *buffer, uint32_t len); - -int decode_u8_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t value, uint32_t len); +int decode_nas_key_set_identifier(NasKeySetIdentifier *naskeysetidentifier, uint8_t iei, uint8_t value); #endif /* NAS KEY SET IDENTIFIER_H_ */ diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index 1ced950a4d..f5510e5392 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -256,6 +256,7 @@ typedef enum { } cause_secu_id_t; // IEI (information element identifier) are spread in each message definition +#define IEI_NULL 0x00 #define IEI_RAND 0x21 #define IEI_AUTN 0x20 #define IEI_EAP 0x78 From 29220a60dcf0334d1571f6473e63bebf131a419a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 11 Nov 2024 10:51:57 +0100 Subject: [PATCH 4/9] Add check on minimum length in encode_5gs_mobile_identity --- openair3/NAS/COMMON/IES/FGSMobileIdentity.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index c0b60f101f..bd98cc090a 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -37,6 +37,8 @@ #include "TLVDecoder.h" #include "FGSMobileIdentity.h" +#define MIN_LEN_FGS_MOBILE_ID_IE 3 // type of identity "No identity" + static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, const uint8_t *buffer); static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); @@ -77,6 +79,10 @@ int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) { + // Return if buffer is shorter than min length + if (len < MIN_LEN_FGS_MOBILE_ID_IE) + return -1; + int encoded_rc = TLV_ENCODE_VALUE_DOESNT_MATCH; uint32_t encoded = 0; @@ -86,6 +92,7 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei } encoded = encoded + 2; + len -= encoded; if (fgsmobileidentity->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI) { encoded_rc = encode_guti_5gs_mobile_identity(&fgsmobileidentity->guti, From c817c44ae9689951b1ecce24a09436371af27296 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 11 Nov 2024 10:55:28 +0100 Subject: [PATCH 5/9] Add include for stdbool.h in FGSMobileIdentity.c --- openair3/NAS/COMMON/IES/FGSMobileIdentity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index bd98cc090a..98f0b5017a 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include "TLVEncoder.h" #include "TLVDecoder.h" From 1c4e1029a88e1c229fa358f2b89d92ad55e67359 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 24 Sep 2024 14:33:58 +0200 Subject: [PATCH 6/9] Add NAS Service Request enc/dec functions * FGMM enc/dec library files * Plain message encoding + logic for security protected message * added fill_fgstmsi function * add checks on length in 5G-S-TMSI encoder function * encoding of NAS Service Request and relevant mandatory IEs --- CMakeLists.txt | 6 ++ .../NAS/COMMON/EMM/MSG/fgs_service_request.c | 90 ++++++++++++++++++ .../NAS/COMMON/EMM/MSG/fgs_service_request.h | 62 +++++++++++++ openair3/NAS/COMMON/IES/FGSMobileIdentity.c | 55 +++++++++++ openair3/NAS/COMMON/IES/FGSMobileIdentity.h | 5 + openair3/NAS/NR_UE/nr_nas_msg.c | 93 +++++++++++++++++++ openair3/NAS/NR_UE/nr_nas_msg.h | 6 ++ 7 files changed, 317 insertions(+) create mode 100644 openair3/NAS/COMMON/EMM/MSG/fgs_service_request.c create mode 100644 openair3/NAS/COMMON/EMM/MSG/fgs_service_request.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ef1045726c..05c3609052 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1561,6 +1561,10 @@ set(libnas_emm_msg_OBJS ${NAS_SRC}COMMON/EMM/MSG/UplinkNasTransport.c ) +set(libnas_fgs_msg_OBJS + ${NAS_SRC}COMMON/EMM/MSG/fgs_service_request.c +) + set(libnas_esm_msg_OBJS ${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.c ${NAS_SRC}COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.c @@ -1785,6 +1789,7 @@ add_library(LIB_NAS_SIMUE ${libnas_api_OBJS} ${libnas_ue_api_OBJS} ${libnas_emm_msg_OBJS} + ${libnas_fgs_msg_OBJS} ${libnas_esm_msg_OBJS} ${libnas_ies_OBJS} ${libnas_utils_OBJS} @@ -1831,6 +1836,7 @@ include_directories(${NAS_SRC}UE) include_directories(${NAS_SRC}UE/API/USER) include_directories(${NAS_SRC}UE/API/USIM) include_directories(${NAS_SRC}UE/EMM) +include_directories(${NAS_SRC}UE/EMM/MSG) include_directories(${NAS_SRC}UE/EMM/SAP) include_directories(${NAS_SRC}UE/ESM) include_directories(${NAS_SRC}UE/ESM/SAP) diff --git a/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.c b/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.c new file mode 100644 index 0000000000..85e67498a5 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.c @@ -0,0 +1,90 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "fgs_service_request.h" +#include "FGSMobileIdentity.h" +#include "NasKeySetIdentifier.h" +#include "ServiceType.h" +#include "NR_NAS_defs.h" + +#define LEN_FGS_MOBILE_ID_CONTENTS_SIZE 2 // octets +#define MIN_LEN_FGS_SERVICE_REQUEST 10 // octets + +/** + * @brief Encode 5GMM NAS Service Request message (8.2.16 of 3GPP TS 24.501) + */ +int encode_fgs_service_request(uint8_t *buffer, fgs_service_request_msg_t *service_request, uint32_t len) +{ + // Return if buffer is shorter than min length + if (len < MIN_LEN_FGS_SERVICE_REQUEST) + return -1; + + int encoded = 0; + + // ngKSI + Service type (1 octet) (M) + *buffer = ((encode_nas_key_set_identifier(&service_request->naskeysetidentifier, IEI_NULL) & 0x0f) << 4) + | (service_request->serviceType & 0x0f); + encoded++; + len -= encoded; + + // 5GS Mobile Identity (M) type 5G-S-TMSI (9 octets) + encoded += LEN_FGS_MOBILE_ID_CONTENTS_SIZE; // skip "Length of 5GS mobile identity contents" IE + len -= encoded; + encoded += encode_stmsi_5gs_mobile_identity(buffer + encoded, &service_request->fiveg_s_tmsi, len); + // encode length of 5GS mobile identity contents + uint16_t tmp = htons(encoded - LEN_FGS_MOBILE_ID_CONTENTS_SIZE - 1); + memcpy(buffer + 1, &tmp, sizeof(tmp)); + + return encoded; +} + +/** + * @brief Decode 5GMM NAS Service Request message (8.2.16 of 3GPP TS 24.501) + */ +int decode_fgs_service_request(fgs_service_request_msg_t *sr, const uint8_t *buffer, uint32_t len) +{ + uint32_t decoded = 0; + int decoded_rc = 0; + + // Service type (1/2 octet) (M) + sr->serviceType = *buffer & 0x0f; + // KSI (1/2 octet) (M) + if ((decoded_rc = decode_nas_key_set_identifier(&sr->naskeysetidentifier, IEI_NULL, *buffer >> 4)) < 0) { + return decoded_rc; + } + decoded++; + + // 5GS Mobile Identity (M) type 5G-S-TMSI (9 octets) (M) + decoded += LEN_FGS_MOBILE_ID_CONTENTS_SIZE; // skip "Length of 5GS mobile identity contents" IE + if ((decoded_rc = decode_stmsi_5gs_mobile_identity(&sr->fiveg_s_tmsi, buffer + decoded, len - decoded)) < 0) { + return decoded_rc; + } + decoded += decoded_rc; + + return decoded; +} diff --git a/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.h b/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.h new file mode 100644 index 0000000000..eecd1ee34a --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/fgs_service_request.h @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include + +#include "ProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "NasKeySetIdentifier.h" +#include "ServiceType.h" +#include "ExtendedProtocolDiscriminator.h" +#include "FGCNasMessageContainer.h" +//#include "PDUSessionStatus.h" +#include "MessageType.h" +#include "SpareHalfOctet.h" +#include "FGSMobileIdentity.h" + +#ifndef FGS_SERVICE_REQUEST_H_ +#define FGS_SERVICE_REQUEST_H_ + +/** + * Message name: Service request (8.2.16 of 3GPP TS 24.501) + * Description: The SERVICE REQUEST message is sent by the UE to the AMF + * in order to request the establishment of an N1 NAS signalling + * connection and/or to request the establishment of user-plane + * resources for PDU sessions which are established without + * user-plane resources + * Direction: UE to network + */ + +typedef struct { + /* Mandatory fields */ + NasKeySetIdentifier naskeysetidentifier; + ServiceType serviceType: 4; + Stmsi5GSMobileIdentity_t fiveg_s_tmsi; + /* Optional fields */ + FGCNasMessageContainer *fgsnasmessagecontainer; +} fgs_service_request_msg_t; + +int encode_fgs_service_request(uint8_t *buffer, fgs_service_request_msg_t *servicerequest, uint32_t len); +int decode_fgs_service_request(fgs_service_request_msg_t *sr, const uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_SERVICE_REQUEST_H_) */ diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index 98f0b5017a..f70dfc66ed 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -38,6 +38,7 @@ #include "FGSMobileIdentity.h" #define MIN_LEN_FGS_MOBILE_ID_IE 3 // type of identity "No identity" +#define LEN_5G_FGS_TMSI_IE 9 static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, const uint8_t *buffer); @@ -45,6 +46,56 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer); static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer); +int encode_stmsi_5gs_mobile_identity(uint8_t *buffer, Stmsi5GSMobileIdentity_t *stmsi, uint32_t len) +{ + // Return if buffer is shorter than min length + if (len < LEN_5G_FGS_TMSI_IE) + return -1; + + uint32_t encoded = 0; + // octet 4 + *(buffer + encoded) = (DIGIT1 << 4) | ((stmsi->spare & 0x1) << 3) | (stmsi->typeofidentity & 0x7); + encoded++; + // octet 5-6 + uint16_t temp = 0x00 | ((stmsi->amfsetid) << 6) | (stmsi->amfpointer & 0x3f); + IES_ENCODE_U16(buffer, encoded, temp); + // octet 7 + IES_ENCODE_U32(buffer, encoded, stmsi->tmsi); + return encoded; +} + +int decode_stmsi_5gs_mobile_identity(Stmsi5GSMobileIdentity_t *stmsi, const uint8_t *buffer, uint32_t len) +{ + int decoded = 0; + uint16_t temp; + + // Return if buffer is shorter than min length + if (len < LEN_5G_FGS_TMSI_IE) + return -1; + + // Octet 4: spare (bit 3) and type of identity (bits 0-2) + stmsi->digit1 = DIGIT1; + stmsi->spare = (*(buffer + decoded) >> 3) & 0x1; + stmsi->typeofidentity = *(buffer + decoded) & 0x7; + + // Validate type of identity + if (stmsi->typeofidentity != FGS_MOBILE_IDENTITY_5GS_TMSI) { + return -1; + } + + decoded++; + + // Octet 5-6: AMF Set ID (bits 6-15) and AMF Pointer (bits 0-5) + IES_DECODE_U16(buffer, decoded, temp); + stmsi->amfsetid = (temp >> 6) & 0x03ff; + stmsi->amfpointer = temp & 0x3f; + + // Octet 7-10: 32-bit TMSI + IES_DECODE_U32(buffer, decoded, stmsi->tmsi); + + return decoded; +} + int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, const uint8_t *buffer, uint32_t len) { int decoded_rc = TLV_DECODE_VALUE_DOESNT_MATCH; @@ -109,6 +160,10 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei buffer + encoded); } + if (fgsmobileidentity->stmsi.typeofidentity == FGS_MOBILE_IDENTITY_5GS_TMSI) { + encoded_rc = encode_stmsi_5gs_mobile_identity(buffer + encoded, &fgsmobileidentity->stmsi, len); + } + if (encoded_rc < 0) { return encoded_rc; } diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h index 9356a46eff..e4747461e9 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h @@ -37,6 +37,8 @@ #ifndef FGS_MOBILE_IDENTITY_H_ #define FGS_MOBILE_IDENTITY_H_ +// 4x 1bit according to 9.11.3.4 5GS mobile identity (type 5G-S-TMSI) +#define DIGIT1 0xF typedef struct { uint8_t spare:5; @@ -151,5 +153,8 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, const uint8_t *buffer, uint32_t len); +int encode_stmsi_5gs_mobile_identity(uint8_t *buffer, Stmsi5GSMobileIdentity_t *stmsi, uint32_t len); +int decode_stmsi_5gs_mobile_identity(Stmsi5GSMobileIdentity_t *stmsi, const uint8_t *buffer, uint32_t len); + #endif /* FGS MOBILE IDENTITY_H_ */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 1199aad94b..5e9ce65194 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -194,6 +194,18 @@ static int fill_guti(FGSMobileIdentity *mi, const Guti5GSMobileIdentity_t *guti) return 13; } +static int fill_fgstmsi(Stmsi5GSMobileIdentity_t *stmsi, const Guti5GSMobileIdentity_t *guti) +{ + AssertFatal(guti != NULL, "UE has no GUTI\n"); + stmsi->amfpointer = guti->amfpointer; + stmsi->amfsetid = guti->amfsetid; + stmsi->tmsi = guti->tmsi; + stmsi->digit1 = DIGIT1; + stmsi->spare = 0; + stmsi->typeofidentity = FGS_MOBILE_IDENTITY_5GS_TMSI; + return 10; +} + static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc) { int i = 0; @@ -260,6 +272,9 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) encode_result = encode_fgs_deregistration_request_ue_originating(&mm_msg->fgs_deregistration_request_ue_originating, buffer, len); break; + case FGS_SERVICE_REQUEST: + encode_result = encode_fgs_service_request(buffer, &mm_msg->service_request, len); + break; default: LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", mm_msg->header.message_type); encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE; @@ -550,6 +565,84 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) nas->registration_request_len = initialNasMsg->length; } +void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas) +{ + LOG_I(NAS, "Generate initial NAS message: Service Request\n"); + int size = 0; + fgs_nas_message_t nas_msg = {0}; + memset(&nas_msg, 0, sizeof(nas_msg)); + // NAS is security protected if has valid security contexts + bool security_protected = nas->security_container->ciphering_context && nas->security_container->integrity_context; + MM_msg *mm_msg; + + if (security_protected) { + /* Set security protected 5GS NAS message header (see 9.1.1 of 3GPP TS 24.501) */ + nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + nas_msg.header.security_header_type = INTEGRITY_PROTECTED; + nas_msg.header.sequence_number = nas->security.nas_count_ul & 0xff; + size += sizeof(fgs_nas_message_security_header_t); + mm_msg = &nas_msg.security_protected.plain.mm_msg; + } else { + // Set Mobility Management plain message header + mm_msg = &nas_msg.plain.mm_msg; + } + // Fill MM plain message header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_SERVICE_REQUEST; + size += sizeof(mm_msg_header_t); + + // Fill Service Request + // Service Type + mm_msg->service_request.serviceType = SERVICE_TYPE_DATA; + // NAS key set identifier + mm_msg->service_request.naskeysetidentifier.naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE; + mm_msg->service_request.naskeysetidentifier.tsc = NAS_KEY_SET_IDENTIFIER_NATIVE; + size += 1; + // 5G-S-TMSI + size += fill_fgstmsi(&mm_msg->service_request.fiveg_s_tmsi, nas->guti); + + /* message encoding */ + initialNasMsg->nas_data = (Byte_t *)malloc(size * sizeof(Byte_t)); + if (security_protected) { + // security protected encoding + int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->nas_data), &(nas_msg.header), size); + initialNasMsg->length = + security_header_len + + mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->nas_data + security_header_len), size - security_header_len); + /* ciphering */ + uint8_t buf[initialNasMsg->length - 7]; + nas_stream_cipher_t stream_cipher; + stream_cipher.context = nas->security_container->ciphering_context; + AssertFatal(nas->security.nas_count_ul <= 0xffffff, "fatal: NAS COUNT UL too big (todo: fix that)\n"); + stream_cipher.count = nas->security.nas_count_ul; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->nas_data + 7); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 7) << 3; + stream_compute_encrypt(nas->security_container->ciphering_algorithm, &stream_cipher, buf); + memcpy(stream_cipher.message, buf, initialNasMsg->length - 7); + /* integrity protection */ + uint8_t mac[4]; + stream_cipher.context = nas->security_container->integrity_context; + stream_cipher.count = nas->security.nas_count_ul++; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->nas_data + 6); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 6) << 3; + stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac); + printf("Integrity protected initial NAS message: mac = %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); + for (int i = 0; i < 4; i++) + initialNasMsg->nas_data[2 + i] = mac[i]; + } else { + // plain encoding + initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t *)(initialNasMsg->nas_data), size); + LOG_I(NAS, "PLAIN_5GS_MSG initial NAS message: Service Request with length %d \n", initialNasMsg->length); + } +} + void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t *uicc) { int size = sizeof(mm_msg_header_t); diff --git a/openair3/NAS/NR_UE/nr_nas_msg.h b/openair3/NAS/NR_UE/nr_nas_msg.h index e10ac54b0f..0e324052ad 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.h +++ b/openair3/NAS/NR_UE/nr_nas_msg.h @@ -36,6 +36,7 @@ #include "FGSNASSecurityModeComplete.h" #include "FGSDeregistrationRequestUEOriginating.h" #include "RegistrationComplete.h" +#include "EMM/MSG/fgs_service_request.h" #include "as_message.h" #include "FGSUplinkNasTransport.h" #include @@ -48,6 +49,9 @@ #define PAYLOAD_CONTAINER_LENGTH_MIN 3 #define PAYLOAD_CONTAINER_LENGTH_MAX 65537 +/* 3GPP TS 24.501: 9.11.3.50 Service type */ +#define SERVICE_TYPE_DATA 0x1 + /* List of allowed NSSAI from NAS messaging. */ typedef struct { int sst; @@ -106,6 +110,7 @@ typedef struct { typedef union { mm_msg_header_t header; registration_request_msg registration_request; + fgs_service_request_msg_t service_request; fgs_identiy_response_msg fgs_identity_response; fgs_authentication_response_msg fgs_auth_response; fgs_deregistration_request_ue_originating_msg fgs_deregistration_request_ue_originating; @@ -158,6 +163,7 @@ typedef struct { 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 generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas); void *nas_nrue_task(void *args_p); void *nas_nrue(void *args_p); void nas_init_nrue(int num_ues); From ad412028a2bd55e039b61058767c98b264897b07 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 29 Oct 2024 15:40:05 +0100 Subject: [PATCH 7/9] Refactor TLVDecoder macros * ideally the result of these macros shall be relevant only in unit tests, in order to validate enc/dec NAS functions * use a local print macro * remove dependency from LOG module * simplified the code * cleanup TLVDecoder.c (kept it for LTE dependencies) --- openair3/NAS/COMMON/UTIL/TLVDecoder.c | 24 -------- openair3/NAS/COMMON/UTIL/TLVDecoder.h | 86 +++++++++++++++------------ 2 files changed, 47 insertions(+), 63 deletions(-) diff --git a/openair3/NAS/COMMON/UTIL/TLVDecoder.c b/openair3/NAS/COMMON/UTIL/TLVDecoder.c index 0ed4b6f456..625176319e 100644 --- a/openair3/NAS/COMMON/UTIL/TLVDecoder.c +++ b/openair3/NAS/COMMON/UTIL/TLVDecoder.c @@ -23,28 +23,4 @@ #include #include -#include "TLVDecoder.h" - int errorCodeDecoder = 0; - -static const char* const errorCodeStringDecoder[] = { - "No error", - "Buffer NULL", - "Buffer too short", - "Unexpected IEI", - "Mandatory field not present", - "Wrong message type", - "EXT value doesn't match", - "Protocol not supported", -}; - -void tlv_decode_perror(void) -{ - if (errorCodeDecoder >= 0) - // No error or TLV_DECODE_ERR_OK - return; - - printf("TLV decoder error: (%d, %s)\n", errorCodeDecoder, errorCodeStringDecoder[errorCodeDecoder * -1]); -} - - diff --git a/openair3/NAS/COMMON/UTIL/TLVDecoder.h b/openair3/NAS/COMMON/UTIL/TLVDecoder.h index 1f93d7a554..90b95cd6bb 100644 --- a/openair3/NAS/COMMON/UTIL/TLVDecoder.h +++ b/openair3/NAS/COMMON/UTIL/TLVDecoder.h @@ -95,48 +95,56 @@ typedef enum { extern int errorCodeDecoder; -void tlv_decode_perror(void); +#ifdef ENABLE_TESTS +#define TLV_DEC_ERROR(...) fprintf(stderr, "TLV Decoder: " __VA_ARGS__) +#else +#define TLV_DEC_ERROR(...) // Do nothing +#endif -#define CHECK_PDU_POINTER_AND_LENGTH_DECODER(bUFFER, mINIMUMlENGTH, lENGTH) \ - if (bUFFER == NULL) \ - { \ - printf("(%s:%d) Got NULL pointer for the payload\n", \ - __FILE__, __LINE__); \ - errorCodeDecoder = TLV_DECODE_BUFFER_NULL; \ - LOG_FUNC_RETURN(TLV_DECODE_BUFFER_NULL); \ - } \ - if (lENGTH < mINIMUMlENGTH) \ - { \ - printf("(%s:%d) Expecting at least %d bytes, got %u\n", \ - __FILE__, __LINE__, mINIMUMlENGTH, lENGTH); \ - errorCodeDecoder = TLV_DECODE_BUFFER_TOO_SHORT; \ - LOG_FUNC_RETURN(TLV_DECODE_BUFFER_TOO_SHORT); \ - } +#define CHECK_PDU_POINTER_AND_LENGTH_DECODER(bUFFER, mINIMUMlENGTH, lENGTH) \ + do { \ + if ((bUFFER) == NULL) { \ + TLV_DEC_ERROR("(%s:%d) Got NULL pointer for the payload\n", __FILE__, __LINE__); \ + return TLV_DECODE_BUFFER_NULL; \ + } \ + if ((lENGTH) < (mINIMUMlENGTH)) { \ + TLV_DEC_ERROR("(%s:%d) Expecting at least %d bytes, got %u\n", __FILE__, __LINE__, (mINIMUMlENGTH), (lENGTH)); \ + return TLV_DECODE_BUFFER_TOO_SHORT; \ + } \ + } while (0) -#define CHECK_LENGTH_DECODER(bUFFERlENGTH, lENGTH) \ - if (bUFFERlENGTH < lENGTH) \ - { \ - errorCodeDecoder = TLV_DECODE_BUFFER_TOO_SHORT; \ - LOG_FUNC_RETURN(TLV_DECODE_BUFFER_TOO_SHORT); \ - } +#define CHECK_LENGTH_DECODER(bUFFERlENGTH, lENGTH) \ + do { \ + if ((bUFFERlENGTH) < (lENGTH)) { \ + TLV_DEC_ERROR("(%s:%d) Buffer is too short, length (%u) is less than the required length (%u)\n", \ + __FILE__, \ + __LINE__, \ + (bUFFERlENGTH), \ + (lENGTH)); \ + return TLV_DECODE_BUFFER_TOO_SHORT; \ + } \ + } while (0) -#define CHECK_MESSAGE_TYPE(mESSAGE_tYPE, bUFFER) \ - { \ - if (mESSAGE_tYPE != bUFFER) \ - { \ - errorCodeDecoder = TLV_DECODE_WRONG_MESSAGE_TYPE; \ - LOG_FUNC_RETURN(errorCodeDecoder); \ - } \ - } +#define CHECK_MESSAGE_TYPE(mESSAGE_TYPE, BUFFER) \ + do { \ + if ((MESSAGE_TYPE) != (BUFFER)) { \ + TLV_DEC_ERROR("(%s:%d) Wrong message type: Got: %u, Expected: %u\n", __FILE__, __LINE__, (BUFFER), (MESSAGE_TYPE)); \ + return TLV_DECODE_WRONG_MESSAGE_TYPE; \ + } \ + } while (0) -#define CHECK_IEI_DECODER(iEI, bUFFER) \ - if(iEI != bUFFER) \ - { \ - printf("IEI is different than the one expected." \ - "(Got: 0x%x, expecting: 0x%x)\n", bUFFER, iEI); \ - errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI; \ - LOG_FUNC_RETURN(TLV_DECODE_UNEXPECTED_IEI); \ - } +#define CHECK_IEI_DECODER(iEI, bUFFER) \ + do { \ + if ((iEI) != (bUFFER)) { \ + TLV_DEC_ERROR( \ + "IEI check failure: %s:%d: IEI is different than the one expected: " \ + "(Got: 0x%x, expecting: 0x%x)\n", \ + __FILE__, \ + __LINE__, \ + (bUFFER), \ + (iEI)); \ + return TLV_DECODE_UNEXPECTED_IEI; \ + } \ + } while (0) #endif /* define (TLV_DECODER_H_) */ - From 6faa5d3066164f73ba54308d16f72f35ff22049b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 30 Oct 2024 14:39:57 +0100 Subject: [PATCH 8/9] Refactor TLVEncoder * deleted unused TLVEncoder.c * removed dependency from LOG module in TLVEncoder Macros --- CMakeLists.txt | 1 - cmake_targets/at_commands/CMakeLists.txt | 1 - cmake_targets/nas_sim_tools/CMakeLists.txt | 1 - doc/Doxyfile | 1 - openair3/NAS/COMMON/UTIL/TLVEncoder.c | 47 --------------------- openair3/NAS/COMMON/UTIL/TLVEncoder.h | 48 +++++++++++----------- 6 files changed, 24 insertions(+), 75 deletions(-) delete mode 100644 openair3/NAS/COMMON/UTIL/TLVEncoder.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 05c3609052..8c8fbd8f71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1678,7 +1678,6 @@ set (libnas_utils_OBJS ${NAS_SRC}COMMON/UTIL/nas_timer.c ${NAS_SRC}COMMON/UTIL/socket.c ${NAS_SRC}COMMON/UTIL/stty.c - ${NAS_SRC}COMMON/UTIL/TLVEncoder.c ${NAS_SRC}COMMON/UTIL/TLVDecoder.c ${NAS_SRC}COMMON/UTIL/OctetString.c ) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index 13067562fe..146b63028c 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -145,7 +145,6 @@ set(util_SRC ${OPENAIR_NAS_DIR}/COMMON/UTIL/OctetString.c ${OPENAIR_NAS_DIR}/COMMON/UTIL/parser.c ${OPENAIR_NAS_DIR}/COMMON/UTIL/TLVDecoder.c - ${OPENAIR_NAS_DIR}/COMMON/UTIL/TLVEncoder.c ${OPENAIR_NAS_DIR}/COMMON/UTIL/socket.c ${OPENAIR_NAS_DIR}/COMMON/UTIL/stty.c ) diff --git a/cmake_targets/nas_sim_tools/CMakeLists.txt b/cmake_targets/nas_sim_tools/CMakeLists.txt index 4f0be81064..98b0772582 100755 --- a/cmake_targets/nas_sim_tools/CMakeLists.txt +++ b/cmake_targets/nas_sim_tools/CMakeLists.txt @@ -31,7 +31,6 @@ set(CONF2UEDATA_LIB_SRC ${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c ${OPENAIR_DIR}/common/utils/mem/memory.c ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c - ${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c ${OPENAIR_DIR}/common/utils/utils.c ) diff --git a/doc/Doxyfile b/doc/Doxyfile index bd1661fe60..564c43bb3f 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1332,7 +1332,6 @@ INPUT = \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/parser.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/device.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/device.c \ -@CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/TLVEncoder.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/OctetString.h \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/nas_timer.c \ @CMAKE_CURRENT_SOURCE_DIR@/../openair3/NAS/COMMON/UTIL/TLVDecoder.c \ diff --git a/openair3/NAS/COMMON/UTIL/TLVEncoder.c b/openair3/NAS/COMMON/UTIL/TLVEncoder.c deleted file mode 100644 index 0316c353fa..0000000000 --- a/openair3/NAS/COMMON/UTIL/TLVEncoder.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include - -#include "TLVEncoder.h" - -int errorCodeEncoder = 0; - -const char *const errorCodeStringEncoder[] = { - "No error", - "Buffer NULL", - "Buffer too short", - "Octet string too long for IEI", - "Wrong message type", - "Protocol not supported", -}; - -void tlv_encode_perror(void) -{ - if (errorCodeEncoder >= 0) - // No error or TLV_DECODE_ERR_OK - return; - - printf("error: (%d, %s)\n", errorCodeEncoder, errorCodeStringEncoder[errorCodeEncoder * -1]); -} - diff --git a/openair3/NAS/COMMON/UTIL/TLVEncoder.h b/openair3/NAS/COMMON/UTIL/TLVEncoder.h index 8b85185361..a400d9e388 100644 --- a/openair3/NAS/COMMON/UTIL/TLVEncoder.h +++ b/openair3/NAS/COMMON/UTIL/TLVEncoder.h @@ -84,32 +84,32 @@ typedef enum { * it cannot be further processed */ #define TLV_ENCODE_FATAL_ERROR (TLV_ENCODE_VALUE_DOESNT_MATCH) -extern int errorCodeEncoder; +#ifdef ENABLE_TESTS +#define TLV_ENC_ERROR(...) fprintf(stderr, "TLV Encoder: " __VA_ARGS__) +#else +#define TLV_ENC_ERROR(...) // Do nothing +#endif -void tlv_encode_perror(void); +#define CHECK_PDU_POINTER_AND_LENGTH_ENCODER(bUFFER, mINIMUMlENGTH, lENGTH) \ + do { \ + if ((bUFFER) == NULL) { \ + TLV_ENC_ERROR("Got NULL pointer for the payload\n"); \ + return TLV_ENCODE_BUFFER_NULL; \ + } \ + if ((lENGTH) < (mINIMUMlENGTH)) { \ + TLV_ENC_ERROR("(%s:%d) Expecting at least %d bytes, got %u\n", __FILE__, __LINE__, (mINIMUMlENGTH), (lENGTH)); \ + return TLV_ENCODE_BUFFER_TOO_SHORT; \ + } \ + } while (0) -#define CHECK_PDU_POINTER_AND_LENGTH_ENCODER(bUFFER, mINIMUMlENGTH, lENGTH) \ - if (bUFFER == NULL) \ - { \ - printf("Got NULL pointer for the payload\n"); \ - errorCodeEncoder = TLV_ENCODE_BUFFER_NULL; \ - return TLV_ENCODE_BUFFER_NULL; \ - } \ - if (lENGTH < mINIMUMlENGTH) \ - { \ - printf("(%s:%d) Expecting at least %d bytes, got %u\n", \ - __FILE__, __LINE__, mINIMUMlENGTH, lENGTH); \ - errorCodeEncoder = TLV_ENCODE_BUFFER_TOO_SHORT; \ - return TLV_ENCODE_BUFFER_TOO_SHORT; \ - } - -#define CHECK_PDU_POINTER_ENCODER(bUFFER) \ - if (bUFFER == NULL) \ - { \ - printf("Got NULL pointer for the payload\n"); \ - errorCodeEncoder = TLV_ENCODE_BUFFER_NULL; \ - return TLV_ENCODE_BUFFER_NULL; \ - } +#define CHECK_PDU_POINTER_ENCODER(bUFFER) \ + do { \ + if ((bUFFER) == NULL) { \ + TLV_ENC_ERROR("Got NULL pointer for the payload\n"); \ + errorCodeEncoder = TLV_ENCODE_BUFFER_NULL; \ + return TLV_ENCODE_BUFFER_NULL; \ + } \ + } while (0) #endif /* define (TLV_ENCODER_H_) */ From 44c9dec681861318346d4787e6337483979e3c74 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 29 Oct 2024 15:37:48 +0100 Subject: [PATCH 9/9] Add test for NAS Service Request enc/dec --- openair3/CMakeLists.txt | 1 + openair3/NAS/CMakeLists.txt | 1 + openair3/NAS/COMMON/CMakeLists.txt | 2 + openair3/NAS/COMMON/EMM/CMakeLists.txt | 5 ++ openair3/NAS/COMMON/EMM/MSG/CMakeLists.txt | 10 +++ openair3/NAS/COMMON/EMM/tests/CMakeLists.txt | 13 ++++ openair3/NAS/COMMON/EMM/tests/nas_lib_test.c | 82 ++++++++++++++++++++ openair3/NAS/COMMON/IES/CMakeLists.txt | 9 +++ 8 files changed, 123 insertions(+) create mode 100644 openair3/NAS/CMakeLists.txt create mode 100644 openair3/NAS/COMMON/CMakeLists.txt create mode 100644 openair3/NAS/COMMON/EMM/CMakeLists.txt create mode 100644 openair3/NAS/COMMON/EMM/MSG/CMakeLists.txt create mode 100644 openair3/NAS/COMMON/EMM/tests/CMakeLists.txt create mode 100644 openair3/NAS/COMMON/EMM/tests/nas_lib_test.c create mode 100644 openair3/NAS/COMMON/IES/CMakeLists.txt diff --git a/openair3/CMakeLists.txt b/openair3/CMakeLists.txt index 555ca7cbc8..f638abbaaa 100644 --- a/openair3/CMakeLists.txt +++ b/openair3/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(M3AP) add_subdirectory(S1AP) add_subdirectory(NGAP) add_subdirectory(NRPPA) +add_subdirectory(NAS) diff --git a/openair3/NAS/CMakeLists.txt b/openair3/NAS/CMakeLists.txt new file mode 100644 index 0000000000..50cbedd280 --- /dev/null +++ b/openair3/NAS/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(COMMON) diff --git a/openair3/NAS/COMMON/CMakeLists.txt b/openair3/NAS/COMMON/CMakeLists.txt new file mode 100644 index 0000000000..21de73f92f --- /dev/null +++ b/openair3/NAS/COMMON/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(IES) +add_subdirectory(EMM) diff --git a/openair3/NAS/COMMON/EMM/CMakeLists.txt b/openair3/NAS/COMMON/EMM/CMakeLists.txt new file mode 100644 index 0000000000..1da5bad152 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/CMakeLists.txt @@ -0,0 +1,5 @@ +add_subdirectory(MSG) + +if(ENABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/openair3/NAS/COMMON/EMM/MSG/CMakeLists.txt b/openair3/NAS/COMMON/EMM/MSG/CMakeLists.txt new file mode 100644 index 0000000000..fed78e453d --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(fgs_lib OBJECT + fgs_service_request.c +) + +target_link_libraries(fgs_lib PUBLIC fgs_ies_lib) + +target_include_directories(fgs_lib PUBLIC + ${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/openair3/NAS/COMMON/EMM/tests/CMakeLists.txt b/openair3/NAS/COMMON/EMM/tests/CMakeLists.txt new file mode 100644 index 0000000000..3f960c5562 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/tests/CMakeLists.txt @@ -0,0 +1,13 @@ +message(STATUS "Add test nas_lib_test") + +add_executable(nas_lib_test nas_lib_test.c) + +add_dependencies(tests nas_lib_test) +add_test(NAME nas_lib_test COMMAND nas_lib_test) + +target_link_libraries(nas_lib_test PRIVATE fgs_lib fgs_ies_lib) + +target_include_directories(nas_lib_test PRIVATE + ${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) diff --git a/openair3/NAS/COMMON/EMM/tests/nas_lib_test.c b/openair3/NAS/COMMON/EMM/tests/nas_lib_test.c new file mode 100644 index 0000000000..41865051cd --- /dev/null +++ b/openair3/NAS/COMMON/EMM/tests/nas_lib_test.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include "fgs_service_request.h" +#include "nr_nas_msg.h" + +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + printf("detected error at %s:%d:%s: %s\n", file, line, function, s); + abort(); +} + +/** + * @brief Equality check for NAS Service Request enc/dec + */ +static bool eq_service_request(const fgs_service_request_msg_t *a, const fgs_service_request_msg_t *b) +{ + bool result = true; + result &= memcmp(&a->naskeysetidentifier, &b->naskeysetidentifier, sizeof(NasKeySetIdentifier)) == 0; + result &= a->serviceType == b->serviceType; + result &= memcmp(&a->fiveg_s_tmsi, &b->fiveg_s_tmsi, sizeof(Stmsi5GSMobileIdentity_t)) == 0; + return result; +} + +/** + * @brief Test NAS Service Request enc/dec + */ +static void test_service_request(void) +{ + // Dummy NAS Service Request message + uint16_t amf_set_id = 0x48; + uint16_t amf_pointer = 0x34; + uint32_t tmsi = 0x56789ABC; + fgs_service_request_msg_t original_msg = { + .naskeysetidentifier = {.tsc = NAS_KEY_SET_IDENTIFIER_NATIVE, .naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE}, + .serviceType = SERVICE_TYPE_DATA, + .fiveg_s_tmsi = {.spare = 0, + .typeofidentity = FGS_MOBILE_IDENTITY_5GS_TMSI, + .amfsetid = amf_set_id, + .amfpointer = amf_pointer, + .tmsi = tmsi}}; + + uint8_t expected_encoded_data[] = {0x71, + 0x00, + 0x00, + 0xF4, + (amf_set_id >> 2) & 0xFF, + (amf_set_id << 6) | (amf_pointer & 0x3F), + (tmsi >> 24) & 0xFF, + (tmsi >> 16) & 0xFF, + (tmsi >> 8) & 0xFF, + tmsi & 0xFF}; + uint16_t tmp = htons(7); // length of 5GS mobile identity IE for 5G-S-TMSI (bytes) + memcpy(expected_encoded_data + 1, &tmp, sizeof(tmp)); + + // Buffer + uint8_t buffer[64]; + memset(buffer, 0, sizeof(buffer)); + + // Encode NAS Service Request + int encoded_length = encode_fgs_service_request(buffer, &original_msg, sizeof(buffer)); + AssertFatal(encoded_length >= 0, "encode_fgs_service_request() failed\n"); + + // Compare the raw encoded buffer with expected encoded data + AssertFatal(memcmp(buffer, expected_encoded_data, encoded_length) == 0, "Encoding mismatch!\n"); + + // Decode NAS Service Request + fgs_service_request_msg_t decoded_service_request = {0}; + int decoded_length = decode_fgs_service_request(&decoded_service_request, buffer, sizeof(buffer)); + AssertFatal(decoded_length >= 0, "decode_fgs_service_request() failed\n"); + + // Compare original and decoded messages + AssertFatal(eq_service_request(&original_msg, &decoded_service_request) == 0, + "test_service_request() failed: original and decoded messages do not match\n"); +} + +int main() +{ + test_service_request(); + return 0; +} diff --git a/openair3/NAS/COMMON/IES/CMakeLists.txt b/openair3/NAS/COMMON/IES/CMakeLists.txt new file mode 100644 index 0000000000..99df08e7b0 --- /dev/null +++ b/openair3/NAS/COMMON/IES/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(fgs_ies_lib OBJECT + NasKeySetIdentifier.c + FGSMobileIdentity.c +) + +target_include_directories(fgs_ies_lib PUBLIC + ${CMAKE_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +)