From 724af2b060b0481c75a161335ee1c49ff0b3426a Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 30 Jun 2021 12:59:32 +0200 Subject: [PATCH] Added nas 5g msg packing and unpacking --- lib/include/srsran/asn1/nas_5g_ies.h | 2699 +++++++++++++++ lib/include/srsran/asn1/nas_5g_msg.h | 2390 +++++++++++++ lib/include/srsran/asn1/nas_5g_utils.h | 87 + lib/src/asn1/CMakeLists.txt | 5 + lib/src/asn1/nas_5g_ies.cc | 4359 ++++++++++++++++++++++++ lib/src/asn1/nas_5g_msg.cc | 4198 +++++++++++++++++++++++ lib/src/asn1/nas_5g_utils.cc | 56 + lib/test/asn1/CMakeLists.txt | 3 + lib/test/asn1/nas_5g_msg_test.cc | 1610 +++++++++ 9 files changed, 15407 insertions(+) create mode 100644 lib/include/srsran/asn1/nas_5g_ies.h create mode 100644 lib/include/srsran/asn1/nas_5g_msg.h create mode 100644 lib/include/srsran/asn1/nas_5g_utils.h create mode 100644 lib/src/asn1/nas_5g_ies.cc create mode 100644 lib/src/asn1/nas_5g_msg.cc create mode 100644 lib/src/asn1/nas_5g_utils.cc create mode 100644 lib/test/asn1/nas_5g_msg_test.cc diff --git a/lib/include/srsran/asn1/nas_5g_ies.h b/lib/include/srsran/asn1/nas_5g_ies.h new file mode 100644 index 000000000..2c780076c --- /dev/null +++ b/lib/include/srsran/asn1/nas_5g_ies.h @@ -0,0 +1,2699 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#ifndef SRSRAN_NAS_5G_IES_H +#define SRSRAN_NAS_5G_IES_H +#include "nas_5g_utils.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/config.h" + +#include +#include +#include + +namespace srsran { +namespace nas_5g { + +// IEs + +// IE: 5GS registration type +// Reference: 9.11.3.7 +class registration_type_5gs_t +{ +public: + struct registration_type_type_ { + enum options { + initial_registration = 0b001, + mobility_registration_updating = 0b010, + periodic_registration_updating = 0b011, + emergency_registration = 0b100, + reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated registration_type_type; + + struct follow_on_request_bit_type_ { + enum options { + no_follow_on_request_pending = 0b0, + follow_on_request_pending = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated follow_on_request_bit_type; + + uint32_t length; + follow_on_request_bit_type follow_on_request_bit; + registration_type_type registration_type; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_type_5gs_t + +// IE: key set identifier +// Reference: 9.11.3.32 +class key_set_identifier_t +{ +public: + struct security_context_flag_type_ { + enum options { + native_security_context = 0b0, + mapped_security_context = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated security_context_flag_type; + + struct nas_key_set_identifier_type_ { + enum options { + no_key_is_available_or_reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated nas_key_set_identifier_type; + + uint32_t length; + security_context_flag_type security_context_flag; + nas_key_set_identifier_type nas_key_set_identifier; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // key_set_identifier_t + +// IE: 5GS mobile identity +// Reference: 9.11.3.4 +class mobile_identity_5gs_t +{ +public: + struct identity_types_ { + enum options { + no_identity = 0b000, + suci = 0b001, + guti_5g = 0b010, + imei = 0b011, + s_tmsi_5g = 0b100, + imeisv = 0b101, + mac_address = 0b110, + eui_64 = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated identity_types; + + void set(identity_types::options e = identity_types::no_identity) { type_ = e; }; + identity_types type() const { return type_; } + + class suci_s + { + public: + struct supi_format_type_ { + enum options { + imsi = 0b000, + network_specific_identifier = 0b010, + gci = 0b011, + gli = 0b100, + + } value; + const char* to_string(); + }; + typedef nas_enumerated supi_format_type; + + struct protection_scheme_id_type_ { + enum options { + null_scheme = 0b0000, + ecies_scheme_profile_a = 0b0001, + ecies_scheme_profile_b = 0b0010, + + } value; + const char* to_string(); + }; + typedef nas_enumerated protection_scheme_id_type; + + supi_format_type supi_format = supi_format_type_::options::imsi; + std::array mcc; + std::array mnc; + std::array routing_indicator; + protection_scheme_id_type protection_scheme_id = protection_scheme_id_type_::options::null_scheme; + uint8_t home_network_public_key_identifier; + std::vector scheme_output; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // suci + class guti_5g_s + { + public: + std::array mcc; + std::array mnc; + uint8_t amf_region_id; + uint16_t amf_set_id; + uint8_t amf_pointer; + uint32_t tmsi_5g; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // guti_5g + class imei_s + { + public: + bool odd_even_indicator; + std::array imei; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // imei + class s_tmsi_5g_s + { + public: + uint16_t amf_set_id; + uint8_t amf_pointer; + uint32_t tmsi_5g; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // s_tmsi_5g + class imeisv_s + { + public: + bool odd_even_indicator; + std::array imeisv; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // imeisv + class mac_address_s + { + public: + std::array mac_address; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // mac_address + class eui_64_s + { + public: + std::array eui_64; + + SRSASN_CODE pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp); + SRSASN_CODE unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length); + + }; // eui_64 + + uint32_t length; + // Getters + + suci_s& suci() + { + asn1::assert_choice_type(identity_types::suci, type_, "suci"); + return *srslog::detail::any_cast(&choice_container); + } + + guti_5g_s& guti_5g() + { + asn1::assert_choice_type(identity_types::guti_5g, type_, "guti_5g"); + return *srslog::detail::any_cast(&choice_container); + } + + imei_s& imei() + { + asn1::assert_choice_type(identity_types::imei, type_, "imei"); + return *srslog::detail::any_cast(&choice_container); + } + + s_tmsi_5g_s& s_tmsi_5g() + { + asn1::assert_choice_type(identity_types::s_tmsi_5g, type_, "s_tmsi_5g"); + return *srslog::detail::any_cast(&choice_container); + } + + imeisv_s& imeisv() + { + asn1::assert_choice_type(identity_types::imeisv, type_, "imeisv"); + return *srslog::detail::any_cast(&choice_container); + } + + mac_address_s& mac_address() + { + asn1::assert_choice_type(identity_types::mac_address, type_, "mac_address"); + return *srslog::detail::any_cast(&choice_container); + } + + eui_64_s& eui_64() + { + asn1::assert_choice_type(identity_types::eui_64, type_, "eui_64"); + return *srslog::detail::any_cast(&choice_container); + } + + suci_s& set_suci() + { + set(identity_types::suci); + choice_container = srslog::detail::any{suci_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + guti_5g_s& set_guti_5g() + { + set(identity_types::guti_5g); + choice_container = srslog::detail::any{guti_5g_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + imei_s& set_imei() + { + set(identity_types::imei); + choice_container = srslog::detail::any{imei_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + s_tmsi_5g_s& set_s_tmsi_5g() + { + set(identity_types::s_tmsi_5g); + choice_container = srslog::detail::any{s_tmsi_5g_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + imeisv_s& set_imeisv() + { + set(identity_types::imeisv); + choice_container = srslog::detail::any{imeisv_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + mac_address_s& set_mac_address() + { + set(identity_types::mac_address); + choice_container = srslog::detail::any{mac_address_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + eui_64_s& set_eui_64() + { + set(identity_types::eui_64); + choice_container = srslog::detail::any{eui_64_s()}; + return *srslog::detail::any_cast(&choice_container); + } + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +private: + identity_types type_; + srslog::detail::any choice_container; + +}; // mobile_identity_5gs_t + +// IE: 5GMM capability +// Reference: 9.11.3.1 +class capability_5gmm_t +{ +public: + uint32_t length; + bool sgc; + bool iphc_cp_c_io_t_5g; + bool n3_data; + bool cp_c_io_t_5g; + bool restrict_ec; + bool lpp; + bool ho_attach; + bool s1_mode; + bool racs; + bool nssaa; + bool lcs_5g; + bool v2_xcnpc5; + bool v2_xcepc5; + bool v2_x; + bool up_c_io_t_5g; + bool srvcc_5g; + bool ehc_cp_c_io_t_5g; + bool multiple_up; + bool wusa; + bool cag; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // capability_5gmm_t + +// IE: UE security capability +// Reference: 9.11.3.54 +class ue_security_capability_t +{ +public: + uint32_t length; + bool ea0_5g_supported; + bool ea1_128_5g_supported; + bool ea2_128_5g_supported; + bool ea3_128_5g_supported; + bool ea4_5g_supported; + bool ea5_5g_supported; + bool ea6_5g_supported; + bool ea7_5g_supported; + bool ia0_5g_supported; + bool ia1_128_5g_supported; + bool ia2_128_5g_supported; + bool ia3_128_5g_supported; + bool ia4_5g_supported; + bool ia5_5g_supported; + bool ia6_5g_supported; + bool ia7_5g_supported; + bool eps_caps_present; + bool eea0_supported; + bool eea1_128_supported; + bool eea2_128_supported; + bool eea3_128_supported; + bool eea4_supported; + bool eea5_supported; + bool eea6_supported; + bool eea7_supported; + bool eia0_supported; + bool eia1_128_supported; + bool eia2_128_supported; + bool eia3_128_supported; + bool eia4_supported; + bool eia5_supported; + bool eia6_supported; + bool eia7_supported; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_security_capability_t + +// IE: S-NSSAI +// Reference: 9.11.2.8 +class s_nssai_t +{ +public: + struct SST_type_ { + enum options { + sst = 0b00000001, + sst_and_mapped_hplmn_sst = 0b00000010, + sst_and_sd = 0b00000100, + sst_sd_and_mapped_hplmn_sst = 0b00000101, + sst_sd_mapped_hplmn_sst_and_mapped_hplmn_sd = 0b00001000, + + } value; + const char* to_string(); + }; + typedef nas_enumerated SST_type; + + uint32_t length; + uint8_t sst; + uint32_t sd; + uint8_t mapped_hplmn_sst; + uint32_t mapped_hplmn_sd; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // s_nssai_t + +// IE: NSSAI +// Reference: 9.11.3.37 +class nssai_t +{ +public: + uint32_t length; + std::vector s_nssai_list; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // nssai_t + +// IE: 5GS tracking area identity +// Reference: 9.11.3.8 +class tracking_area_identity_5gs_t +{ +public: + uint32_t length; + std::array mcc; + std::array mnc; + uint32_t tac; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // tracking_area_identity_5gs_t + +// IE: S1 UE network capability +// Reference: 9.11.3.48 +class s1_ue_network_capability_t +{ +public: + uint32_t length; + bool eea0_supported; + bool eea1_128_supported; + bool eea2_128_supported; + bool eea3_128_supported; + bool eea4_supported; + bool eea5_supported; + bool eea6_supported; + bool eea7_supported; + bool eia0_supported; + bool eia1_128_supported; + bool eia2_128_supported; + bool eia3_128_supported; + bool eia4_supported; + bool eia5_supported; + bool eia6_supported; + bool eia7_supported; + bool uea0_supported; + bool uea1_128_supported; + bool uea2_128_supported; + bool uea3_128_supported; + bool uea4_supported; + bool uea5_supported; + bool uea6_supported; + bool uea7_supported; + bool ucs2_support; + bool uia1_128_supported; + bool uia2_128_supported; + bool uia3_128_supported; + bool uia4_supported; + bool uia5_supported; + bool uia6_supported; + bool uia7_supported; + bool pro_se_dd_supported; + bool pro_se_supported; + bool h245_ash_supported; + bool acc_csfb_supported; + bool llp_supported; + bool lcs_supported; + bool srvcc_capability_supported; + bool nf_capability_supported; + bool e_pco_supported; + bool hc_cp_c_io_t_supported; + bool e_rw_o_pdn_supported; + bool s1_u_data_supported; + bool up_c_io_t_supported; + bool cp_c_io_t_supported; + bool pro_se_relay_supported; + bool pro_se_dc_supported; + bool max_15_eps_bearer_supported; + bool sgc_supported; + bool n1mode_supported; + bool dcnr_supported; + bool cp_backoff_supported; + bool restrict_ec_supported; + bool v2_x_pc5_supported; + bool multiple_drb_supported; + bool nr_pc5_supported; + bool up_mt_edt_supported; + bool cp_mt_edt_supported; + bool wus_supported; + bool racs_supported; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // s1_ue_network_capability_t + +// IE: Uplink data status +// Reference: 9.11.3.57 +class uplink_data_status_t +{ +public: + uint32_t length; + bool psi_7; + bool psi_6; + bool psi_5; + bool psi_4; + bool psi_3; + bool psi_2; + bool psi_1; + bool psi_0; + bool psi_15; + bool psi_14; + bool psi_13; + bool psi_12; + bool psi_11; + bool psi_10; + bool psi_9; + bool psi_8; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // uplink_data_status_t + +// IE: PDU session status +// Reference: 9.11.3.44 +class pdu_session_status_t +{ +public: + uint32_t length; + bool psi_7; + bool psi_6; + bool psi_5; + bool psi_4; + bool psi_3; + bool psi_2; + bool psi_1; + bool psi_0; + bool psi_15; + bool psi_14; + bool psi_13; + bool psi_12; + bool psi_11; + bool psi_10; + bool psi_9; + bool psi_8; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_status_t + +// IE: MICO indication +// Reference: 9.11.3.31 +class mico_indication_t +{ +public: + uint32_t length; + bool sprti; + bool aai; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // mico_indication_t + +// IE: UE status +// Reference: 9.11.3.56 +class ue_status_t +{ +public: + uint32_t length; + bool n1_mode_reg; + bool s1_mode_reg; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_status_t + +// IE: Allowed PDU session status +// Reference: 9.11.3.13 +class allowed_pdu_session_status_t +{ +public: + uint32_t length; + bool psi_7; + bool psi_6; + bool psi_5; + bool psi_4; + bool psi_3; + bool psi_2; + bool psi_1; + bool psi_0; + bool psi_15; + bool psi_14; + bool psi_13; + bool psi_12; + bool psi_11; + bool psi_10; + bool psi_9; + bool psi_8; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // allowed_pdu_session_status_t + +// IE: UE usage setting +// Reference: 9.11.3.55 +class ue_usage_setting_t +{ +public: + struct UE_usage_setting_type_ { + enum options { + voice_centric = 0b0, + data_centric = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated UE_usage_setting_type; + + uint32_t length; + UE_usage_setting_type ue_usage_setting; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_usage_setting_t + +// IE: 5GS DRX parameters +// Reference: 9.11.3.2A +class drx_parameters_5gs_t +{ +public: + struct drx_value_type_ { + enum options { + drx_value_not_specified = 0b0000, + drx_cycle_parameter_t_32 = 0b0001, + drx_cycle_parameter_t_64 = 0b0010, + drx_cycle_parameter_t_128 = 0b0011, + drx_cycle_parameter_t_256 = 0b0100, + + } value; + const char* to_string(); + }; + typedef nas_enumerated drx_value_type; + + uint32_t length; + drx_value_type drx_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // drx_parameters_5gs_t + +// IE: EPS NAS message container +// Reference: 9.11.3.24 +class eps_nas_message_container_t +{ +public: + uint32_t length; + std::vector eps_nas_message_container; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // eps_nas_message_container_t + +// IE: DNN +// Reference: 9.11.2.1B +class dnn_t +{ +public: + uint32_t length; + std::vector dnn_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // dnn_t + +// IE: LADN indication +// Reference: 9.11.3.29 +class ladn_indication_t +{ +public: + uint32_t length; + std::vector ladn_dnn_values; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ladn_indication_t + +// IE: Payload container type +// Reference: 9.11.3.40 +class payload_container_type_t +{ +public: + struct Payload_container_type_type_ { + enum options { + n1_sm_information = 0b0001, + sms = 0b0010, + lte_positioning_protocol_lpp_message_container = 0b0011, + sor_transparent_container = 0b0100, + ue_policy_container = 0b0101, + ue_parameters_update_transparent_container = 0b0110, + location_services_message_container = 0b0111, + c_io_t_user_data_container = 0b1000, + multiple_payloads = 0b1111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Payload_container_type_type; + + uint32_t length; + Payload_container_type_type payload_container_type; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // payload_container_type_t + +// IE: Payload container +// Reference: 9.11.3.39 +class payload_container_t +{ +public: + uint32_t length; + std::vector payload_container_contents; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // payload_container_t + +// IE: Network slicing indication +// Reference: 9.11.3.36 +class network_slicing_indication_t +{ +public: + uint32_t length; + bool nssci; + bool dcni; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // network_slicing_indication_t + +// IE: 5GS update type +// Reference: 9.11.3.9A +class update_type_5gs_t +{ +public: + struct SMS_requested_type_ { + enum options { + sms_over_nas_not_supported = 0b0, + sms_over_nas_supported = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated SMS_requested_type; + + struct NG_RAN_RCU_type_ { + enum options { + ue_radio_capability_update_not_needed = 0b0, + ue_radio_capability_update_needed = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated NG_RAN_RCU_type; + + struct PNB_5GS_CIoT_type_ { + enum options { + no_additional_information = 0b00, + control_plane_c_io_t_5gs_optimization = 0b01, + user_plane_c_io_t_5gs_optimization = 0b10, + reserved = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated PNB_5GS_CIoT_type; + + struct PNB_EPS_CIoT_type_ { + enum options { + no_additional_information = 0b00, + control_plane_c_io_t_eps_optimization = 0b01, + user_plane_c_io_t_eps_optimization = 0b10, + reserved = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated PNB_EPS_CIoT_type; + + uint32_t length; + PNB_EPS_CIoT_type pnb_eps_c_io_t; + PNB_5GS_CIoT_type pnb_5gs_c_io_t; + NG_RAN_RCU_type ng_ran_rcu; + SMS_requested_type sms_requested; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // update_type_5gs_t + +// IE: Mobile station classmark 2 +// Reference: 9.11.3.31C +class mobile_station_classmark_2_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // mobile_station_classmark_2_t + +// IE: Supported codec list +// Reference: 9.11.3.51A +class supported_codec_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // supported_codec_list_t + +// IE: message container +// Reference: 9.11.3.33 +class message_container_t +{ +public: + uint32_t length; + std::vector nas_message_container; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // message_container_t + +// IE: EPS bearer context status +// Reference: 9.11.3.23A +class eps_bearer_context_status_t +{ +public: + uint32_t length; + bool ebi_7; + bool ebi_6; + bool ebi_5; + bool ebi_4; + bool ebi_3; + bool ebi_2; + bool ebi_1; + bool ebi_0; + bool ebi_15; + bool ebi_14; + bool ebi_13; + bool ebi_12; + bool ebi_11; + bool ebi_10; + bool ebi_9; + bool ebi_8; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // eps_bearer_context_status_t + +// IE: Extended DRX parameters +// Reference: 9.11.3.26A +class extended_drx_parameters_t +{ +public: + struct Paging_Time_Window_type_ { + enum options { + seconds_0 = 0b0000, + second_1 = 0b0001, + seconds_2 = 0b0010, + seconds_3 = 0b0011, + seconds_4 = 0b0100, + seconds_5 = 0b0101, + seconds_6 = 0b0110, + seconds_7 = 0b0111, + seconds_8 = 0b1000, + seconds_9 = 0b1001, + seconds_10 = 0b1010, + seconds_12 = 0b1011, + seconds_14 = 0b1100, + seconds_16 = 0b1101, + seconds_18 = 0b1110, + seconds_20 = 0b1111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Paging_Time_Window_type; + + struct eDRX_value_type_ { + enum options { + second_1_28 = 0b0000, + second_2_56 = 0b0001, + second_3_84 = 0b0010, + second_5_12 = 0b0011, + second_6_4 = 0b0100, + second_7_68 = 0b0101, + second_8_96 = 0b0110, + second_10_24 = 0b0111, + second_11_52 = 0b1000, + second_12_8 = 0b1001, + second_14_08 = 0b1010, + second_15_36 = 0b1011, + second_16_64 = 0b1100, + second_17_92 = 0b1101, + second_19_20 = 0b1110, + second_20_48 = 0b1111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated eDRX_value_type; + + uint32_t length; + Paging_Time_Window_type paging__time__window; + eDRX_value_type e_drx_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // extended_drx_parameters_t + +// IE: GPRS timer 3 +// Reference: 9.11.2.5 +class gprs_timer_3_t +{ +public: + struct Unit_type_ { + enum options { + value_is_incremented_in_multiples_of_10_minutes = 0b000, + value_is_incremented_in_multiples_of_1_hour = 0b001, + value_is_incremented_in_multiples_of_10_hours = 0b010, + value_is_incremented_in_multiples_of_2_seconds = 0b011, + value_is_incremented_in_multiples_of_30_seconds = 0b100, + value_is_incremented_in_multiples_of_1_minute = 0b101, + value_is_incremented_in_multiples_of_320_hours = 0b110, + value_indicates_that_the_timer_is_deactivated = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Unit_type; + + uint32_t length; + Unit_type unit; + uint8_t timer_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // gprs_timer_3_t + +// IE: UE radio capability ID +// Reference: 9.11.3.68 +class ue_radio_capability_id_t +{ +public: + uint32_t length; + std::vector ue_radio_capability_id; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_radio_capability_id_t + +// IE: Mapped NSSAI +// Reference: 9.11.3.31B +class mapped_nssai_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // mapped_nssai_t + +// IE: Additional information requested +// Reference: 9.11.3.12A +class additional_information_requested_t +{ +public: + uint32_t length; + bool cipher_key; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // additional_information_requested_t + +// IE: WUS assistance information +// Reference: 9.11.3.71 +class wus_assistance_information_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // wus_assistance_information_t + +// IE: N5GC indication +// Reference: 9.11.3.72 +class n5gc_indication_t +{ +public: + uint32_t length; + bool n5gcreg; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // n5gc_indication_t + +// IE: NB-N1 mode DRX parameters +// Reference: 9.11.3.73 +class nb_n1_mode_drx_parameters_t +{ +public: + struct nb_n1_mode_drx_value_type_ { + enum options { + drx_value_not_specified = 0b0000, + drx_cycle_parameter_t_32 = 0b0001, + drx_cycle_parameter_t_64 = 0b0010, + drx_cycle_parameter_t_128 = 0b0011, + drx_cycle_parameter_t_256 = 0b0100, + drx_cycle_parameter_t_512 = 0b0101, + drx_cycle_parameter_t_1024 = 0b0111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated nb_n1_mode_drx_value_type; + + uint32_t length; + nb_n1_mode_drx_value_type nb_n1_mode_drx_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // nb_n1_mode_drx_parameters_t + +// IE: 5GS registration result +// Reference: 9.11.3.6 +class registration_result_5gs_t +{ +public: + struct Emergency_registered_type_ { + enum options { + not_registered_for_emergency_services = 0b0, + registered_for_emergency_services = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Emergency_registered_type; + + struct NSSAA_to_be_performed_type_ { + enum options { + nssaa_is_not_to_be_performed = 0b0, + nssaa_is_to_be_performed = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated NSSAA_to_be_performed_type; + + struct SMS_allowed_type_ { + enum options { + sms_over_nas_not_allowed = 0b0, + sms_over_nas_allowed = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated SMS_allowed_type; + + struct registration_result_type_ { + enum options { + access_3_gpp = 0b001, + non_3_gpp_access = 0b010, + access_3_gpp_and_non_3_gpp_access = 0b011, + reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated registration_result_type; + + uint32_t length; + Emergency_registered_type emergency_registered; + NSSAA_to_be_performed_type nssaa_to_be_performed; + SMS_allowed_type sms_allowed; + registration_result_type registration_result; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_result_5gs_t + +// IE: PLMN list +// Reference: 9.11.3.45 +class plmn_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // plmn_list_t + +// IE: 5GS tracking area identity list +// Reference: 9.11.3.9 +class tracking_area_identity_list_5gs_t +{ +public: + struct type_of_list_type_ { + enum options { + list_of_ta_cs_belonging_to_one_plmn_or_snpn_with_non_consecutive_tac_values = 0b00, + list_of_ta_cs_belonging_to_one_plmn_or_snpn_with_consecutive_tac_values = 0b01, + list_of_ta_is_belonging_to_different_plm_ns = 0b10, + reserved = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated type_of_list_type; + + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // tracking_area_identity_list_5gs_t + +// IE: Rejected NSSAI +// Reference: 9.11.3.46 +class rejected_nssai_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // rejected_nssai_t + +// IE: 5GS network feature support +// Reference: 9.11.3.5 +class network_feature_support_5gs_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // network_feature_support_5gs_t + +// IE: PDU session reactivation result +// Reference: 9.11.3.42 +class pdu_session_reactivation_result_t +{ +public: + uint32_t length; + bool psi_7; + bool psi_6; + bool psi_5; + bool psi_4; + bool psi_3; + bool psi_2; + bool psi_1; + bool psi_0; + bool psi_15; + bool psi_14; + bool psi_13; + bool psi_12; + bool psi_11; + bool psi_10; + bool psi_9; + bool psi_8; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_reactivation_result_t + +// IE: PDU session reactivation result error cause +// Reference: 9.11.3.43 +class pdu_session_reactivation_result_error_cause_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_reactivation_result_error_cause_t + +// IE: LADN information +// Reference: 9.11.3.30 +class ladn_information_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ladn_information_t + +// IE: Service area list +// Reference: 9.11.3.49 +class service_area_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // service_area_list_t + +// IE: GPRS timer 2 +// Reference: 9.11.2.4 +class gprs_timer_2_t +{ +public: + uint32_t length; + uint8_t timer_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // gprs_timer_2_t + +// IE: Emergency number list +// Reference: 9.11.3.23 +class emergency_number_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // emergency_number_list_t + +// IE: Extended emergency number list +// Reference: 9.11.3.26 +class extended_emergency_number_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // extended_emergency_number_list_t + +// IE: SOR transparent container +// Reference: 9.11.3.51 +class sor_transparent_container_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // sor_transparent_container_t + +// IE: EAP message +// Reference: 9.11.2.2 +class eap_message_t +{ +public: + uint32_t length; + std::vector eap_message; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // eap_message_t + +// IE: NSSAI inclusion mode +// Reference: 9.11.3.37A +class nssai_inclusion_mode_t +{ +public: + struct NSSAI_inclusion_mode_type_ { + enum options { + nssai_inclusion_mode_a = 0b00, + nssai_inclusion_mode_b = 0b01, + nssai_inclusion_mode_c = 0b10, + nssai_inclusion_mode_d = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated NSSAI_inclusion_mode_type; + + uint32_t length; + NSSAI_inclusion_mode_type nssai_inclusion_mode; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // nssai_inclusion_mode_t + +// IE: Operator-defined access category definitions +// Reference: 9.11.3.38 +class operator_defined_access_category_definitions_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // operator_defined_access_category_definitions_t + +// IE: Non-3GPP NW provided policies +// Reference: 9.11.3.36A +class non_3_gpp_nw_provided_policies_t +{ +public: + uint32_t length; + bool n3_en; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // non_3_gpp_nw_provided_policies_t + +// IE: UE radio capability ID deletion indication +// Reference: 9.11.3.69 +class ue_radio_capability_id_deletion_indication_t +{ +public: + struct Deletion_request_type_ { + enum options { + ue_radio_capability_id_deletion_not_requested = 0b000, + network_assigned_ue_radio_capability_i_ds_deletion_requested = 0b001, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Deletion_request_type; + + uint32_t length; + Deletion_request_type deletion_request; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_radio_capability_id_deletion_indication_t + +// IE: Ciphering key data +// Reference: 9.11.3.18C +class ciphering_key_data_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ciphering_key_data_t + +// IE: CAG information list +// Reference: 9.11.3.18A +class cag_information_list_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // cag_information_list_t + +// IE: Truncated 5G-S-TMSI configuration +// Reference: 9.11.3.70 +class truncated_5g_s_tmsi_configuration_t +{ +public: + uint32_t length; + uint8_t truncated_amf__set_id_value; + uint8_t truncated_amf__pointer_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // truncated_5g_s_tmsi_configuration_t + +// IE: 5GMM cause +// Reference: 9.11.3.2 +class cause_5gmm_t +{ +public: + struct cause_5gmm_type_ { + enum options { + illegal_ue = 0b00000011, + pei_not_accepted = 0b00000101, + illegal_me = 0b00000110, + services_not_allowed_5gs = 0b00000111, + ue_identity_cannot_be_derived_by_the_network = 0b00001001, + implicitly_de_registered = 0b00001010, + plmn_not_allowed = 0b00001011, + tracking_area_not_allowed = 0b00001100, + roaming_not_allowed_in_this_tracking_area = 0b00001101, + no_suitable_cells_in_tracking_area = 0b00001111, + mac_failure = 0b00010100, + synch_failure = 0b00010101, + congestion = 0b00010110, + ue_security_capabilities_mismatch = 0b00010111, + security_mode_rejected_unspecified = 0b00011000, + non_5g_authentication_unacceptable = 0b00011010, + n1_mode_not_allowed = 0b00011011, + restricted_service_area = 0b00011100, + redirection_to_epc_required = 0b00011111, + ladn_not_available = 0b00101011, + no_network_slices_available = 0b00111110, + maximum_number_of_pdu_sessions_reached_ = 0b01000001, + insufficient_resources_for_specific_slice_and_dnn = 0b01000011, + insufficient_resources_for_specific_slice = 0b01000101, + ng_ksi_already_in_use = 0b01000111, + non_3_gpp_access_to_5gcn_not_allowed = 0b01001000, + serving_network_not_authorized = 0b01001001, + temporarily_not_authorized_for_this_snpn = 0b01001010, + permanently_not_authorized_for_this_snpn = 0b01001011, + not_authorized_for_this_cag_or_authorized_for_cag_cells_only = 0b01001100, + wireline_access_area_not_allowed = 0b01001101, + payload_was_not_forwarded = 0b01011010, + dnn_not_supported_or_not_subscribed_in_the_slice = 0b01011011, + insufficient_user_plane_resources_for_the_pdu_session = 0b01011100, + semantically_incorrect_message = 0b01011111, + invalid_mandatory_information = 0b01100000, + message_type_non_existent_or_not_implemented = 0b01100001, + message_type_not_compatible_with_the_protocol_state = 0b01100010, + information_element_non_existent_or_not_implemented = 0b01100011, + conditional_ie_error = 0b01100100, + message_not_compatible_with_the_protocol_state = 0b01100101, + protocol_error_unspecified = 0b01101111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated cause_5gmm_type; + + uint32_t length; + cause_5gmm_type cause_5gmm; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // cause_5gmm_t + +// IE: De-registration type +// Reference: 9.11.3.20 +class de_registration_type_t +{ +public: + struct switch_off_type_ { + enum options { + normal_de_registration = 0b0, + switch_off = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated switch_off_type; + + struct re_registration_required_type_ { + enum options { + re_registration_not_required = 0b0, + re_registration_required = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated re_registration_required_type; + + struct access_type_type_ { + enum options { + access_3_gpp = 0b01, + non_3_gpp_access = 0b10, + access_3_gpp_and_non_3_gpp_access = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated access_type_type; + + uint32_t length; + switch_off_type switch_off; + re_registration_required_type re_registration_required; + access_type_type access_type; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // de_registration_type_t + +// IE: Spare half octet +// Reference: 9.5 +class spare_half_octet_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // spare_half_octet_t + +// IE: Service type +// Reference: 9.11.3.50 +class service_type_t +{ +public: + struct Service_type_value_type_ { + enum options { + signalling = 0b0000, + data = 0b0001, + mobile_terminated_services = 0b0010, + emergency_services = 0b0011, + emergency_services_fallback = 0b0100, + high_priority_access = 0b0101, + elevated_signalling = 0b0110, + unused_shall_be_interpreted_as_signalling = 0b0111, + unused_shall_be_interpreted_as_signalling_1 = 0b1000, + unused_shall_be_interpreted_as_data = 0b1001, + unused_shall_be_interpreted_as_data_1 = 0b1010, + unused_shall_be_interpreted_as_data_2 = 0b1011, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Service_type_value_type; + + uint32_t length; + Service_type_value_type service_type_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // service_type_t + +// IE: Configuration update indication +// Reference: 9.11.3.18 +class configuration_update_indication_t +{ +public: + struct control_plane_service_type_value_type_ { + enum options { + mobile_originating_request = 0b000, + mobile_terminating_request = 0b001, + emergency_services = 0b010, + emergency_services_fallback = 0b100, + + } value; + const char* to_string(); + }; + typedef nas_enumerated control_plane_service_type_value_type; + + uint32_t length; + control_plane_service_type_value_type control_plane_service_type_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // configuration_update_indication_t + +// IE: Network name +// Reference: 9.11.3.35 +class network_name_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // network_name_t + +// IE: Time zone +// Reference: 9.11.3.52 +class time_zone_t +{ +public: + uint32_t length; + uint8_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t second; + uint8_t time_zone; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // time_zone_t + +// IE: Time zone and time +// Reference: 9.11.3.53 +class time_zone_and_time_t +{ +public: + uint32_t length; + uint8_t time_zone; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // time_zone_and_time_t + +// IE: Daylight saving time +// Reference: 9.11.3.19 +class daylight_saving_time_t +{ +public: + struct value_type_ { + enum options { + no_adjustment_for_daylight_saving_time = 0b00, + hour_1_adjustment_for_daylight_saving_time = 0b01, + hours_2_adjustment_for_daylight_saving_time = 0b10, + reserved = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated value_type; + + uint32_t length; + value_type value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // daylight_saving_time_t + +// IE: SMS indication +// Reference: 9.11.3.50A +class sms_indication_t +{ +public: + uint32_t length; + bool sms_availability_indication; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // sms_indication_t + +// IE: Additional configuration indication +// Reference: 9.11.3.74 +class additional_configuration_indication_t +{ +public: + struct SCMR_type_ { + enum options { + no_additional_information = 0b0, + release_of_n1_nas_signalling_connection_not_required = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated SCMR_type; + + uint32_t length; + SCMR_type scmr; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // additional_configuration_indication_t + +// IE: ABBA +// Reference: 9.11.3.10 +class abba_t +{ +public: + uint32_t length; + std::vector abba_contents; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // abba_t + +// IE: Authentication parameter RAND +// Reference: 9.11.3.16 +class authentication_parameter_rand_t +{ +public: + uint32_t length; + std::array rand; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_parameter_rand_t + +// IE: Authentication parameter AUTN +// Reference: 9.11.3.15 +class authentication_parameter_autn_t +{ +public: + uint32_t length; + std::vector autn; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_parameter_autn_t + +// IE: Authentication response parameter +// Reference: 9.11.3.17 +class authentication_response_parameter_t +{ +public: + uint32_t length; + std::vector res; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_response_parameter_t + +// IE: Authentication failure parameter +// Reference: 9.11.3.14 +class authentication_failure_parameter_t +{ +public: + uint32_t length; + std::vector auth_failure; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_failure_parameter_t + +// IE: 5GS identity type +// Reference: 9.11.3.3 +class identity_type_5gs_t +{ +public: + struct identity_types_ { + enum options { + suci = 0b001, + guti_5g = 0b010, + imei = 0b011, + s_tmsi_5g = 0b100, + imeisv = 0b101, + mac_address = 0b110, + eui_64 = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated identity_types; + + uint32_t length; + identity_types type_of_identity; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // identity_type_5gs_t + +// IE: security algorithms +// Reference: 9.11.3.34 +class security_algorithms_t +{ +public: + struct integrity_protection_algorithm_type_ { + enum options { + ia0_5g = 0b0000, + ia1_128_5g = 0b0001, + ia2_128_5g = 0b0010, + ia3_128_5g = 0b0011, + ia4_5g = 0b0100, + ia5_5g = 0b0101, + ia6_5g = 0b0110, + ia7_5g = 0b0111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated integrity_protection_algorithm_type; + + struct ciphering_algorithm_type_ { + enum options { + ea0_5g = 0b0000, + ea1_128_5g = 0b0001, + ea2_128_5g = 0b0010, + ea3_128_5g = 0b0011, + ea4_5g = 0b0100, + ea5_5g = 0b0101, + ea6_5g = 0b0110, + ea7_5g = 0b0111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated ciphering_algorithm_type; + + uint32_t length; + ciphering_algorithm_type ciphering_algorithm; + integrity_protection_algorithm_type integrity_protection_algorithm; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // security_algorithms_t + +// IE: IMEISV request +// Reference: 9.11.3.28 +class imeisv_request_t +{ +public: + struct imeisv_request_type_ { + enum options { + imeisv_not_requested = 0b000, + imeisv_requested = 0b001, + + } value; + const char* to_string(); + }; + typedef nas_enumerated imeisv_request_type; + + uint32_t length; + imeisv_request_type imeisv_request; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // imeisv_request_t + +// IE: EPS NAS security algorithms +// Reference: 9.11.3.25 +class eps_nas_security_algorithms_t +{ +public: + struct integrity_protection_algorithm_type_ { + enum options { + eia0 = 0b000, + eia1_128 = 0b001, + eia2_128 = 0b010, + eia3_128 = 0b011, + eia4 = 0b100, + eia5 = 0b101, + eia6 = 0b110, + eia7 = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated integrity_protection_algorithm_type; + + struct ciphering_algorithm_type_ { + enum options { + eea0 = 0b000, + eea1_128 = 0b001, + eea2_128 = 0b010, + eea3_128 = 0b011, + eea4 = 0b100, + eea5 = 0b101, + eea6 = 0b110, + eea7 = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated ciphering_algorithm_type; + + uint32_t length; + ciphering_algorithm_type ciphering_algorithm; + integrity_protection_algorithm_type integrity_protection_algorithm; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // eps_nas_security_algorithms_t + +// IE: Additional 5G security information +// Reference: 9.11.3.12 +class additional_5g_security_information_t +{ +public: + uint32_t length; + bool rinmr; + bool hdp; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // additional_5g_security_information_t + +// IE: S1 UE security capability +// Reference: 9.11.3.48A +class s1_ue_security_capability_t +{ +public: + uint32_t length; + bool eea0; + bool eea1_128; + bool eea2_128; + bool eea3_128; + bool eea4; + bool eea5; + bool eea6; + bool eea7; + bool eia0; + bool eia1_128; + bool eia2_128; + bool eia3_128; + bool eia4; + bool eia5; + bool eia6; + bool eia7; + bool uea0; + bool uea1; + bool uea2; + bool uea3; + bool uea4; + bool uea5; + bool uea6; + bool uea7; + bool uia1; + bool uia2; + bool uia3; + bool uia4; + bool uia5; + bool uia6; + bool uia7; + bool gea1; + bool gea2; + bool gea3; + bool gea4; + bool gea5; + bool gea6; + bool gea7; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // s1_ue_security_capability_t + +// IE: Access type +// Reference: 9.11.2.1A +class access_type_t +{ +public: + struct Access_type_value_type_ { + enum options { + access_3_gpp = 0b01, + non_3_gpp_access = 0b10, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Access_type_value_type; + + uint32_t length; + Access_type_value_type access_type_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // access_type_t + +// IE: PDU session identity 2 +// Reference: 9.11.3.41 +class pdu_session_identity_2_t +{ +public: + uint32_t length; + uint8_t pdu_session_identity_2_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_identity_2_t + +// IE: Request type +// Reference: 9.11.3.47 +class request_type_t +{ +public: + struct Request_type_value_type_ { + enum options { + initial_request = 0b001, + existing_pdu_session = 0b010, + initial_emergency_request = 0b011, + existing_emergency_pdu_session = 0b100, + modification_request = 0b101, + ma_pdu_request = 0b110, + reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Request_type_value_type; + + uint32_t length; + Request_type_value_type request_type_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // request_type_t + +// IE: Additional information +// Reference: 9.11.2.1 +class additional_information_t +{ +public: + uint32_t length; + std::vector additional_information_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // additional_information_t + +// IE: MA PDU session information +// Reference: 9.11.3.31A +class ma_pdu_session_information_t +{ +public: + struct MA_PDU_session_information_value_type_ { + enum options { + ma_pdu_session_network_upgrade_is_allowed = 0b0001, + + } value; + const char* to_string(); + }; + typedef nas_enumerated MA_PDU_session_information_value_type; + + uint32_t length; + MA_PDU_session_information_value_type ma_pdu_session_information_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ma_pdu_session_information_t + +// IE: Release assistance indication +// Reference: 9.11.3.46A +class release_assistance_indication_t +{ +public: + struct Downlink_data_expected_type_ { + enum options { + no_information_regarding_ddx_is_conveyed = 0b00, + no_further_uplink_and_no_further_downlink_data = 0b01, + only_a_single_downlink_data_transmission = 0b10, + reserved = 0b11, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Downlink_data_expected_type; + + uint32_t length; + Downlink_data_expected_type downlink_data_expected; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // release_assistance_indication_t + +// IE: Integrity protection maximum data rate +// Reference: 9.11.4.7 +class integrity_protection_maximum_data_rate_t +{ +public: + struct max_data_rate_UPIP_uplink_type_ { + enum options { + kbps_64 = 0b00000000, + null = 0b00000001, + full_data_rate = 0b11111111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated max_data_rate_UPIP_uplink_type; + + struct max_data_rate_UPIP_downlink_type_ { + enum options { + kbps_64 = 0b00000000, + null = 0b00000001, + full_data_rate = 0b11111111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated max_data_rate_UPIP_downlink_type; + + uint32_t length; + max_data_rate_UPIP_uplink_type max_data_rate_upip_uplink; + max_data_rate_UPIP_downlink_type max_data_rate_upip_downlink; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // integrity_protection_maximum_data_rate_t + +// IE: PDU session type +// Reference: 9.11.4.11 +class pdu_session_type_t +{ +public: + struct PDU_session_type_value_type_ { + enum options { + ipv4 = 0b001, + ipv6 = 0b010, + ipv4v6 = 0b011, + unstructured = 0b100, + ethernet = 0b101, + reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated PDU_session_type_value_type; + + uint32_t length; + PDU_session_type_value_type pdu_session_type_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_type_t + +// IE: SSC mode +// Reference: 9.11.4.16 +class ssc_mode_t +{ +public: + struct SSC_mode_value_type_ { + enum options { + ssc_mode_1 = 0b001, + ssc_mode_2 = 0b010, + ssc_mode_3 = 0b011, + unused_or_ssc_mode_1 = 0b100, + unused_or_ssc_mode_2 = 0b101, + unused_or_ssc_mode_3 = 0b110, + reserved = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated SSC_mode_value_type; + + uint32_t length; + SSC_mode_value_type ssc_mode_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ssc_mode_t + +// IE: 5GSM capability +// Reference: 9.11.4.1 +class capability_5gsm_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // capability_5gsm_t + +// IE: Maximum number of supported packet filters +// Reference: 9.11.4.9 +class maximum_number_of_supported_packet_filters_t +{ +public: + uint32_t length; + uint16_t maximum_number_of_supported_packet_filters; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // maximum_number_of_supported_packet_filters_t + +// IE: Always-on PDU session requested +// Reference: 9.11.4.4 +class always_on_pdu_session_requested_t +{ +public: + uint32_t length; + bool apsi; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // always_on_pdu_session_requested_t + +// IE: SM PDU DN request container +// Reference: 9.11.4.15 +class sm_pdu_dn_request_container_t +{ +public: + uint32_t length; + std::vector dn_specific_identity; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // sm_pdu_dn_request_container_t + +// IE: Extended protocol configuration options +// Reference: 9.11.4.6 +class extended_protocol_configuration_options_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // extended_protocol_configuration_options_t + +// IE: IP header compression configuration +// Reference: 9.11.4.24 +class ip_header_compression_configuration_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ip_header_compression_configuration_t + +// IE: DS-TT Ethernet port MAC address +// Reference: 9.11.4.25 +class ds_tt__ethernet_port_mac_address_t +{ +public: + uint32_t length; + std::array ds_tt__ethernet_port_mac_address_contents; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ds_tt__ethernet_port_mac_address_t + +// IE: UE-DS-TT residence time +// Reference: 9.11.4.26 +class ue_ds_tt_residence_time_t +{ +public: + uint32_t length; + std::array ue_ds_tt_residence_time_contents; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ue_ds_tt_residence_time_t + +// IE: Port management information container +// Reference: 9.11.4.27 +class port_management_information_container_t +{ +public: + uint32_t length; + std::vector port_management_information_container; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // port_management_information_container_t + +// IE: Ethernet header compression configuration +// Reference: 9.11.4.28 +class ethernet_header_compression_configuration_t +{ +public: + struct CID_Length_type_ { + enum options { + ethernet_header_compression_not_used = 0b00, + bits_7 = 0b01, + bits_15 = 0b10, + + } value; + const char* to_string(); + }; + typedef nas_enumerated CID_Length_type; + + uint32_t length; + CID_Length_type cid__length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ethernet_header_compression_configuration_t + +// IE: PDU address +// Reference: 9.11.4.10 +class pdu_address_t +{ +public: + struct PDU_session_type_value_type_ { + enum options { + ipv4 = 0b001, + ipv6 = 0b010, + ipv4v6 = 0b011, + + } value; + const char* to_string(); + }; + typedef nas_enumerated PDU_session_type_value_type; + + uint32_t length; + bool si6_lla; + PDU_session_type_value_type pdu_session_type_value; + std::array ipv4; + std::array ipv6; + std::array smf_i_pv6_link_local_address; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_address_t + +// IE: QoS rules +// Reference: 9.11.4.13 +class qo_s_rules_t +{ +public: + struct qos_rule_t {}; + uint32_t length; + std::vector qos_rules; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // qo_s_rules_t + +// IE: Session-AMBR +// Reference: 9.11.4.14 +class session_ambr_t +{ +public: + struct unit_session_AMBR_type_ { + enum options { + not_used = 0b00000000, + inc_by_1_kbps = 0b00000001, + inc_by_4_kbps = 0b00000010, + inc_by_16_kbps = 0b00000011, + inc_by_64_kbps = 0b00000100, + inc_by_256_kbps = 0b00000101, + inc_by_1_mbps = 0b00000110, + inc_by_4_mbps = 0b00000111, + inc_by_16_mbps = 0b00001000, + inc_by_64_mbps = 0b00001001, + inc_by_256_mbps = 0b00001010, + inc_by_1_gbps = 0b00001011, + inc_by_4_gbps = 0b00001100, + inc_by_16_gbps = 0b00001101, + inc_by_64_gbps = 0b00001110, + inc_by_256_gbps = 0b00001111, + inc_by_1_tbps = 0b00010000, + inc_by_4_tbps = 0b00010001, + inc_by_16_tbps = 0b00010010, + inc_by_64_tbps = 0b00010011, + inc_by_256_tbps = 0b00010100, + inc_by_1_pbps = 0b00010101, + inc_by_4_pbps = 0b00010110, + inc_by_16_pbps = 0b00010111, + inc_by_64_pbps = 0b00011000, + inc_by_256_pbps = 0b00011001, + + } value; + const char* to_string(); + }; + typedef nas_enumerated unit_session_AMBR_type; + + uint32_t length; + unit_session_AMBR_type unit_session_ambr_for_downlink; + uint16_t session_ambr_for_downlink; + unit_session_AMBR_type unit_session_ambr_for_uplink; + uint16_t session_ambr_for_uplink; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // session_ambr_t + +// IE: 5GSM cause +// Reference: 9.11.4.2 +class cause_5gsm_t +{ +public: + struct cause_value_type_ { + enum options { + operator_determined_barring = 0b00001000, + insufficient_resources = 0b00011010, + missing_or_unknown_dnn = 0b00011011, + unknown_pdu_session_type = 0b00011100, + user_authentication_or_authorization_failed = 0b00011101, + request_rejected_unspecified = 0b00011111, + service_option_not_supported = 0b00100000, + requested_service_option_not_subscribed = 0b00100001, + pti_already_in_use = 0b00100011, + regular_deactivation = 0b00100100, + network_failure = 0b00100110, + reactivation_requested = 0b00100111, + semantic_error_in_the_tft_operation = 0b00101001, + syntactical_error_in_the_tft_operation = 0b00101010, + invalid_pdu_session_identity = 0b00101011, + semantic_errors_in_packet_filter = 0b00101100, + syntactical_error_in_packet_filter = 0b00101101, + out_of_ladn_service_area = 0b00101110, + pti_mismatch = 0b00101111, + pdu_session_type_i_pv4_only_allowed = 0b00110010, + pdu_session_type_i_pv6_only_allowed = 0b00110011, + pdu_session_does_not_exist = 0b00110110, + pdu_session_type_i_pv4v6_only_allowed = 0b00111001, + pdu_session_type_unstructured_only_allowed = 0b00111010, + unsupported_5_qi_value = 0b00111011, + pdu_session_type_ethernet_only_allowed = 0b00111101, + insufficient_resources_for_specific_slice_and_dnn = 0b01000011, + not_supported_ssc_mode = 0b01000100, + insufficient_resources_for_specific_slice = 0b01000101, + missing_or_unknown_dnn_in_a_slice = 0b01000110, + invalid_pti_value = 0b01010001, + maximum_data_rate_per_ue_for_user_plane_integrity_protection_is_too_low = 0b01010010, + semantic_error_in_the_qo_s_operation = 0b01010011, + syntactical_error_in_the_qo_s_operation = 0b01010100, + invalid_mapped_eps_bearer_identity = 0b01010101, + semantically_incorrect_message = 0b01011111, + invalid_mandatory_information = 0b01100000, + message_type_non_existent_or_not_implemented = 0b01100001, + message_type_not_compatible_with_the_protocol_state = 0b01100010, + information_element_non_existent_or_not_implemented = 0b01100011, + conditional_ie_error = 0b01100100, + message_not_compatible_with_the_protocol_state = 0b01100101, + protocol_error_unspecified = 0b01101111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated cause_value_type; + + uint32_t length; + cause_value_type cause_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // cause_5gsm_t + +// IE: GPRS timer +// Reference: 9.11.2.3 +class gprs_timer_t +{ +public: + struct Unit_type_ { + enum options { + value_is_incremented_in_multiples_of_2_seconds = 0b000, + value_is_incremented_in_multiples_of_1_minute = 0b001, + value_is_incremented_in_multiples_of_decihours = 0b010, + value_indicates_that_the_timer_is_deactivated = 0b111, + + } value; + const char* to_string(); + }; + typedef nas_enumerated Unit_type; + + uint32_t length; + Unit_type unit; + uint8_t timer_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // gprs_timer_t + +// IE: Always-on PDU session indication +// Reference: 9.11.4.3 +class always_on_pdu_session_indication_t +{ +public: + uint32_t length; + bool apsr; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // always_on_pdu_session_indication_t + +// IE: Mapped EPS bearer contexts +// Reference: 9.11.4.8 +class mapped_eps_bearer_contexts_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // mapped_eps_bearer_contexts_t + +// IE: QoS flow descriptions +// Reference: 9.11.4.12 +class qo_s_flow_descriptions_t +{ +public: + uint32_t length; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // qo_s_flow_descriptions_t + +// IE: 5GSM network feature support +// Reference: 9.11.4.18 +class network_feature_support_5gsm_t +{ +public: + struct EPT_S1_type_ { + enum options { + ethernet_pdn_type_in_s1_mode_not_supported = 0b0, + ethernet_pdn_type_in_s1_mode_supported = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated EPT_S1_type; + + uint32_t length; + EPT_S1_type ept_s1; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // network_feature_support_5gsm_t + +// IE: Serving PLMN rate control +// Reference: 9.11.4.20 +class serving_plmn_rate_control_t +{ +public: + uint32_t length; + uint16_t serving_plmn_rate_control_value; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // serving_plmn_rate_control_t + +// IE: ATSSS container +// Reference: 9.11.4.22 +class atsss_container_t +{ +public: + uint32_t length; + std::vector nas_message_container; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // atsss_container_t + +// IE: Control plane only indication +// Reference: 9.11.4.23 +class control_plane_only_indication_t +{ +public: + uint32_t length; + bool cpoi; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // control_plane_only_indication_t + +// IE: Allowed SSC mode +// Reference: 9.11.4.5 +class allowed_ssc_mode_t +{ +public: + uint32_t length; + bool ssc3; + bool ssc2; + bool ssc1; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // allowed_ssc_mode_t + +// IE: 5GSM congestion re-attempt indicator +// Reference: 9.11.4.21 +class congestion_re_attempt_indicator_5gsm_t +{ +public: + struct abo_type_ { + enum options { + the_back_off_timer_is_applied_in_the_registered_plmn = 0b0, + the_back_off_timer_is_applied_in_all_plm_ns = 0b1, + + } value; + const char* to_string(); + }; + typedef nas_enumerated abo_type; + + uint32_t length; + abo_type abo; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // congestion_re_attempt_indicator_5gsm_t + +// IE: Re-attempt indicator +// Reference: 9.11.4.17 +class re_attempt_indicator_t +{ +public: + uint32_t length; + bool eplmnc; + bool ratc; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // re_attempt_indicator_t + +} // namespace nas_5g +} // namespace srsran +#endif diff --git a/lib/include/srsran/asn1/nas_5g_msg.h b/lib/include/srsran/asn1/nas_5g_msg.h new file mode 100644 index 000000000..cdf7225fe --- /dev/null +++ b/lib/include/srsran/asn1/nas_5g_msg.h @@ -0,0 +1,2390 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#ifndef SRSRAN_NAS_5G_MSG_H +#define SRSRAN_NAS_5G_MSG_H +#include "nas_5g_ies.h" +#include "nas_5g_utils.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/config.h" + +#include +#include +#include + +namespace srsran { +namespace nas_5g { + +/* + * Message: Registration request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class registration_request_t +{ +public: + // Mandatory fields + registration_type_5gs_t registration_type_5gs; + key_set_identifier_t ng_ksi; + mobile_identity_5gs_t mobile_identity_5gs; + + // Optional fields + bool non_current_native_nas_key_set_identifier_present = false; + bool capability_5gmm_present = false; + bool ue_security_capability_present = false; + bool requested_nssai_present = false; + bool last_visited_registered_tai_present = false; + bool s1_ue_network_capability_present = false; + bool uplink_data_status_present = false; + bool pdu_session_status_present = false; + bool mico_indication_present = false; + bool ue_status_present = false; + bool additional_guti_present = false; + bool allowed_pdu_session_status_present = false; + bool ue_usage_setting_present = false; + bool requested_drx_parameters_present = false; + bool eps_nas_message_container_present = false; + bool ladn_indication_present = false; + bool payload_container_type_present = false; + bool payload_container_present = false; + bool network_slicing_indication_present = false; + bool update_type_5gs_present = false; + bool mobile_station_classmark_2_present = false; + bool supported_codecs_present = false; + bool nas_message_container_present = false; + bool eps_bearer_context_status_present = false; + bool requested_extended_drx_parameters_present = false; + bool t3324_value_present = false; + bool ue_radio_capability_id_present = false; + bool requested_mapped_nssai_present = false; + bool additional_information_requested_present = false; + bool requested_wus_assistance_information_present = false; + bool n5gc_indication_present = false; + bool requested_nb_n1_mode_drx_parameters_present = false; + + key_set_identifier_t non_current_native_nas_key_set_identifier; + capability_5gmm_t capability_5gmm; + ue_security_capability_t ue_security_capability; + nssai_t requested_nssai; + tracking_area_identity_5gs_t last_visited_registered_tai; + s1_ue_network_capability_t s1_ue_network_capability; + uplink_data_status_t uplink_data_status; + pdu_session_status_t pdu_session_status; + mico_indication_t mico_indication; + ue_status_t ue_status; + mobile_identity_5gs_t additional_guti; + allowed_pdu_session_status_t allowed_pdu_session_status; + ue_usage_setting_t ue_usage_setting; + drx_parameters_5gs_t requested_drx_parameters; + eps_nas_message_container_t eps_nas_message_container; + ladn_indication_t ladn_indication; + payload_container_type_t payload_container_type; + payload_container_t payload_container; + network_slicing_indication_t network_slicing_indication; + update_type_5gs_t update_type_5gs; + mobile_station_classmark_2_t mobile_station_classmark_2; + supported_codec_list_t supported_codecs; + message_container_t nas_message_container; + eps_bearer_context_status_t eps_bearer_context_status; + extended_drx_parameters_t requested_extended_drx_parameters; + gprs_timer_3_t t3324_value; + ue_radio_capability_id_t ue_radio_capability_id; + mapped_nssai_t requested_mapped_nssai; + additional_information_requested_t additional_information_requested; + wus_assistance_information_t requested_wus_assistance_information; + n5gc_indication_t n5gc_indication; + nb_n1_mode_drx_parameters_t requested_nb_n1_mode_drx_parameters; + + const static uint8_t ie_iei_non_current_native_nas_key_set_identifier = 0xC; + const static uint8_t ie_iei_capability_5gmm = 0x10; + const static uint8_t ie_iei_ue_security_capability = 0x2E; + const static uint8_t ie_iei_requested_nssai = 0x2F; + const static uint8_t ie_iei_last_visited_registered_tai = 0x52; + const static uint8_t ie_iei_s1_ue_network_capability = 0x17; + const static uint8_t ie_iei_uplink_data_status = 0x40; + const static uint8_t ie_iei_pdu_session_status = 0x50; + const static uint8_t ie_iei_mico_indication = 0xB; + const static uint8_t ie_iei_ue_status = 0x2B; + const static uint8_t ie_iei_additional_guti = 0x77; + const static uint8_t ie_iei_allowed_pdu_session_status = 0x25; + const static uint8_t ie_iei_ue_usage_setting = 0x18; + const static uint8_t ie_iei_requested_drx_parameters = 0x51; + const static uint8_t ie_iei_eps_nas_message_container = 0x70; + const static uint8_t ie_iei_ladn_indication = 0x74; + const static uint8_t ie_iei_payload_container_type = 0x8; + const static uint8_t ie_iei_payload_container = 0x7B; + const static uint8_t ie_iei_network_slicing_indication = 0x9; + const static uint8_t ie_iei_update_type_5gs = 0x53; + const static uint8_t ie_iei_mobile_station_classmark_2 = 0x41; + const static uint8_t ie_iei_supported_codecs = 0x42; + const static uint8_t ie_iei_nas_message_container = 0x71; + const static uint8_t ie_iei_eps_bearer_context_status = 0x60; + const static uint8_t ie_iei_requested_extended_drx_parameters = 0x6E; + const static uint8_t ie_iei_t3324_value = 0x6A; + const static uint8_t ie_iei_ue_radio_capability_id = 0x67; + const static uint8_t ie_iei_requested_mapped_nssai = 0x35; + const static uint8_t ie_iei_additional_information_requested = 0x48; + const static uint8_t ie_iei_requested_wus_assistance_information = 0x1A; + const static uint8_t ie_iei_n5gc_indication = 0xA; + const static uint8_t ie_iei_requested_nb_n1_mode_drx_parameters = 0x30; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_request_t + +/* + * Message: Registration accept. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class registration_accept_t +{ +public: + // Mandatory fields + registration_result_5gs_t registration_result_5gs; + + // Optional fields + bool guti_5g_present = false; + bool equivalent_plm_ns_present = false; + bool tai_list_present = false; + bool allowed_nssai_present = false; + bool rejected_nssai_present = false; + bool configured_nssai_present = false; + bool network_feature_support_5gs_present = false; + bool pdu_session_status_present = false; + bool pdu_session_reactivation_result_present = false; + bool pdu_session_reactivation_result_error_cause_present = false; + bool ladn_information_present = false; + bool mico_indication_present = false; + bool network_slicing_indication_present = false; + bool service_area_list_present = false; + bool t3512_value_present = false; + bool non_3_gpp_de_registration_timer_value_present = false; + bool t3502_value_present = false; + bool emergency_number_list_present = false; + bool extended_emergency_number_list_present = false; + bool sor_transparent_container_present = false; + bool eap_message_present = false; + bool nssai_inclusion_mode_present = false; + bool operator_defined_access_category_definitions_present = false; + bool negotiated_drx_parameters_present = false; + bool non_3_gpp_nw_policies_present = false; + bool eps_bearer_context_status_present = false; + bool negotiated_extended_drx_parameters_present = false; + bool t3447_value_present = false; + bool t3448_value_present = false; + bool t3324_value_present = false; + bool ue_radio_capability_id_present = false; + bool ue_radio_capability_id_deletion_indication_present = false; + bool pending_nssai_present = false; + bool ciphering_key_data_present = false; + bool cag_information_list_present = false; + bool truncated_5g_s_tmsi_configuration_present = false; + bool negotiated_wus_assistance_information_present = false; + bool negotiated_nb_n1_mode_drx_parameters_present = false; + + mobile_identity_5gs_t guti_5g; + plmn_list_t equivalent_plm_ns; + tracking_area_identity_list_5gs_t tai_list; + nssai_t allowed_nssai; + rejected_nssai_t rejected_nssai; + nssai_t configured_nssai; + network_feature_support_5gs_t network_feature_support_5gs; + pdu_session_status_t pdu_session_status; + pdu_session_reactivation_result_t pdu_session_reactivation_result; + pdu_session_reactivation_result_error_cause_t pdu_session_reactivation_result_error_cause; + ladn_information_t ladn_information; + mico_indication_t mico_indication; + network_slicing_indication_t network_slicing_indication; + service_area_list_t service_area_list; + gprs_timer_3_t t3512_value; + gprs_timer_2_t non_3_gpp_de_registration_timer_value; + gprs_timer_2_t t3502_value; + emergency_number_list_t emergency_number_list; + extended_emergency_number_list_t extended_emergency_number_list; + sor_transparent_container_t sor_transparent_container; + eap_message_t eap_message; + nssai_inclusion_mode_t nssai_inclusion_mode; + operator_defined_access_category_definitions_t operator_defined_access_category_definitions; + drx_parameters_5gs_t negotiated_drx_parameters; + non_3_gpp_nw_provided_policies_t non_3_gpp_nw_policies; + eps_bearer_context_status_t eps_bearer_context_status; + extended_drx_parameters_t negotiated_extended_drx_parameters; + gprs_timer_3_t t3447_value; + gprs_timer_2_t t3448_value; + gprs_timer_3_t t3324_value; + ue_radio_capability_id_t ue_radio_capability_id; + ue_radio_capability_id_deletion_indication_t ue_radio_capability_id_deletion_indication; + nssai_t pending_nssai; + ciphering_key_data_t ciphering_key_data; + cag_information_list_t cag_information_list; + truncated_5g_s_tmsi_configuration_t truncated_5g_s_tmsi_configuration; + wus_assistance_information_t negotiated_wus_assistance_information; + nb_n1_mode_drx_parameters_t negotiated_nb_n1_mode_drx_parameters; + + const static uint8_t ie_iei_guti_5g = 0x77; + const static uint8_t ie_iei_equivalent_plm_ns = 0x4A; + const static uint8_t ie_iei_tai_list = 0x54; + const static uint8_t ie_iei_allowed_nssai = 0x15; + const static uint8_t ie_iei_rejected_nssai = 0x11; + const static uint8_t ie_iei_configured_nssai = 0x31; + const static uint8_t ie_iei_network_feature_support_5gs = 0x21; + const static uint8_t ie_iei_pdu_session_status = 0x50; + const static uint8_t ie_iei_pdu_session_reactivation_result = 0x26; + const static uint8_t ie_iei_pdu_session_reactivation_result_error_cause = 0x72; + const static uint8_t ie_iei_ladn_information = 0x79; + const static uint8_t ie_iei_mico_indication = 0xB; + const static uint8_t ie_iei_network_slicing_indication = 0x9; + const static uint8_t ie_iei_service_area_list = 0x27; + const static uint8_t ie_iei_t3512_value = 0x5E; + const static uint8_t ie_iei_non_3_gpp_de_registration_timer_value = 0x5D; + const static uint8_t ie_iei_t3502_value = 0x16; + const static uint8_t ie_iei_emergency_number_list = 0x34; + const static uint8_t ie_iei_extended_emergency_number_list = 0x7A; + const static uint8_t ie_iei_sor_transparent_container = 0x73; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_nssai_inclusion_mode = 0xA; + const static uint8_t ie_iei_operator_defined_access_category_definitions = 0x76; + const static uint8_t ie_iei_negotiated_drx_parameters = 0x51; + const static uint8_t ie_iei_non_3_gpp_nw_policies = 0xD; + const static uint8_t ie_iei_eps_bearer_context_status = 0x60; + const static uint8_t ie_iei_negotiated_extended_drx_parameters = 0x6E; + const static uint8_t ie_iei_t3447_value = 0x6C; + const static uint8_t ie_iei_t3448_value = 0x6B; + const static uint8_t ie_iei_t3324_value = 0x6A; + const static uint8_t ie_iei_ue_radio_capability_id = 0x67; + const static uint8_t ie_iei_ue_radio_capability_id_deletion_indication = 0xE; + const static uint8_t ie_iei_pending_nssai = 0x39; + const static uint8_t ie_iei_ciphering_key_data = 0x74; + const static uint8_t ie_iei_cag_information_list = 0x75; + const static uint8_t ie_iei_truncated_5g_s_tmsi_configuration = 0x1B; + const static uint8_t ie_iei_negotiated_wus_assistance_information = 0x1C; + const static uint8_t ie_iei_negotiated_nb_n1_mode_drx_parameters = 0x29; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_accept_t + +/* + * Message: Registration complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class registration_complete_t +{ +public: + // Mandatory fields + + // Optional fields + bool sor_transparent_container_present = false; + + sor_transparent_container_t sor_transparent_container; + + const static uint8_t ie_iei_sor_transparent_container = 0x73; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_complete_t + +/* + * Message: Registration reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class registration_reject_t +{ +public: + // Mandatory fields + cause_5gmm_t cause_5gmm; + + // Optional fields + bool t3346_value_present = false; + bool t3502_value_present = false; + bool eap_message_present = false; + bool rejected_nssai_present = false; + bool cag_information_list_present = false; + + gprs_timer_2_t t3346_value; + gprs_timer_2_t t3502_value; + eap_message_t eap_message; + rejected_nssai_t rejected_nssai; + cag_information_list_t cag_information_list; + + const static uint8_t ie_iei_t3346_value = 0x5F; + const static uint8_t ie_iei_t3502_value = 0x16; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_rejected_nssai = 0x69; + const static uint8_t ie_iei_cag_information_list = 0x75; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // registration_reject_t + +/* + * Message: Deregistration request UE originating. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class deregistration_request_ue_originating_t +{ +public: + // Mandatory fields + de_registration_type_t de_registration_type; + key_set_identifier_t ng_ksi; + mobile_identity_5gs_t mobile_identity_5gs; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // deregistration_request_ue_originating_t + +/* + * Message: Deregistration accept UE originating. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class deregistration_accept_ue_originating_t +{ +public: + // Mandatory fields + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // deregistration_accept_ue_originating_t + +/* + * Message: Deregistration request UE terminated. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class deregistration_request_ue_terminated_t +{ +public: + // Mandatory fields + de_registration_type_t de_registration_type; + spare_half_octet_t spare_half_octet; + + // Optional fields + bool cause_5gmm_present = false; + bool t3346_value_present = false; + bool rejected_nssai_present = false; + bool cag_information_list_present = false; + + cause_5gmm_t cause_5gmm; + gprs_timer_2_t t3346_value; + rejected_nssai_t rejected_nssai; + cag_information_list_t cag_information_list; + + const static uint8_t ie_iei_cause_5gmm = 0x58; + const static uint8_t ie_iei_t3346_value = 0x5F; + const static uint8_t ie_iei_rejected_nssai = 0x6D; + const static uint8_t ie_iei_cag_information_list = 0x75; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // deregistration_request_ue_terminated_t + +/* + * Message: Deregistration accept UE terminated. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class deregistration_accept_ue_terminated_t +{ +public: + // Mandatory fields + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // deregistration_accept_ue_terminated_t + +/* + * Message: Service request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class service_request_t +{ +public: + // Mandatory fields + key_set_identifier_t ng_ksi; + service_type_t service_type; + mobile_identity_5gs_t s_tmsi_5g; + + // Optional fields + bool uplink_data_status_present = false; + bool pdu_session_status_present = false; + bool allowed_pdu_session_status_present = false; + bool nas_message_container_present = false; + + uplink_data_status_t uplink_data_status; + pdu_session_status_t pdu_session_status; + allowed_pdu_session_status_t allowed_pdu_session_status; + message_container_t nas_message_container; + + const static uint8_t ie_iei_uplink_data_status = 0x40; + const static uint8_t ie_iei_pdu_session_status = 0x50; + const static uint8_t ie_iei_allowed_pdu_session_status = 0x25; + const static uint8_t ie_iei_nas_message_container = 0x71; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // service_request_t + +/* + * Message: Service reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class service_reject_t +{ +public: + // Mandatory fields + + // Optional fields + bool pdu_session_status_present = false; + bool pdu_session_reactivation_result_present = false; + bool pdu_session_reactivation_result_error_cause_present = false; + bool eap_message_present = false; + bool t3448_value_present = false; + + pdu_session_status_t pdu_session_status; + pdu_session_reactivation_result_t pdu_session_reactivation_result; + pdu_session_reactivation_result_error_cause_t pdu_session_reactivation_result_error_cause; + eap_message_t eap_message; + gprs_timer_2_t t3448_value; + + const static uint8_t ie_iei_pdu_session_status = 0x50; + const static uint8_t ie_iei_pdu_session_reactivation_result = 0x26; + const static uint8_t ie_iei_pdu_session_reactivation_result_error_cause = 0x72; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_t3448_value = 0x6B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // service_reject_t + +/* + * Message: Service accept. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class service_accept_t +{ +public: + // Mandatory fields + cause_5gmm_t cause_5gmm; + + // Optional fields + bool pdu_session_status_present = false; + bool t3346_value_present = false; + bool eap_message_present = false; + bool t3448_value_present = false; + bool cag_information_list_present = false; + + pdu_session_status_t pdu_session_status; + gprs_timer_2_t t3346_value; + eap_message_t eap_message; + gprs_timer_2_t t3448_value; + cag_information_list_t cag_information_list; + + const static uint8_t ie_iei_pdu_session_status = 0x50; + const static uint8_t ie_iei_t3346_value = 0x5F; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_t3448_value = 0x6B; + const static uint8_t ie_iei_cag_information_list = 0x75; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // service_accept_t + +/* + * Message: Configuration update command. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class configuration_update_command_t +{ +public: + // Mandatory fields + + // Optional fields + bool configuration_update_indication_present = false; + bool guti_5g_present = false; + bool tai_list_present = false; + bool allowed_nssai_present = false; + bool service_area_list_present = false; + bool full_name_for_network_present = false; + bool short_name_for_network_present = false; + bool local_time_zone_present = false; + bool universal_time_and_local_time_zone_present = false; + bool network_daylight_saving_time_present = false; + bool ladn_information_present = false; + bool mico_indication_present = false; + bool network_slicing_indication_present = false; + bool configured_nssai_present = false; + bool rejected_nssai_present = false; + bool operator_defined_access_category_definitions_present = false; + bool sms_indication_present = false; + bool t3447_value_present = false; + bool cag_information_list_present = false; + bool ue_radio_capability_id_present = false; + bool ue_radio_capability_id_deletion_indication_present = false; + bool registration_result_5gs_present = false; + bool truncated_5g_s_tmsi_configuration_present = false; + bool additional_configuration_indication_present = false; + + configuration_update_indication_t configuration_update_indication; + mobile_identity_5gs_t guti_5g; + tracking_area_identity_list_5gs_t tai_list; + nssai_t allowed_nssai; + service_area_list_t service_area_list; + network_name_t full_name_for_network; + network_name_t short_name_for_network; + time_zone_t local_time_zone; + time_zone_and_time_t universal_time_and_local_time_zone; + daylight_saving_time_t network_daylight_saving_time; + ladn_information_t ladn_information; + mico_indication_t mico_indication; + network_slicing_indication_t network_slicing_indication; + nssai_t configured_nssai; + rejected_nssai_t rejected_nssai; + operator_defined_access_category_definitions_t operator_defined_access_category_definitions; + sms_indication_t sms_indication; + gprs_timer_3_t t3447_value; + cag_information_list_t cag_information_list; + ue_radio_capability_id_t ue_radio_capability_id; + ue_radio_capability_id_deletion_indication_t ue_radio_capability_id_deletion_indication; + registration_result_5gs_t registration_result_5gs; + truncated_5g_s_tmsi_configuration_t truncated_5g_s_tmsi_configuration; + additional_configuration_indication_t additional_configuration_indication; + + const static uint8_t ie_iei_configuration_update_indication = 0xD; + const static uint8_t ie_iei_guti_5g = 0x77; + const static uint8_t ie_iei_tai_list = 0x54; + const static uint8_t ie_iei_allowed_nssai = 0x15; + const static uint8_t ie_iei_service_area_list = 0x27; + const static uint8_t ie_iei_full_name_for_network = 0x43; + const static uint8_t ie_iei_short_name_for_network = 0x45; + const static uint8_t ie_iei_local_time_zone = 0x46; + const static uint8_t ie_iei_universal_time_and_local_time_zone = 0x47; + const static uint8_t ie_iei_network_daylight_saving_time = 0x49; + const static uint8_t ie_iei_ladn_information = 0x79; + const static uint8_t ie_iei_mico_indication = 0xB; + const static uint8_t ie_iei_network_slicing_indication = 0x9; + const static uint8_t ie_iei_configured_nssai = 0x31; + const static uint8_t ie_iei_rejected_nssai = 0x11; + const static uint8_t ie_iei_operator_defined_access_category_definitions = 0x76; + const static uint8_t ie_iei_sms_indication = 0xF; + const static uint8_t ie_iei_t3447_value = 0x6C; + const static uint8_t ie_iei_cag_information_list = 0x75; + const static uint8_t ie_iei_ue_radio_capability_id = 0x67; + const static uint8_t ie_iei_ue_radio_capability_id_deletion_indication = 0xA; + const static uint8_t ie_iei_registration_result_5gs = 0x44; + const static uint8_t ie_iei_truncated_5g_s_tmsi_configuration = 0x1B; + const static uint8_t ie_iei_additional_configuration_indication = 0xC; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // configuration_update_command_t + +/* + * Message: Configuration update complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class configuration_update_complete_t +{ +public: + // Mandatory fields + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // configuration_update_complete_t + +/* + * Message: Authentication request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class authentication_request_t +{ +public: + // Mandatory fields + key_set_identifier_t ng_ksi; + spare_half_octet_t spare_half_octet; + abba_t abba; + + // Optional fields + bool authentication_parameter_rand_present = false; + bool authentication_parameter_autn_present = false; + bool eap_message_present = false; + + authentication_parameter_rand_t authentication_parameter_rand; + authentication_parameter_autn_t authentication_parameter_autn; + eap_message_t eap_message; + + const static uint8_t ie_iei_authentication_parameter_rand = 0x21; + const static uint8_t ie_iei_authentication_parameter_autn = 0x20; + const static uint8_t ie_iei_eap_message = 0x78; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_request_t + +/* + * Message: Authentication response. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class authentication_response_t +{ +public: + // Mandatory fields + + // Optional fields + bool authentication_response_parameter_present = false; + bool eap_message_present = false; + + authentication_response_parameter_t authentication_response_parameter; + eap_message_t eap_message; + + const static uint8_t ie_iei_authentication_response_parameter = 0x2D; + const static uint8_t ie_iei_eap_message = 0x78; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_response_t + +/* + * Message: Authentication reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class authentication_reject_t +{ +public: + // Mandatory fields + + // Optional fields + bool eap_message_present = false; + + eap_message_t eap_message; + + const static uint8_t ie_iei_eap_message = 0x78; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_reject_t + +/* + * Message: Authentication failure. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class authentication_failure_t +{ +public: + // Mandatory fields + cause_5gmm_t cause_5gmm; + + // Optional fields + bool authentication_failure_parameter_present = false; + + authentication_failure_parameter_t authentication_failure_parameter; + + const static uint8_t ie_iei_authentication_failure_parameter = 0x30; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_failure_t + +/* + * Message: Authentication result. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class authentication_result_t +{ +public: + // Mandatory fields + key_set_identifier_t ng_ksi; + spare_half_octet_t spare_half_octet; + eap_message_t eap_message; + + // Optional fields + bool abba_present = false; + + abba_t abba; + + const static uint8_t ie_iei_abba = 0x38; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // authentication_result_t + +/* + * Message: Identity request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class identity_request_t +{ +public: + // Mandatory fields + identity_type_5gs_t identity_type; + spare_half_octet_t spare_half_octet; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // identity_request_t + +/* + * Message: Identity response. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class identity_response_t +{ +public: + // Mandatory fields + mobile_identity_5gs_t mobile_identity; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // identity_response_t + +/* + * Message: Security mode command. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class security_mode_command_t +{ +public: + // Mandatory fields + security_algorithms_t selected_nas_security_algorithms; + key_set_identifier_t ng_ksi; + spare_half_octet_t spare_half_octet; + ue_security_capability_t replayed_ue_security_capabilities; + + // Optional fields + bool imeisv_request_present = false; + bool selected_eps_nas_security_algorithms_present = false; + bool additional_5g_security_information_present = false; + bool eap_message_present = false; + bool abba_present = false; + bool replayed_s1_ue_security_capabilities_present = false; + + imeisv_request_t imeisv_request; + eps_nas_security_algorithms_t selected_eps_nas_security_algorithms; + additional_5g_security_information_t additional_5g_security_information; + eap_message_t eap_message; + abba_t abba; + s1_ue_security_capability_t replayed_s1_ue_security_capabilities; + + const static uint8_t ie_iei_imeisv_request = 0xE; + const static uint8_t ie_iei_selected_eps_nas_security_algorithms = 0x57; + const static uint8_t ie_iei_additional_5g_security_information = 0x36; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_abba = 0x38; + const static uint8_t ie_iei_replayed_s1_ue_security_capabilities = 0x19; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // security_mode_command_t + +/* + * Message: Security mode complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class security_mode_complete_t +{ +public: + // Mandatory fields + + // Optional fields + bool imeisv_present = false; + bool nas_message_container_present = false; + bool non_imeisv_pei_present = false; + + mobile_identity_5gs_t imeisv; + message_container_t nas_message_container; + mobile_identity_5gs_t non_imeisv_pei; + + const static uint8_t ie_iei_imeisv = 0x77; + const static uint8_t ie_iei_nas_message_container = 0x71; + const static uint8_t ie_iei_non_imeisv_pei = 0x78; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // security_mode_complete_t + +/* + * Message: Security mode reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class security_mode_reject_t +{ +public: + // Mandatory fields + cause_5gmm_t cause_5gmm; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // security_mode_reject_t + +/* + * Message: Status 5GMM. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class status_5gmm_t +{ +public: + // Mandatory fields + cause_5gmm_t cause_5gmm; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // status_5gmm_t + +/* + * Message: Notification. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class notification_t +{ +public: + // Mandatory fields + access_type_t access_type; + spare_half_octet_t spare_half_octet; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // notification_t + +/* + * Message: Notification response. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class notification_response_t +{ +public: + // Mandatory fields + + // Optional fields + bool pdu_session_status_present = false; + + pdu_session_status_t pdu_session_status; + + const static uint8_t ie_iei_pdu_session_status = 0x50; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // notification_response_t + +/* + * Message: UL NAS transport. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class ul_nas_transport_t +{ +public: + // Mandatory fields + payload_container_type_t payload_container_type; + spare_half_octet_t spare_half_octet; + payload_container_t payload_container; + + // Optional fields + bool pdu_session_id_present = false; + bool old_pdu_session_id_present = false; + bool request_type_present = false; + bool s_nssai_present = false; + bool dnn_present = false; + bool additional_information_present = false; + bool ma_pdu_session_information_present = false; + bool release_assistance_indication_present = false; + + pdu_session_identity_2_t pdu_session_id; + pdu_session_identity_2_t old_pdu_session_id; + request_type_t request_type; + s_nssai_t s_nssai; + dnn_t dnn; + additional_information_t additional_information; + ma_pdu_session_information_t ma_pdu_session_information; + release_assistance_indication_t release_assistance_indication; + + const static uint8_t ie_iei_pdu_session_id = 0x12; + const static uint8_t ie_iei_old_pdu_session_id = 0x59; + const static uint8_t ie_iei_request_type = 0x8; + const static uint8_t ie_iei_s_nssai = 0x22; + const static uint8_t ie_iei_dnn = 0x25; + const static uint8_t ie_iei_additional_information = 0x24; + const static uint8_t ie_iei_ma_pdu_session_information = 0xA; + const static uint8_t ie_iei_release_assistance_indication = 0xF; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // ul_nas_transport_t + +/* + * Message: DL NAS transport . + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class dl_nas_transport_t +{ +public: + // Mandatory fields + payload_container_type_t payload_container_type; + spare_half_octet_t spare_half_octet; + payload_container_t payload_container; + + // Optional fields + bool pdu_session_id_present = false; + bool additional_information_present = false; + bool cause_5gmm_present = false; + bool back_off_timer_value_present = false; + + pdu_session_identity_2_t pdu_session_id; + additional_information_t additional_information; + cause_5gmm_t cause_5gmm; + gprs_timer_3_t back_off_timer_value; + + const static uint8_t ie_iei_pdu_session_id = 0x12; + const static uint8_t ie_iei_additional_information = 0x24; + const static uint8_t ie_iei_cause_5gmm = 0x58; + const static uint8_t ie_iei_back_off_timer_value = 0x37; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // dl_nas_transport_t + +/* + * Message: PDU session establishment request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_establishment_request_t +{ +public: + // Mandatory fields + integrity_protection_maximum_data_rate_t integrity_protection_maximum_data_rate; + + // Optional fields + bool pdu_session_type_present = false; + bool ssc_mode_present = false; + bool capability_5gsm_present = false; + bool maximum_number_of_supported_packet_filters_present = false; + bool always_on_pdu_session_requested_present = false; + bool sm_pdu_dn_request_container_present = false; + bool extended_protocol_configuration_options_present = false; + bool ip_header_compression_configuration_present = false; + bool ds_tt__ethernet_port_mac_address_present = false; + bool ue_ds_tt_residence_time_present = false; + bool port_management_information_container_present = false; + bool ethernet_header_compression_configuration_present = false; + bool suggested_interface_identifier_present = false; + + pdu_session_type_t pdu_session_type; + ssc_mode_t ssc_mode; + capability_5gsm_t capability_5gsm; + maximum_number_of_supported_packet_filters_t maximum_number_of_supported_packet_filters; + always_on_pdu_session_requested_t always_on_pdu_session_requested; + sm_pdu_dn_request_container_t sm_pdu_dn_request_container; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + ip_header_compression_configuration_t ip_header_compression_configuration; + ds_tt__ethernet_port_mac_address_t ds_tt__ethernet_port_mac_address; + ue_ds_tt_residence_time_t ue_ds_tt_residence_time; + port_management_information_container_t port_management_information_container; + ethernet_header_compression_configuration_t ethernet_header_compression_configuration; + pdu_address_t suggested_interface_identifier; + + const static uint8_t ie_iei_pdu_session_type = 0x9; + const static uint8_t ie_iei_ssc_mode = 0xA; + const static uint8_t ie_iei_capability_5gsm = 0x28; + const static uint8_t ie_iei_maximum_number_of_supported_packet_filters = 0x55; + const static uint8_t ie_iei_always_on_pdu_session_requested = 0xB; + const static uint8_t ie_iei_sm_pdu_dn_request_container = 0x39; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_ip_header_compression_configuration = 0x66; + const static uint8_t ie_iei_ds_tt__ethernet_port_mac_address = 0x6E; + const static uint8_t ie_iei_ue_ds_tt_residence_time = 0x6F; + const static uint8_t ie_iei_port_management_information_container = 0x74; + const static uint8_t ie_iei_ethernet_header_compression_configuration = 0x1F; + const static uint8_t ie_iei_suggested_interface_identifier = 0x29; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_establishment_request_t + +/* + * Message: PDU session establishment accept. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_establishment_accept_t +{ +public: + // Mandatory fields + pdu_session_type_t selected_pdu_session_type; + ssc_mode_t selected_ssc_mode; + qo_s_rules_t authorized__qo_s_rules; + session_ambr_t session_ambr; + + // Optional fields + bool cause_5gsm_present = false; + bool pdu_address_present = false; + bool rq_timer_value_present = false; + bool s_nssai_present = false; + bool always_on_pdu_session_indication_present = false; + bool mapped_eps_bearer_contexts_present = false; + bool eap_message_present = false; + bool authorized__qo_s_flow_descriptions_present = false; + bool extended_protocol_configuration_options_present = false; + bool dnn_present = false; + bool network_feature_support_5gsm_present = false; + bool serving_plmn_rate_control_present = false; + bool atsss_container_present = false; + bool control_plane_only_indication_present = false; + bool ip_header_compression_configuration_present = false; + bool ethernet_header_compression_configuration_present = false; + + cause_5gsm_t cause_5gsm; + pdu_address_t pdu_address; + gprs_timer_t rq_timer_value; + s_nssai_t s_nssai; + always_on_pdu_session_indication_t always_on_pdu_session_indication; + mapped_eps_bearer_contexts_t mapped_eps_bearer_contexts; + eap_message_t eap_message; + qo_s_flow_descriptions_t authorized__qo_s_flow_descriptions; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + dnn_t dnn; + network_feature_support_5gsm_t network_feature_support_5gsm; + serving_plmn_rate_control_t serving_plmn_rate_control; + atsss_container_t atsss_container; + control_plane_only_indication_t control_plane_only_indication; + ip_header_compression_configuration_t ip_header_compression_configuration; + ethernet_header_compression_configuration_t ethernet_header_compression_configuration; + + const static uint8_t ie_iei_cause_5gsm = 0x59; + const static uint8_t ie_iei_pdu_address = 0x29; + const static uint8_t ie_iei_rq_timer_value = 0x56; + const static uint8_t ie_iei_s_nssai = 0x22; + const static uint8_t ie_iei_always_on_pdu_session_indication = 0x8; + const static uint8_t ie_iei_mapped_eps_bearer_contexts = 0x75; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_authorized__qo_s_flow_descriptions = 0x79; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_dnn = 0x25; + const static uint8_t ie_iei_network_feature_support_5gsm = 0x17; + const static uint8_t ie_iei_serving_plmn_rate_control = 0x18; + const static uint8_t ie_iei_atsss_container = 0x77; + const static uint8_t ie_iei_control_plane_only_indication = 0xC; + const static uint8_t ie_iei_ip_header_compression_configuration = 0x66; + const static uint8_t ie_iei_ethernet_header_compression_configuration = 0x1F; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_establishment_accept_t + +/* + * Message: PDU session establishment reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_establishment_reject_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + bool back_off_timer_value_present = false; + bool allowed_ssc_mode_present = false; + bool eap_message_present = false; + bool congestion_re_attempt_indicator_5gsm_present = false; + bool extended_protocol_configuration_options_present = false; + bool re_attempt_indicator_present = false; + + gprs_timer_3_t back_off_timer_value; + allowed_ssc_mode_t allowed_ssc_mode; + eap_message_t eap_message; + congestion_re_attempt_indicator_5gsm_t congestion_re_attempt_indicator_5gsm; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + re_attempt_indicator_t re_attempt_indicator; + + const static uint8_t ie_iei_back_off_timer_value = 0x37; + const static uint8_t ie_iei_allowed_ssc_mode = 0xF; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_congestion_re_attempt_indicator_5gsm = 0x61; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_re_attempt_indicator = 0x1D; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_establishment_reject_t + +/* + * Message: PDU session authentication command. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_authentication_command_t +{ +public: + // Mandatory fields + eap_message_t eap_message; + + // Optional fields + bool extended_protocol_configuration_options_present = false; + + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_authentication_command_t + +/* + * Message: PDU session authentication complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_authentication_complete_t +{ +public: + // Mandatory fields + eap_message_t eap_message; + + // Optional fields + bool extended_protocol_configuration_options_present = false; + + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_authentication_complete_t + +/* + * Message: PDU session authentication result. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_authentication_result_t +{ +public: + // Mandatory fields + + // Optional fields + bool eap_message_present = false; + bool extended_protocol_configuration_options_present = false; + + eap_message_t eap_message; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_authentication_result_t + +/* + * Message: PDU session modification request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_modification_request_t +{ +public: + // Mandatory fields + + // Optional fields + bool capability_5gsm_present = false; + bool cause_5gsm_present = false; + bool maximum_number_of_supported_packet_filters_present = false; + bool always_on_pdu_session_requested_present = false; + bool integrity_protection_maximum_data_rate_present = false; + bool requested__qo_s_rules_present = false; + bool requested__qo_s_flow_descriptions_present = false; + bool mapped_eps_bearer_contexts_present = false; + bool extended_protocol_configuration_options_present = false; + bool port_management_information_container_present = false; + bool ip_header_compression_configuration_present = false; + bool ethernet_header_compression_configuration_present = false; + + capability_5gsm_t capability_5gsm; + cause_5gsm_t cause_5gsm; + maximum_number_of_supported_packet_filters_t maximum_number_of_supported_packet_filters; + always_on_pdu_session_requested_t always_on_pdu_session_requested; + integrity_protection_maximum_data_rate_t integrity_protection_maximum_data_rate; + qo_s_rules_t requested__qo_s_rules; + qo_s_flow_descriptions_t requested__qo_s_flow_descriptions; + mapped_eps_bearer_contexts_t mapped_eps_bearer_contexts; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + port_management_information_container_t port_management_information_container; + ip_header_compression_configuration_t ip_header_compression_configuration; + ethernet_header_compression_configuration_t ethernet_header_compression_configuration; + + const static uint8_t ie_iei_capability_5gsm = 0x28; + const static uint8_t ie_iei_cause_5gsm = 0x59; + const static uint8_t ie_iei_maximum_number_of_supported_packet_filters = 0x55; + const static uint8_t ie_iei_always_on_pdu_session_requested = 0xB; + const static uint8_t ie_iei_integrity_protection_maximum_data_rate = 0x13; + const static uint8_t ie_iei_requested__qo_s_rules = 0x7A; + const static uint8_t ie_iei_requested__qo_s_flow_descriptions = 0x79; + const static uint8_t ie_iei_mapped_eps_bearer_contexts = 0x75; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_port_management_information_container = 0x74; + const static uint8_t ie_iei_ip_header_compression_configuration = 0x66; + const static uint8_t ie_iei_ethernet_header_compression_configuration = 0x1F; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_modification_request_t + +/* + * Message: PDU session modification reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_modification_reject_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + bool back_off_timer_value_present = false; + bool congestion_re_attempt_indicator_5gsm_present = false; + bool extended_protocol_configuration_options_present = false; + bool re_attempt_indicator_present = false; + + gprs_timer_3_t back_off_timer_value; + congestion_re_attempt_indicator_5gsm_t congestion_re_attempt_indicator_5gsm; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + re_attempt_indicator_t re_attempt_indicator; + + const static uint8_t ie_iei_back_off_timer_value = 0x37; + const static uint8_t ie_iei_congestion_re_attempt_indicator_5gsm = 0x61; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_re_attempt_indicator = 0x1D; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_modification_reject_t + +/* + * Message: PDU session modification command. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_modification_command_t +{ +public: + // Mandatory fields + + // Optional fields + bool cause_5gsm_present = false; + bool session_ambr_present = false; + bool rq_timer_value_present = false; + bool always_on_pdu_session_indication_present = false; + bool authorized__qo_s_rules_present = false; + bool mapped_eps_bearer_contexts_present = false; + bool authorized__qo_s_flow_descriptions_present = false; + bool extended_protocol_configuration_options_present = false; + bool atsss_container_present = false; + bool ip_header_compression_configuration_present = false; + bool port_management_information_container_present = false; + bool serving_plmn_rate_control_present = false; + bool ethernet_header_compression_configuration_present = false; + + cause_5gsm_t cause_5gsm; + session_ambr_t session_ambr; + gprs_timer_t rq_timer_value; + always_on_pdu_session_indication_t always_on_pdu_session_indication; + qo_s_rules_t authorized__qo_s_rules; + mapped_eps_bearer_contexts_t mapped_eps_bearer_contexts; + qo_s_flow_descriptions_t authorized__qo_s_flow_descriptions; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + atsss_container_t atsss_container; + ip_header_compression_configuration_t ip_header_compression_configuration; + port_management_information_container_t port_management_information_container; + serving_plmn_rate_control_t serving_plmn_rate_control; + ethernet_header_compression_configuration_t ethernet_header_compression_configuration; + + const static uint8_t ie_iei_cause_5gsm = 0x59; + const static uint8_t ie_iei_session_ambr = 0x2A; + const static uint8_t ie_iei_rq_timer_value = 0x56; + const static uint8_t ie_iei_always_on_pdu_session_indication = 0x8; + const static uint8_t ie_iei_authorized__qo_s_rules = 0x7A; + const static uint8_t ie_iei_mapped_eps_bearer_contexts = 0x75; + const static uint8_t ie_iei_authorized__qo_s_flow_descriptions = 0x79; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_atsss_container = 0x77; + const static uint8_t ie_iei_ip_header_compression_configuration = 0x66; + const static uint8_t ie_iei_port_management_information_container = 0x74; + const static uint8_t ie_iei_serving_plmn_rate_control = 0x1E; + const static uint8_t ie_iei_ethernet_header_compression_configuration = 0x1F; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_modification_command_t + +/* + * Message: PDU session modification complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_modification_complete_t +{ +public: + // Mandatory fields + + // Optional fields + bool extended_protocol_configuration_options_present = false; + bool port_management_information_container_present = false; + + extended_protocol_configuration_options_t extended_protocol_configuration_options; + port_management_information_container_t port_management_information_container; + + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_port_management_information_container = 0x74; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_modification_complete_t + +/* + * Message: PDU session modification command reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_modification_command_reject_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + bool extended_protocol_configuration_options_present = false; + + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_modification_command_reject_t + +/* + * Message: PDU session release request. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_release_request_t +{ +public: + // Mandatory fields + + // Optional fields + bool cause_5gsm_present = false; + bool extended_protocol_configuration_options_present = false; + + cause_5gsm_t cause_5gsm; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_cause_5gsm = 0x59; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_release_request_t + +/* + * Message: PDU session release reject. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_release_reject_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + bool extended_protocol_configuration_options_present = false; + + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_release_reject_t + +/* + * Message: PDU session release command. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_release_command_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + bool back_off_timer_value_present = false; + bool eap_message_present = false; + bool congestion_re_attempt_indicator_5gsm_present = false; + bool extended_protocol_configuration_options_present = false; + bool access_type_present = false; + + gprs_timer_3_t back_off_timer_value; + eap_message_t eap_message; + congestion_re_attempt_indicator_5gsm_t congestion_re_attempt_indicator_5gsm; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + access_type_t access_type; + + const static uint8_t ie_iei_back_off_timer_value = 0x37; + const static uint8_t ie_iei_eap_message = 0x78; + const static uint8_t ie_iei_congestion_re_attempt_indicator_5gsm = 0x61; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + const static uint8_t ie_iei_access_type = 0xD; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_release_command_t + +/* + * Message: PDU session release complete. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class pdu_session_release_complete_t +{ +public: + // Mandatory fields + + // Optional fields + bool cause_5gsm_present = false; + bool extended_protocol_configuration_options_present = false; + + cause_5gsm_t cause_5gsm; + extended_protocol_configuration_options_t extended_protocol_configuration_options; + + const static uint8_t ie_iei_cause_5gsm = 0x59; + const static uint8_t ie_iei_extended_protocol_configuration_options = 0x7B; + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // pdu_session_release_complete_t + +/* + * Message: Status 5GSM. + * Based on 3GPP TS 24.501 v16.7.0 + */ + +class status_5gsm_t +{ +public: + // Mandatory fields + cause_5gsm_t cause_5gsm; + + // Optional fields + +public: + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + +}; // status_5gsm_t +// Include from nas5g/infiles/nas_5g_msg.h.in + +struct msg_opts { + enum options { + registration_request = 0x41, + registration_accept = 0x42, + registration_complete = 0x43, + registration_reject = 0x44, + deregistration_request_ue_originating = 0x45, + deregistration_accept_ue_originating = 0x46, + deregistration_request_ue_terminated = 0x47, + deregistration_accept_ue_terminated = 0x48, + service_request = 0x4c, + service_reject = 0x4d, + service_accept = 0x4e, + configuration_update_command = 0x54, + configuration_update_complete = 0x55, + authentication_request = 0x56, + authentication_response = 0x57, + authentication_reject = 0x58, + authentication_failure = 0x59, + authentication_result = 0x5a, + identity_request = 0x5b, + identity_response = 0x5c, + security_mode_command = 0x5d, + security_mode_complete = 0x5e, + security_mode_reject = 0x5f, + status_5gmm = 0x64, + notification = 0x65, + notification_response = 0x66, + ul_nas_transport = 0x67, + dl_nas_transport = 0x68, + pdu_session_establishment_request = 0xc1, + pdu_session_establishment_accept = 0xc2, + pdu_session_establishment_reject = 0xc3, + pdu_session_authentication_command = 0xc5, + pdu_session_authentication_complete = 0xc6, + pdu_session_authentication_result = 0xc7, + pdu_session_modification_request = 0xc9, + pdu_session_modification_reject = 0xca, + pdu_session_modification_command = 0xcb, + pdu_session_modification_complete = 0xcc, + pdu_session_modification_command_reject = 0xcd, + pdu_session_release_request = 0xd1, + pdu_session_release_reject = 0xd2, + pdu_session_release_command = 0xd3, + pdu_session_release_complete = 0xd4, + status_5gsm = 0xd6, + nulltype = 0xff, + + } value; + const char* to_string() const + { + switch (value) { + case registration_request: + return "Registration request"; + case registration_accept: + return "Registration accept"; + case registration_complete: + return "Registration complete"; + case registration_reject: + return "Registration reject"; + case deregistration_request_ue_originating: + return "Deregistration request UE originating"; + case deregistration_accept_ue_originating: + return "Deregistration accept UE originating"; + case deregistration_request_ue_terminated: + return "Deregistration request UE terminated"; + case deregistration_accept_ue_terminated: + return "Deregistration accept UE terminated"; + case service_request: + return "Service request"; + case service_reject: + return "Service reject"; + case service_accept: + return "Service accept"; + case configuration_update_command: + return "Configuration update command"; + case configuration_update_complete: + return "Configuration update complete"; + case authentication_request: + return "Authentication request"; + case authentication_response: + return "Authentication response"; + case authentication_reject: + return "Authentication reject"; + case authentication_failure: + return "Authentication failure"; + case authentication_result: + return "Authentication result"; + case identity_request: + return "Identity request"; + case identity_response: + return "Identity response"; + case security_mode_command: + return "Security mode command"; + case security_mode_complete: + return "Security mode complete"; + case security_mode_reject: + return "Security mode reject"; + case status_5gmm: + return "Status 5GMM"; + case notification: + return "Notification"; + case notification_response: + return "Notification response"; + case ul_nas_transport: + return "UL NAS transport"; + case dl_nas_transport: + return "DL NAS transport "; + case pdu_session_establishment_request: + return "PDU session establishment request"; + case pdu_session_establishment_accept: + return "PDU session establishment accept"; + case pdu_session_establishment_reject: + return "PDU session establishment reject"; + case pdu_session_authentication_command: + return "PDU session authentication command"; + case pdu_session_authentication_complete: + return "PDU session authentication complete"; + case pdu_session_authentication_result: + return "PDU session authentication result"; + case pdu_session_modification_request: + return "PDU session modification request"; + case pdu_session_modification_reject: + return "PDU session modification reject"; + case pdu_session_modification_command: + return "PDU session modification command"; + case pdu_session_modification_complete: + return "PDU session modification complete"; + case pdu_session_modification_command_reject: + return "PDU session modification command reject"; + case pdu_session_release_request: + return "PDU session release request"; + case pdu_session_release_reject: + return "PDU session release reject"; + case pdu_session_release_command: + return "PDU session release command"; + case pdu_session_release_complete: + return "PDU session release complete"; + case status_5gsm: + return "Status 5GSM"; + default: + return "Error"; + } + } +}; + +typedef asn1::enumerated msg_types; +struct nas_5gs_hdr { + enum security_header_type_opts { + plain_5gs_nas_message, + integrity_protected, + integrity_protected_and_ciphered, + integrity_protected_with_new_5G_nas_context, + integrity_protected_and_ciphered_with_new_5G_nas_context + }; + + enum extended_protocol_discriminator_opts { + extended_protocol_discriminator_5gsm = 0x2e, + extended_protocol_discriminator_5gmm = 0x7e, + }; + + // Outer + extended_protocol_discriminator_opts extended_protocol_discriminator = extended_protocol_discriminator_5gsm; + security_header_type_opts security_header_type = plain_5gs_nas_message; + // Only valid if not plain + uint8_t sequence_number = 0xff; + uint32_t message_authentication_code = 0x00000000; + // Only valid if 5gsm type + uint8_t pdu_session_identity = 0xff; + uint8_t procedure_transaction_identity = 0xff; + // Inner + extended_protocol_discriminator_opts inner_extended_protocol_discriminator = extended_protocol_discriminator_5gsm; + security_header_type_opts inner_security_header_type = plain_5gs_nas_message; + + msg_types message_type = msg_types::options::nulltype; + + SRSASN_CODE pack(asn1::bit_ref& bref); + SRSASN_CODE pack_outer(asn1::bit_ref& bref); + SRSASN_CODE unpack(asn1::cbit_ref& bref); + SRSASN_CODE unpack_outer(asn1::cbit_ref& bref); +}; + +class nas_5gs_msg +{ +public: + nas_5gs_hdr hdr; + + SRSASN_CODE pack(unique_byte_buffer_t& buf); + SRSASN_CODE pack(std::vector buf); + SRSASN_CODE unpack(const unique_byte_buffer_t& buf); + SRSASN_CODE unpack(const std::vector buf); + SRSASN_CODE unpack_outer_hdr(const unique_byte_buffer_t& buf); + SRSASN_CODE unpack_outer_hdr(const std::vector buf); + + void set(msg_types::options e = msg_types::nulltype) { hdr.message_type = e; }; + // Getters + + registration_request_t& registration_request() + { + asn1::assert_choice_type(msg_types::options::registration_request, hdr.message_type, "registration_request"); + return *srslog::detail::any_cast(&msg_container); + } + + registration_accept_t& registration_accept() + { + asn1::assert_choice_type(msg_types::options::registration_accept, hdr.message_type, "registration_accept"); + return *srslog::detail::any_cast(&msg_container); + } + + registration_complete_t& registration_complete() + { + asn1::assert_choice_type(msg_types::options::registration_complete, hdr.message_type, "registration_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + registration_reject_t& registration_reject() + { + asn1::assert_choice_type(msg_types::options::registration_reject, hdr.message_type, "registration_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + deregistration_request_ue_originating_t& deregistration_request_ue_originating() + { + asn1::assert_choice_type(msg_types::options::deregistration_request_ue_originating, + hdr.message_type, + "deregistration_request_ue_originating"); + return *srslog::detail::any_cast(&msg_container); + } + + deregistration_accept_ue_originating_t& deregistration_accept_ue_originating() + { + asn1::assert_choice_type(msg_types::options::deregistration_accept_ue_originating, + hdr.message_type, + "deregistration_accept_ue_originating"); + return *srslog::detail::any_cast(&msg_container); + } + + deregistration_request_ue_terminated_t& deregistration_request_ue_terminated() + { + asn1::assert_choice_type(msg_types::options::deregistration_request_ue_terminated, + hdr.message_type, + "deregistration_request_ue_terminated"); + return *srslog::detail::any_cast(&msg_container); + } + + deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated() + { + asn1::assert_choice_type(msg_types::options::deregistration_accept_ue_terminated, + hdr.message_type, + "deregistration_accept_ue_terminated"); + return *srslog::detail::any_cast(&msg_container); + } + + service_request_t& service_request() + { + asn1::assert_choice_type(msg_types::options::service_request, hdr.message_type, "service_request"); + return *srslog::detail::any_cast(&msg_container); + } + + service_reject_t& service_reject() + { + asn1::assert_choice_type(msg_types::options::service_reject, hdr.message_type, "service_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + service_accept_t& service_accept() + { + asn1::assert_choice_type(msg_types::options::service_accept, hdr.message_type, "service_accept"); + return *srslog::detail::any_cast(&msg_container); + } + + configuration_update_command_t& configuration_update_command() + { + asn1::assert_choice_type( + msg_types::options::configuration_update_command, hdr.message_type, "configuration_update_command"); + return *srslog::detail::any_cast(&msg_container); + } + + configuration_update_complete_t& configuration_update_complete() + { + asn1::assert_choice_type( + msg_types::options::configuration_update_complete, hdr.message_type, "configuration_update_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + authentication_request_t& authentication_request() + { + asn1::assert_choice_type(msg_types::options::authentication_request, hdr.message_type, "authentication_request"); + return *srslog::detail::any_cast(&msg_container); + } + + authentication_response_t& authentication_response() + { + asn1::assert_choice_type(msg_types::options::authentication_response, hdr.message_type, "authentication_response"); + return *srslog::detail::any_cast(&msg_container); + } + + authentication_reject_t& authentication_reject() + { + asn1::assert_choice_type(msg_types::options::authentication_reject, hdr.message_type, "authentication_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + authentication_failure_t& authentication_failure() + { + asn1::assert_choice_type(msg_types::options::authentication_failure, hdr.message_type, "authentication_failure"); + return *srslog::detail::any_cast(&msg_container); + } + + authentication_result_t& authentication_result() + { + asn1::assert_choice_type(msg_types::options::authentication_result, hdr.message_type, "authentication_result"); + return *srslog::detail::any_cast(&msg_container); + } + + identity_request_t& identity_request() + { + asn1::assert_choice_type(msg_types::options::identity_request, hdr.message_type, "identity_request"); + return *srslog::detail::any_cast(&msg_container); + } + + identity_response_t& identity_response() + { + asn1::assert_choice_type(msg_types::options::identity_response, hdr.message_type, "identity_response"); + return *srslog::detail::any_cast(&msg_container); + } + + security_mode_command_t& security_mode_command() + { + asn1::assert_choice_type(msg_types::options::security_mode_command, hdr.message_type, "security_mode_command"); + return *srslog::detail::any_cast(&msg_container); + } + + security_mode_complete_t& security_mode_complete() + { + asn1::assert_choice_type(msg_types::options::security_mode_complete, hdr.message_type, "security_mode_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + security_mode_reject_t& security_mode_reject() + { + asn1::assert_choice_type(msg_types::options::security_mode_reject, hdr.message_type, "security_mode_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + status_5gmm_t& status_5gmm() + { + asn1::assert_choice_type(msg_types::options::status_5gmm, hdr.message_type, "status_5gmm"); + return *srslog::detail::any_cast(&msg_container); + } + + notification_t& notification() + { + asn1::assert_choice_type(msg_types::options::notification, hdr.message_type, "notification"); + return *srslog::detail::any_cast(&msg_container); + } + + notification_response_t& notification_response() + { + asn1::assert_choice_type(msg_types::options::notification_response, hdr.message_type, "notification_response"); + return *srslog::detail::any_cast(&msg_container); + } + + ul_nas_transport_t& ul_nas_transport() + { + asn1::assert_choice_type(msg_types::options::ul_nas_transport, hdr.message_type, "ul_nas_transport"); + return *srslog::detail::any_cast(&msg_container); + } + + dl_nas_transport_t& dl_nas_transport() + { + asn1::assert_choice_type(msg_types::options::dl_nas_transport, hdr.message_type, "dl_nas_transport"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_establishment_request_t& pdu_session_establishment_request() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_establishment_request, hdr.message_type, "pdu_session_establishment_request"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_establishment_accept_t& pdu_session_establishment_accept() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_establishment_accept, hdr.message_type, "pdu_session_establishment_accept"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_establishment_reject_t& pdu_session_establishment_reject() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_establishment_reject, hdr.message_type, "pdu_session_establishment_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_authentication_command_t& pdu_session_authentication_command() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_authentication_command, hdr.message_type, "pdu_session_authentication_command"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_authentication_complete_t& pdu_session_authentication_complete() + { + asn1::assert_choice_type(msg_types::options::pdu_session_authentication_complete, + hdr.message_type, + "pdu_session_authentication_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_authentication_result_t& pdu_session_authentication_result() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_authentication_result, hdr.message_type, "pdu_session_authentication_result"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_modification_request_t& pdu_session_modification_request() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_modification_request, hdr.message_type, "pdu_session_modification_request"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_modification_reject_t& pdu_session_modification_reject() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_modification_reject, hdr.message_type, "pdu_session_modification_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_modification_command_t& pdu_session_modification_command() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_modification_command, hdr.message_type, "pdu_session_modification_command"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_modification_complete_t& pdu_session_modification_complete() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_modification_complete, hdr.message_type, "pdu_session_modification_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_modification_command_reject_t& pdu_session_modification_command_reject() + { + asn1::assert_choice_type(msg_types::options::pdu_session_modification_command_reject, + hdr.message_type, + "pdu_session_modification_command_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_release_request_t& pdu_session_release_request() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_release_request, hdr.message_type, "pdu_session_release_request"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_release_reject_t& pdu_session_release_reject() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_release_reject, hdr.message_type, "pdu_session_release_reject"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_release_command_t& pdu_session_release_command() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_release_command, hdr.message_type, "pdu_session_release_command"); + return *srslog::detail::any_cast(&msg_container); + } + + pdu_session_release_complete_t& pdu_session_release_complete() + { + asn1::assert_choice_type( + msg_types::options::pdu_session_release_complete, hdr.message_type, "pdu_session_release_complete"); + return *srslog::detail::any_cast(&msg_container); + } + + status_5gsm_t& status_5gsm() + { + asn1::assert_choice_type(msg_types::options::status_5gsm, hdr.message_type, "status_5gsm"); + return *srslog::detail::any_cast(&msg_container); + } + + // Setters + + registration_request_t& set_registration_request() + { + set(msg_types::options::registration_request); + msg_container = srslog::detail::any{registration_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + registration_accept_t& set_registration_accept() + { + set(msg_types::options::registration_accept); + msg_container = srslog::detail::any{registration_accept_t()}; + return *srslog::detail::any_cast(&msg_container); + } + registration_complete_t& set_registration_complete() + { + set(msg_types::options::registration_complete); + msg_container = srslog::detail::any{registration_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + registration_reject_t& set_registration_reject() + { + set(msg_types::options::registration_reject); + msg_container = srslog::detail::any{registration_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + deregistration_request_ue_originating_t& set_deregistration_request_ue_originating() + { + set(msg_types::options::deregistration_request_ue_originating); + msg_container = srslog::detail::any{deregistration_request_ue_originating_t()}; + return *srslog::detail::any_cast(&msg_container); + } + deregistration_accept_ue_originating_t& set_deregistration_accept_ue_originating() + { + set(msg_types::options::deregistration_accept_ue_originating); + msg_container = srslog::detail::any{deregistration_accept_ue_originating_t()}; + return *srslog::detail::any_cast(&msg_container); + } + deregistration_request_ue_terminated_t& set_deregistration_request_ue_terminated() + { + set(msg_types::options::deregistration_request_ue_terminated); + msg_container = srslog::detail::any{deregistration_request_ue_terminated_t()}; + return *srslog::detail::any_cast(&msg_container); + } + deregistration_accept_ue_terminated_t& set_deregistration_accept_ue_terminated() + { + set(msg_types::options::deregistration_accept_ue_terminated); + msg_container = srslog::detail::any{deregistration_accept_ue_terminated_t()}; + return *srslog::detail::any_cast(&msg_container); + } + service_request_t& set_service_request() + { + set(msg_types::options::service_request); + msg_container = srslog::detail::any{service_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + service_reject_t& set_service_reject() + { + set(msg_types::options::service_reject); + msg_container = srslog::detail::any{service_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + service_accept_t& set_service_accept() + { + set(msg_types::options::service_accept); + msg_container = srslog::detail::any{service_accept_t()}; + return *srslog::detail::any_cast(&msg_container); + } + configuration_update_command_t& set_configuration_update_command() + { + set(msg_types::options::configuration_update_command); + msg_container = srslog::detail::any{configuration_update_command_t()}; + return *srslog::detail::any_cast(&msg_container); + } + configuration_update_complete_t& set_configuration_update_complete() + { + set(msg_types::options::configuration_update_complete); + msg_container = srslog::detail::any{configuration_update_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + authentication_request_t& set_authentication_request() + { + set(msg_types::options::authentication_request); + msg_container = srslog::detail::any{authentication_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + authentication_response_t& set_authentication_response() + { + set(msg_types::options::authentication_response); + msg_container = srslog::detail::any{authentication_response_t()}; + return *srslog::detail::any_cast(&msg_container); + } + authentication_reject_t& set_authentication_reject() + { + set(msg_types::options::authentication_reject); + msg_container = srslog::detail::any{authentication_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + authentication_failure_t& set_authentication_failure() + { + set(msg_types::options::authentication_failure); + msg_container = srslog::detail::any{authentication_failure_t()}; + return *srslog::detail::any_cast(&msg_container); + } + authentication_result_t& set_authentication_result() + { + set(msg_types::options::authentication_result); + msg_container = srslog::detail::any{authentication_result_t()}; + return *srslog::detail::any_cast(&msg_container); + } + identity_request_t& set_identity_request() + { + set(msg_types::options::identity_request); + msg_container = srslog::detail::any{identity_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + identity_response_t& set_identity_response() + { + set(msg_types::options::identity_response); + msg_container = srslog::detail::any{identity_response_t()}; + return *srslog::detail::any_cast(&msg_container); + } + security_mode_command_t& set_security_mode_command() + { + set(msg_types::options::security_mode_command); + msg_container = srslog::detail::any{security_mode_command_t()}; + return *srslog::detail::any_cast(&msg_container); + } + security_mode_complete_t& set_security_mode_complete() + { + set(msg_types::options::security_mode_complete); + msg_container = srslog::detail::any{security_mode_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + security_mode_reject_t& set_security_mode_reject() + { + set(msg_types::options::security_mode_reject); + msg_container = srslog::detail::any{security_mode_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + status_5gmm_t& set_status_5gmm() + { + set(msg_types::options::status_5gmm); + msg_container = srslog::detail::any{status_5gmm_t()}; + return *srslog::detail::any_cast(&msg_container); + } + notification_t& set_notification() + { + set(msg_types::options::notification); + msg_container = srslog::detail::any{notification_t()}; + return *srslog::detail::any_cast(&msg_container); + } + notification_response_t& set_notification_response() + { + set(msg_types::options::notification_response); + msg_container = srslog::detail::any{notification_response_t()}; + return *srslog::detail::any_cast(&msg_container); + } + ul_nas_transport_t& set_ul_nas_transport() + { + set(msg_types::options::ul_nas_transport); + msg_container = srslog::detail::any{ul_nas_transport_t()}; + return *srslog::detail::any_cast(&msg_container); + } + dl_nas_transport_t& set_dl_nas_transport() + { + set(msg_types::options::dl_nas_transport); + msg_container = srslog::detail::any{dl_nas_transport_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_establishment_request_t& set_pdu_session_establishment_request() + { + set(msg_types::options::pdu_session_establishment_request); + msg_container = srslog::detail::any{pdu_session_establishment_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_establishment_accept_t& set_pdu_session_establishment_accept() + { + set(msg_types::options::pdu_session_establishment_accept); + msg_container = srslog::detail::any{pdu_session_establishment_accept_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_establishment_reject_t& set_pdu_session_establishment_reject() + { + set(msg_types::options::pdu_session_establishment_reject); + msg_container = srslog::detail::any{pdu_session_establishment_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_authentication_command_t& set_pdu_session_authentication_command() + { + set(msg_types::options::pdu_session_authentication_command); + msg_container = srslog::detail::any{pdu_session_authentication_command_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_authentication_complete_t& set_pdu_session_authentication_complete() + { + set(msg_types::options::pdu_session_authentication_complete); + msg_container = srslog::detail::any{pdu_session_authentication_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_authentication_result_t& set_pdu_session_authentication_result() + { + set(msg_types::options::pdu_session_authentication_result); + msg_container = srslog::detail::any{pdu_session_authentication_result_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_modification_request_t& set_pdu_session_modification_request() + { + set(msg_types::options::pdu_session_modification_request); + msg_container = srslog::detail::any{pdu_session_modification_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_modification_reject_t& set_pdu_session_modification_reject() + { + set(msg_types::options::pdu_session_modification_reject); + msg_container = srslog::detail::any{pdu_session_modification_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_modification_command_t& set_pdu_session_modification_command() + { + set(msg_types::options::pdu_session_modification_command); + msg_container = srslog::detail::any{pdu_session_modification_command_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_modification_complete_t& set_pdu_session_modification_complete() + { + set(msg_types::options::pdu_session_modification_complete); + msg_container = srslog::detail::any{pdu_session_modification_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_modification_command_reject_t& set_pdu_session_modification_command_reject() + { + set(msg_types::options::pdu_session_modification_command_reject); + msg_container = srslog::detail::any{pdu_session_modification_command_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_release_request_t& set_pdu_session_release_request() + { + set(msg_types::options::pdu_session_release_request); + msg_container = srslog::detail::any{pdu_session_release_request_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_release_reject_t& set_pdu_session_release_reject() + { + set(msg_types::options::pdu_session_release_reject); + msg_container = srslog::detail::any{pdu_session_release_reject_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_release_command_t& set_pdu_session_release_command() + { + set(msg_types::options::pdu_session_release_command); + msg_container = srslog::detail::any{pdu_session_release_command_t()}; + return *srslog::detail::any_cast(&msg_container); + } + pdu_session_release_complete_t& set_pdu_session_release_complete() + { + set(msg_types::options::pdu_session_release_complete); + msg_container = srslog::detail::any{pdu_session_release_complete_t()}; + return *srslog::detail::any_cast(&msg_container); + } + status_5gsm_t& set_status_5gsm() + { + set(msg_types::options::status_5gsm); + msg_container = srslog::detail::any{status_5gsm_t()}; + return *srslog::detail::any_cast(&msg_container); + } + +private: + SRSASN_CODE unpack(asn1::cbit_ref& bref); + SRSASN_CODE pack(asn1::bit_ref& bref); + srslog::detail::any msg_container; +}; +} // namespace nas_5g +} // namespace srsran +#endif diff --git a/lib/include/srsran/asn1/nas_5g_utils.h b/lib/include/srsran/asn1/nas_5g_utils.h new file mode 100644 index 000000000..b8ce86157 --- /dev/null +++ b/lib/include/srsran/asn1/nas_5g_utils.h @@ -0,0 +1,87 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_NAS_5G_UTILS_H +#define SRSRAN_NAS_5G_UTILS_H + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/byte_buffer.h" +#include "srsran/config.h" + +using namespace asn1; +namespace srsran { +namespace nas_5g { + +struct ecies_scheme_profile_a_out { + uint8_t ecc_ephemeral_key[33]; + std::vector ciphertext; + uint8_t mac_tag[8]; +}; + +struct ecies_scheme_profile_b_out { + uint8_t ecc_ephemeral_key[32]; + std::vector ciphertext; + uint8_t mac_tag[8]; +}; + +template +SRSASN_CODE unpack_enum(asn1::cbit_ref& bref, Enum* e) +{ + uint32_t tmp = {}; + HANDLE_CODE(bref.unpack(tmp, bl)); + *e = static_cast(tmp); + return SRSASN_SUCCESS; +} + +template +SRSASN_CODE pack_enum(asn1::bit_ref& bref, Enum e) +{ + uint32_t tmp = static_cast(e); + HANDLE_CODE(bref.pack(tmp, bl)); + return SRSASN_SUCCESS; +} + +template +class nas_enumerated : public EnumType +{ +public: + static const uint32_t bit_length = bit_length_; + + nas_enumerated() {} + nas_enumerated(typename EnumType::options o) { EnumType::value = o; } + SRSASN_CODE pack(asn1::bit_ref& bref) const + { + uint32_t tmp = static_cast(EnumType::value); + HANDLE_CODE(bref.pack(tmp, bit_length)); + return SRSASN_SUCCESS; + } + SRSASN_CODE unpack(asn1::cbit_ref& bref) + { + uint32_t tmp = {}; + HANDLE_CODE(bref.unpack(tmp, bit_length)); + *this = static_cast(tmp); + return SRSASN_SUCCESS; + } + EnumType& operator=(EnumType v) + { + EnumType::value = v; + return *this; + } + operator typename EnumType::options() const { return EnumType::value; } +}; + +SRSASN_CODE unpack_mcc_mnc(uint8_t* mcc_bytes, uint8_t* mnc_bytes, asn1::cbit_ref& bref); +SRSASN_CODE pack_mcc_mnc(uint8_t* mcc_bytes, uint8_t* mnc_bytes, asn1::bit_ref& bref); + +} // namespace nas_5g +} // namespace srsran +#endif // MANUAL_H \ No newline at end of file diff --git a/lib/src/asn1/CMakeLists.txt b/lib/src/asn1/CMakeLists.txt index d99b61f27..ba164a56f 100644 --- a/lib/src/asn1/CMakeLists.txt +++ b/lib/src/asn1/CMakeLists.txt @@ -61,5 +61,10 @@ add_library(ngap_nr_asn1 STATIC ngap.cc) target_compile_options(ngap_nr_asn1 PRIVATE "-Os") target_link_libraries(ngap_nr_asn1 asn1_utils srsran_common) INSTALL(TARGETS ngap_nr_asn1 DESTINATION ${LIBRARY_DIR}) +# NAS 5G +add_library(nas_5g_msg STATIC nas_5g_msg.cc nas_5g_ies.cc nas_5g_utils.cc) +target_compile_options(nas_5g_msg PRIVATE "-Os") +target_link_libraries(nas_5g_msg asn1_utils srsran_common) +INSTALL(TARGETS nas_5g_msg DESTINATION ${LIBRARY_DIR}) diff --git a/lib/src/asn1/nas_5g_ies.cc b/lib/src/asn1/nas_5g_ies.cc new file mode 100644 index 000000000..b90265f61 --- /dev/null +++ b/lib/src/asn1/nas_5g_ies.cc @@ -0,0 +1,4359 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srsran/asn1/nas_5g_ies.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/config.h" + +#include +#include +#include + +namespace srsran { +namespace nas_5g { + +using namespace asn1; +// IE: 5GS registration type +// Reference: 9.11.3.7 +SRSASN_CODE registration_type_5gs_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(follow_on_request_bit.pack(bref)); + HANDLE_CODE(registration_type.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GS registration type +// Reference: 9.11.3.7 +SRSASN_CODE registration_type_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(follow_on_request_bit.unpack(bref)); + HANDLE_CODE(registration_type.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: key set identifier +// Reference: 9.11.3.32 +SRSASN_CODE key_set_identifier_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(security_context_flag.pack(bref)); + HANDLE_CODE(nas_key_set_identifier.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: key set identifier +// Reference: 9.11.3.32 +SRSASN_CODE key_set_identifier_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(security_context_flag.unpack(bref)); + HANDLE_CODE(nas_key_set_identifier.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GS mobile identity +// Reference: 9.11.3.4 +SRSASN_CODE mobile_identity_5gs_t::pack(asn1::bit_ref& bref) +{ + // Length + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + asn1::bit_ref bref_tmp = bref; + switch (type_) { + case identity_types::no_identity: + HANDLE_CODE(type_.pack(bref)); + break; + case identity_types::suci: { + suci_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::guti_5g: { + guti_5g_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::imei: { + imei_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::s_tmsi_5g: { + s_tmsi_5g_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::imeisv: { + imeisv_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::mac_address: { + mac_address_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + case identity_types::eui_64: { + eui_64_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->pack(bref, bref_tmp)); + break; + } + default: + log_invalid_choice_id(type_, "5G NAS ID TYPE"); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + uint16_t length = (uint16_t)((bref.distance(bref_length) / 8) - 2); + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: 5GS mobile identity +// Reference: 9.11.3.4 +SRSASN_CODE mobile_identity_5gs_t::unpack(asn1::cbit_ref& bref) +{ + // Length + HANDLE_CODE(bref.unpack(length, 16)); + uint8_t tmp; + HANDLE_CODE(bref.unpack(tmp, 5)); + identity_types e = identity_types::no_identity; + HANDLE_CODE(e.unpack(bref)); + set(e); + switch (type_) { + case identity_types::no_identity: + break; + case identity_types::suci: { + choice_container = srslog::detail::any{suci_s()}; + suci_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::guti_5g: { + choice_container = srslog::detail::any{guti_5g_s()}; + guti_5g_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::imei: { + choice_container = srslog::detail::any{imei_s()}; + imei_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::s_tmsi_5g: { + choice_container = srslog::detail::any{s_tmsi_5g_s()}; + s_tmsi_5g_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::imeisv: { + choice_container = srslog::detail::any{imeisv_s()}; + imeisv_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::mac_address: { + choice_container = srslog::detail::any{mac_address_s()}; + mac_address_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + case identity_types::eui_64: { + choice_container = srslog::detail::any{eui_64_s()}; + eui_64_s* choice = srslog::detail::any_cast(&choice_container); + HANDLE_CODE(choice->unpack(bref, tmp, length)); + break; + } + default: + log_invalid_choice_id(type_, "5G NAS ID TYPE"); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + return SRSASN_SUCCESS; +} + +const char* mobile_identity_5gs_t::identity_types_::to_string() +{ + switch (value) { + case identity_types_::no_identity: + return "No identity"; + case identity_types_::suci: + return "SUCI"; + case identity_types_::guti_5g: + return "5G-GUTI"; + case identity_types_::imei: + return "IMEI"; + case identity_types_::s_tmsi_5g: + return "5G-S-TMSI"; + case identity_types_::imeisv: + return "IMEISV"; + case identity_types_::mac_address: + return "MAC address"; + case identity_types_::eui_64: + return "EUI-64"; + default: + return "Invalid Choice"; + } +} +SRSASN_CODE mobile_identity_5gs_t::suci_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + HANDLE_CODE(bref.advance_bits(1)); + HANDLE_CODE(supi_format.pack(bref)); + HANDLE_CODE(bref.advance_bits(1)); + + // Pack Type of identity + uint8_t type = static_cast(mobile_identity_5gs_t::identity_types_::options::suci); + HANDLE_CODE(bref.pack(type, 3)); + + HANDLE_CODE(pack_mcc_mnc(mcc.data(), mnc.data(), bref)); + HANDLE_CODE(bref.pack(routing_indicator[1], 4)); + HANDLE_CODE(bref.pack(routing_indicator[0], 4)); + HANDLE_CODE(bref.pack(routing_indicator[3], 4)); + HANDLE_CODE(bref.pack(routing_indicator[2], 4)); + // Spare + HANDLE_CODE(bref.advance_bits(4)); + HANDLE_CODE(protection_scheme_id.pack(bref)); + HANDLE_CODE(bref.pack(home_network_public_key_identifier, 8)); + HANDLE_CODE(bref.pack_bytes(scheme_output.data(), scheme_output.size())); + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::suci_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + supi_format = static_cast(tmp >> 1 & 0b111); + HANDLE_CODE(unpack_mcc_mnc(mcc.data(), mnc.data(), bref)); + HANDLE_CODE(bref.unpack(routing_indicator[1], 4)); + HANDLE_CODE(bref.unpack(routing_indicator[0], 4)); + HANDLE_CODE(bref.unpack(routing_indicator[3], 4)); + HANDLE_CODE(bref.unpack(routing_indicator[2], 4)); + // Spare + HANDLE_CODE(bref.advance_bits(4)); + HANDLE_CODE(protection_scheme_id.unpack(bref)); + HANDLE_CODE(bref.unpack(home_network_public_key_identifier, 8)); + scheme_output.resize(length - 8); + HANDLE_CODE(bref.unpack_bytes(scheme_output.data(), length - 8)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::guti_5g_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + HANDLE_CODE(bref.pack(0x0, 5)); + // Pack Type of identity + uint8_t type = static_cast(mobile_identity_5gs_t::identity_types_::options::guti_5g); + HANDLE_CODE(bref.pack(type, 3)); + + HANDLE_CODE(pack_mcc_mnc(mcc.data(), mnc.data(), bref)); + HANDLE_CODE(bref.pack(amf_region_id, 8)); + HANDLE_CODE(bref.pack(amf_set_id, 10)); + HANDLE_CODE(bref.pack(amf_pointer, 6)); + HANDLE_CODE(bref.pack(tmsi_5g, 4 * 8)); + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::guti_5g_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + HANDLE_CODE(unpack_mcc_mnc(mcc.data(), mnc.data(), bref)); + HANDLE_CODE(bref.unpack(amf_region_id, 8)); + HANDLE_CODE(bref.unpack(amf_set_id, 10)); + HANDLE_CODE(bref.unpack(amf_pointer, 6)); + HANDLE_CODE(bref.unpack(tmsi_5g, 4 * 8)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::imei_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + HANDLE_CODE(bref.pack(imei[0], 4)); + HANDLE_CODE(bref.pack(odd_even_indicator, 1)); + + // Pack Type of identity + uint8_t type = static_cast(mobile_identity_5gs_t::identity_types_::options::imei); + HANDLE_CODE(bref.pack(type, 3)); + + HANDLE_CODE(bref.pack(imei[2], 4)); + HANDLE_CODE(bref.pack(imei[1], 4)); + HANDLE_CODE(bref.pack(imei[4], 4)); + HANDLE_CODE(bref.pack(imei[3], 4)); + HANDLE_CODE(bref.pack(imei[6], 4)); + HANDLE_CODE(bref.pack(imei[5], 4)); + HANDLE_CODE(bref.pack(imei[8], 4)); + HANDLE_CODE(bref.pack(imei[7], 4)); + HANDLE_CODE(bref.pack(imei[10], 4)); + HANDLE_CODE(bref.pack(imei[9], 4)); + HANDLE_CODE(bref.pack(imei[12], 4)); + HANDLE_CODE(bref.pack(imei[11], 4)); + HANDLE_CODE(bref.pack(imei[14], 4)); + HANDLE_CODE(bref.pack(imei[13], 4)); + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::imei_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + imei[0] = (uint8_t)(tmp >> 1) & 0x0f; + odd_even_indicator = (bool)(tmp & 0x01); // true = odd number + HANDLE_CODE(bref.unpack(imei[2], 4)); + HANDLE_CODE(bref.unpack(imei[1], 4)); + HANDLE_CODE(bref.unpack(imei[4], 4)); + HANDLE_CODE(bref.unpack(imei[3], 4)); + HANDLE_CODE(bref.unpack(imei[6], 4)); + HANDLE_CODE(bref.unpack(imei[5], 4)); + HANDLE_CODE(bref.unpack(imei[8], 4)); + HANDLE_CODE(bref.unpack(imei[7], 4)); + HANDLE_CODE(bref.unpack(imei[10], 4)); + HANDLE_CODE(bref.unpack(imei[9], 4)); + HANDLE_CODE(bref.unpack(imei[12], 4)); + HANDLE_CODE(bref.unpack(imei[11], 4)); + HANDLE_CODE(bref.unpack(imei[14], 4)); + HANDLE_CODE(bref.unpack(imei[13], 4)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::s_tmsi_5g_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + // Pack Type of identity + uint8_t type = static_cast(mobile_identity_5gs_t::identity_types_::options::s_tmsi_5g); + HANDLE_CODE(bref.pack(type, 3)); + + HANDLE_CODE(bref.unpack(amf_set_id, 10)); + HANDLE_CODE(bref.unpack(amf_pointer, 6)); + HANDLE_CODE(bref.unpack(tmsi_5g, 4 * 8)); + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::s_tmsi_5g_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + HANDLE_CODE(bref.unpack(amf_set_id, 10)); + HANDLE_CODE(bref.unpack(amf_pointer, 6)); + HANDLE_CODE(bref.unpack(tmsi_5g, 4 * 8)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::imeisv_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + HANDLE_CODE(bref.pack(imeisv[0], 4)); + HANDLE_CODE(bref.pack(odd_even_indicator, 1)); + + // Pack Type of identity + uint8_t type = static_cast(mobile_identity_5gs_t::identity_types_::options::imeisv); + HANDLE_CODE(bref.pack(type, 3)); + + HANDLE_CODE(bref.pack(imeisv[2], 4)); + HANDLE_CODE(bref.pack(imeisv[1], 4)); + HANDLE_CODE(bref.pack(imeisv[4], 4)); + HANDLE_CODE(bref.pack(imeisv[3], 4)); + HANDLE_CODE(bref.pack(imeisv[6], 4)); + HANDLE_CODE(bref.pack(imeisv[5], 4)); + HANDLE_CODE(bref.pack(imeisv[8], 4)); + HANDLE_CODE(bref.pack(imeisv[7], 4)); + HANDLE_CODE(bref.pack(imeisv[10], 4)); + HANDLE_CODE(bref.pack(imeisv[9], 4)); + HANDLE_CODE(bref.pack(imeisv[12], 4)); + HANDLE_CODE(bref.pack(imeisv[11], 4)); + HANDLE_CODE(bref.pack(imeisv[14], 4)); + HANDLE_CODE(bref.pack(imeisv[13], 4)); + HANDLE_CODE(bref.pack(0xf, 4)); + HANDLE_CODE(bref.pack(imeisv[15], 4)); + + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::imeisv_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + imeisv[0] = (uint8_t)(tmp >> 1) & 0x0f; + odd_even_indicator = (bool)(tmp & 0x01); // true = odd number + HANDLE_CODE(bref.unpack(imeisv[2], 4)); + HANDLE_CODE(bref.unpack(imeisv[1], 4)); + HANDLE_CODE(bref.unpack(imeisv[4], 4)); + HANDLE_CODE(bref.unpack(imeisv[3], 4)); + HANDLE_CODE(bref.unpack(imeisv[6], 4)); + HANDLE_CODE(bref.unpack(imeisv[5], 4)); + HANDLE_CODE(bref.unpack(imeisv[8], 4)); + HANDLE_CODE(bref.unpack(imeisv[7], 4)); + HANDLE_CODE(bref.unpack(imeisv[10], 4)); + HANDLE_CODE(bref.unpack(imeisv[9], 4)); + HANDLE_CODE(bref.unpack(imeisv[12], 4)); + HANDLE_CODE(bref.unpack(imeisv[11], 4)); + HANDLE_CODE(bref.unpack(imeisv[14], 4)); + HANDLE_CODE(bref.unpack(imeisv[13], 4)); + HANDLE_CODE(bref.advance_bits(4)); + HANDLE_CODE(bref.unpack(imeisv[15], 4)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::mac_address_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::mac_address_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + return SRSASN_SUCCESS; +} + +SRSASN_CODE mobile_identity_5gs_t::eui_64_s::pack(asn1::bit_ref& bref, asn1::bit_ref& bref_tmp) +{ + return SRSASN_SUCCESS; +} +SRSASN_CODE mobile_identity_5gs_t::eui_64_s::unpack(asn1::cbit_ref& bref, uint8_t tmp, uint32_t length) +{ + return SRSASN_SUCCESS; +} + +// IE: 5GMM capability +// Reference: 9.11.3.1 +SRSASN_CODE capability_5gmm_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(sgc, 1)); + HANDLE_CODE(bref.pack(iphc_cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.pack(n3_data, 1)); + HANDLE_CODE(bref.pack(cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.pack(restrict_ec, 1)); + HANDLE_CODE(bref.pack(lpp, 1)); + HANDLE_CODE(bref.pack(ho_attach, 1)); + HANDLE_CODE(bref.pack(s1_mode, 1)); + + HANDLE_CODE(bref.pack(racs, 1)); + HANDLE_CODE(bref.pack(nssaa, 1)); + HANDLE_CODE(bref.pack(lcs_5g, 1)); + HANDLE_CODE(bref.pack(v2_xcnpc5, 1)); + HANDLE_CODE(bref.pack(v2_xcepc5, 1)); + HANDLE_CODE(bref.pack(v2_x, 1)); + HANDLE_CODE(bref.pack(up_c_io_t_5g, 1)); + HANDLE_CODE(bref.pack(srvcc_5g, 1)); + + HANDLE_CODE(bref.advance_bits(4)); + HANDLE_CODE(bref.pack(ehc_cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.pack(multiple_up, 1)); + HANDLE_CODE(bref.pack(wusa, 1)); + HANDLE_CODE(bref.pack(cag, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 13) { + asn1::log_error("Encoding Failed (5GMM capability): Packed length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GMM capability +// Reference: 9.11.3.1 +SRSASN_CODE capability_5gmm_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 13) { + asn1::log_error("Decoding Failed (5GMM capability): Length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(sgc, 1)); + HANDLE_CODE(bref.unpack(iphc_cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.unpack(n3_data, 1)); + HANDLE_CODE(bref.unpack(cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.unpack(restrict_ec, 1)); + HANDLE_CODE(bref.unpack(lpp, 1)); + HANDLE_CODE(bref.unpack(ho_attach, 1)); + HANDLE_CODE(bref.unpack(s1_mode, 1)); + + if (length < 2) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(racs, 1)); + HANDLE_CODE(bref.unpack(nssaa, 1)); + HANDLE_CODE(bref.unpack(lcs_5g, 1)); + HANDLE_CODE(bref.unpack(v2_xcnpc5, 1)); + HANDLE_CODE(bref.unpack(v2_xcepc5, 1)); + HANDLE_CODE(bref.unpack(v2_x, 1)); + HANDLE_CODE(bref.unpack(up_c_io_t_5g, 1)); + HANDLE_CODE(bref.unpack(srvcc_5g, 1)); + + if (length < 3) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.advance_bits(4)); + HANDLE_CODE(bref.unpack(ehc_cp_c_io_t_5g, 1)); + HANDLE_CODE(bref.unpack(multiple_up, 1)); + HANDLE_CODE(bref.unpack(wusa, 1)); + HANDLE_CODE(bref.unpack(cag, 1)); + return SRSASN_SUCCESS; +} + +// IE: UE security capability +// Reference: 9.11.3.54 +SRSASN_CODE ue_security_capability_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(ea0_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea1_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea2_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea3_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea4_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea5_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea6_5g_supported, 1)); + HANDLE_CODE(bref.pack(ea7_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia0_5g_supported, 1)); + + HANDLE_CODE(bref.pack(ia1_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia2_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia3_128_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia4_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia5_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia6_5g_supported, 1)); + HANDLE_CODE(bref.pack(ia7_5g_supported, 1)); + + if (eps_caps_present == true) { + HANDLE_CODE(bref.pack(eea0_supported, 1)); + HANDLE_CODE(bref.pack(eea1_128_supported, 1)); + HANDLE_CODE(bref.pack(eea2_128_supported, 1)); + HANDLE_CODE(bref.pack(eea3_128_supported, 1)); + HANDLE_CODE(bref.pack(eea4_supported, 1)); + HANDLE_CODE(bref.pack(eea5_supported, 1)); + HANDLE_CODE(bref.pack(eea6_supported, 1)); + HANDLE_CODE(bref.pack(eea7_supported, 1)); + HANDLE_CODE(bref.pack(eia0_supported, 1)); + HANDLE_CODE(bref.pack(eia1_128_supported, 1)); + HANDLE_CODE(bref.pack(eia2_128_supported, 1)); + HANDLE_CODE(bref.pack(eia3_128_supported, 1)); + HANDLE_CODE(bref.pack(eia4_supported, 1)); + HANDLE_CODE(bref.pack(eia5_supported, 1)); + HANDLE_CODE(bref.pack(eia6_supported, 1)); + HANDLE_CODE(bref.pack(eia7_supported, 1)); + } + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 8) { + asn1::log_error( + "Encoding Failed (UE security capability): Packed length (%d) is not in range of min: 2 and max 8 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: UE security capability +// Reference: 9.11.3.54 +SRSASN_CODE ue_security_capability_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 8) { + asn1::log_error("Decoding Failed (UE security capability): Length (%d) is not in range of min: 2 and max 8 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(ea0_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea1_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea2_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea3_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea4_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea5_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea6_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ea7_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia0_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia1_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia2_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia3_128_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia4_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia5_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia6_5g_supported, 1)); + HANDLE_CODE(bref.unpack(ia7_5g_supported, 1)); + if (length > 2) { + eps_caps_present = true; + HANDLE_CODE(bref.unpack(eea0_supported, 1)); + HANDLE_CODE(bref.unpack(eea1_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea2_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea3_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea4_supported, 1)); + HANDLE_CODE(bref.unpack(eea5_supported, 1)); + HANDLE_CODE(bref.unpack(eea6_supported, 1)); + HANDLE_CODE(bref.unpack(eea7_supported, 1)); + HANDLE_CODE(bref.unpack(eia0_supported, 1)); + HANDLE_CODE(bref.unpack(eia1_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia2_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia3_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia4_supported, 1)); + HANDLE_CODE(bref.unpack(eia5_supported, 1)); + HANDLE_CODE(bref.unpack(eia6_supported, 1)); + HANDLE_CODE(bref.unpack(eia7_supported, 1)); + } + if (length > 4) { + HANDLE_CODE(bref.advance_bits((length - 4) * 8)); + } + return SRSASN_SUCCESS; +} + +// IE: NSSAI +// Reference: 9.11.3.37 +SRSASN_CODE nssai_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + for (auto& s_nssai : s_nssai_list) { + HANDLE_CODE(s_nssai.pack(bref)); + } + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 144) { + asn1::log_error("Encoding Failed (NSSAI): Packed length (%d) is not in range of min: 2 and max 144 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: NSSAI +// Reference: 9.11.3.37 +SRSASN_CODE nssai_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 144) { + asn1::log_error("Decoding Failed (NSSAI): Length (%d) is not in range of min: 2 and max 144 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + asn1::cbit_ref bref_start = bref; + while (floorl(bref.distance(bref_start) / 8) < length) { + s_nssai_t s_nssai; + HANDLE_CODE(s_nssai.unpack(bref)); + s_nssai_list.push_back(s_nssai); + } + return SRSASN_SUCCESS; +} + +// IE: 5GS tracking area identity +// Reference: 9.11.3.8 +SRSASN_CODE tracking_area_identity_5gs_t::pack(asn1::bit_ref& bref) +{ + pack_mcc_mnc(mcc.data(), mnc.data(), bref); + HANDLE_CODE(bref.pack(tac, 3 * 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS tracking area identity +// Reference: 9.11.3.8 +SRSASN_CODE tracking_area_identity_5gs_t::unpack(asn1::cbit_ref& bref) +{ + unpack_mcc_mnc(mcc.data(), mnc.data(), bref); + HANDLE_CODE(bref.unpack(tac, 3 * 8)); + return SRSASN_SUCCESS; +} + +// IE: S1 UE network capability +// Reference: 9.11.3.48 +SRSASN_CODE s1_ue_network_capability_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(eea0_supported, 1)); + HANDLE_CODE(bref.pack(eea1_128_supported, 1)); + HANDLE_CODE(bref.pack(eea2_128_supported, 1)); + HANDLE_CODE(bref.pack(eea3_128_supported, 1)); + HANDLE_CODE(bref.pack(eea4_supported, 1)); + HANDLE_CODE(bref.pack(eea5_supported, 1)); + HANDLE_CODE(bref.pack(eea6_supported, 1)); + HANDLE_CODE(bref.pack(eea7_supported, 1)); + HANDLE_CODE(bref.pack(eia0_supported, 1)); + + HANDLE_CODE(bref.pack(eia1_128_supported, 1)); + HANDLE_CODE(bref.pack(eia2_128_supported, 1)); + HANDLE_CODE(bref.pack(eia3_128_supported, 1)); + HANDLE_CODE(bref.pack(eia4_supported, 1)); + HANDLE_CODE(bref.pack(eia5_supported, 1)); + HANDLE_CODE(bref.pack(eia6_supported, 1)); + HANDLE_CODE(bref.pack(eia7_supported, 1)); + + HANDLE_CODE(bref.pack(uea0_supported, 1)); + HANDLE_CODE(bref.pack(uea1_128_supported, 1)); + HANDLE_CODE(bref.pack(uea2_128_supported, 1)); + HANDLE_CODE(bref.pack(uea3_128_supported, 1)); + HANDLE_CODE(bref.pack(uea4_supported, 1)); + HANDLE_CODE(bref.pack(uea5_supported, 1)); + HANDLE_CODE(bref.pack(uea6_supported, 1)); + HANDLE_CODE(bref.pack(uea7_supported, 1)); + + HANDLE_CODE(bref.pack(ucs2_support, 1)); + HANDLE_CODE(bref.pack(uia1_128_supported, 1)); + HANDLE_CODE(bref.pack(uia2_128_supported, 1)); + HANDLE_CODE(bref.pack(uia3_128_supported, 1)); + HANDLE_CODE(bref.pack(uia4_supported, 1)); + HANDLE_CODE(bref.pack(uia5_supported, 1)); + HANDLE_CODE(bref.pack(uia6_supported, 1)); + HANDLE_CODE(bref.pack(uia7_supported, 1)); + + HANDLE_CODE(bref.pack(pro_se_dd_supported, 1)); + HANDLE_CODE(bref.pack(pro_se_supported, 1)); + HANDLE_CODE(bref.pack(h245_ash_supported, 1)); + HANDLE_CODE(bref.pack(acc_csfb_supported, 1)); + HANDLE_CODE(bref.pack(llp_supported, 1)); + HANDLE_CODE(bref.pack(lcs_supported, 1)); + HANDLE_CODE(bref.pack(srvcc_capability_supported, 1)); + HANDLE_CODE(bref.pack(nf_capability_supported, 1)); + + HANDLE_CODE(bref.pack(e_pco_supported, 1)); + HANDLE_CODE(bref.pack(hc_cp_c_io_t_supported, 1)); + HANDLE_CODE(bref.pack(e_rw_o_pdn_supported, 1)); + HANDLE_CODE(bref.pack(s1_u_data_supported, 1)); + HANDLE_CODE(bref.pack(up_c_io_t_supported, 1)); + HANDLE_CODE(bref.pack(cp_c_io_t_supported, 1)); + HANDLE_CODE(bref.pack(pro_se_relay_supported, 1)); + + HANDLE_CODE(bref.pack(pro_se_dc_supported, 1)); + HANDLE_CODE(bref.pack(max_15_eps_bearer_supported, 1)); + HANDLE_CODE(bref.pack(sgc_supported, 1)); + HANDLE_CODE(bref.pack(n1mode_supported, 1)); + HANDLE_CODE(bref.pack(dcnr_supported, 1)); + HANDLE_CODE(bref.pack(cp_backoff_supported, 1)); + HANDLE_CODE(bref.pack(restrict_ec_supported, 1)); + HANDLE_CODE(bref.pack(v2_x_pc5_supported, 1)); + HANDLE_CODE(bref.pack(multiple_drb_supported, 1)); + + HANDLE_CODE(bref.advance_bits(3)); + HANDLE_CODE(bref.pack(nr_pc5_supported, 1)); + HANDLE_CODE(bref.pack(up_mt_edt_supported, 1)); + HANDLE_CODE(bref.pack(cp_mt_edt_supported, 1)); + HANDLE_CODE(bref.pack(wus_supported, 1)); + HANDLE_CODE(bref.pack(racs_supported, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 13) { + asn1::log_error( + "Encoding Failed (S1 UE network capability): Packed length (%d) is not in range of min: 2 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: S1 UE network capability +// Reference: 9.11.3.48 +SRSASN_CODE s1_ue_network_capability_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 13) { + asn1::log_error( + "Decoding Failed (S1 UE network capability): Length (%d) is not in range of min: 2 and max 13 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(eea0_supported, 1)); + HANDLE_CODE(bref.unpack(eea1_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea2_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea3_128_supported, 1)); + HANDLE_CODE(bref.unpack(eea4_supported, 1)); + HANDLE_CODE(bref.unpack(eea5_supported, 1)); + HANDLE_CODE(bref.unpack(eea6_supported, 1)); + HANDLE_CODE(bref.unpack(eea7_supported, 1)); + + HANDLE_CODE(bref.unpack(eia0_supported, 1)); + HANDLE_CODE(bref.unpack(eia1_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia2_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia3_128_supported, 1)); + HANDLE_CODE(bref.unpack(eia4_supported, 1)); + HANDLE_CODE(bref.unpack(eia5_supported, 1)); + HANDLE_CODE(bref.unpack(eia6_supported, 1)); + HANDLE_CODE(bref.unpack(eia7_supported, 1)); + + if (length < 3) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(uea0_supported, 1)); + HANDLE_CODE(bref.unpack(uea1_128_supported, 1)); + HANDLE_CODE(bref.unpack(uea2_128_supported, 1)); + HANDLE_CODE(bref.unpack(uea3_128_supported, 1)); + HANDLE_CODE(bref.unpack(uea4_supported, 1)); + HANDLE_CODE(bref.unpack(uea5_supported, 1)); + HANDLE_CODE(bref.unpack(uea6_supported, 1)); + HANDLE_CODE(bref.unpack(uea7_supported, 1)); + + if (length < 4) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(ucs2_support, 1)); + HANDLE_CODE(bref.unpack(uia1_128_supported, 1)); + HANDLE_CODE(bref.unpack(uia2_128_supported, 1)); + HANDLE_CODE(bref.unpack(uia3_128_supported, 1)); + HANDLE_CODE(bref.unpack(uia4_supported, 1)); + HANDLE_CODE(bref.unpack(uia5_supported, 1)); + HANDLE_CODE(bref.unpack(uia6_supported, 1)); + HANDLE_CODE(bref.unpack(uia7_supported, 1)); + + if (length < 5) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(pro_se_dd_supported, 1)); + HANDLE_CODE(bref.unpack(pro_se_supported, 1)); + HANDLE_CODE(bref.unpack(h245_ash_supported, 1)); + HANDLE_CODE(bref.unpack(acc_csfb_supported, 1)); + HANDLE_CODE(bref.unpack(llp_supported, 1)); + HANDLE_CODE(bref.unpack(lcs_supported, 1)); + HANDLE_CODE(bref.unpack(srvcc_capability_supported, 1)); + HANDLE_CODE(bref.unpack(nf_capability_supported, 1)); + + if (length < 6) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(e_pco_supported, 1)); + HANDLE_CODE(bref.unpack(hc_cp_c_io_t_supported, 1)); + HANDLE_CODE(bref.unpack(e_rw_o_pdn_supported, 1)); + HANDLE_CODE(bref.unpack(s1_u_data_supported, 1)); + HANDLE_CODE(bref.unpack(up_c_io_t_supported, 1)); + HANDLE_CODE(bref.unpack(cp_c_io_t_supported, 1)); + HANDLE_CODE(bref.unpack(pro_se_relay_supported, 1)); + HANDLE_CODE(bref.unpack(pro_se_dc_supported, 1)); + + if (length < 7) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(max_15_eps_bearer_supported, 1)); + HANDLE_CODE(bref.unpack(sgc_supported, 1)); + HANDLE_CODE(bref.unpack(n1mode_supported, 1)); + HANDLE_CODE(bref.unpack(dcnr_supported, 1)); + HANDLE_CODE(bref.unpack(cp_backoff_supported, 1)); + HANDLE_CODE(bref.unpack(restrict_ec_supported, 1)); + HANDLE_CODE(bref.unpack(v2_x_pc5_supported, 1)); + HANDLE_CODE(bref.unpack(multiple_drb_supported, 1)); + + if (length < 8) { + return SRSASN_SUCCESS; + } + // 3 spare bits + bref.advance_bits(3); + + HANDLE_CODE(bref.unpack(nr_pc5_supported, 1)); + HANDLE_CODE(bref.unpack(up_mt_edt_supported, 1)); + HANDLE_CODE(bref.unpack(cp_mt_edt_supported, 1)); + HANDLE_CODE(bref.unpack(wus_supported, 1)); + HANDLE_CODE(bref.unpack(racs_supported, 1)); + return SRSASN_SUCCESS; +} + +// IE: Uplink data status +// Reference: 9.11.3.57 +SRSASN_CODE uplink_data_status_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(psi_7, 1)); + HANDLE_CODE(bref.pack(psi_6, 1)); + HANDLE_CODE(bref.pack(psi_5, 1)); + HANDLE_CODE(bref.pack(psi_4, 1)); + HANDLE_CODE(bref.pack(psi_3, 1)); + HANDLE_CODE(bref.pack(psi_2, 1)); + HANDLE_CODE(bref.pack(psi_1, 1)); + HANDLE_CODE(bref.pack(psi_0, 1)); + HANDLE_CODE(bref.pack(psi_15, 1)); + HANDLE_CODE(bref.pack(psi_14, 1)); + HANDLE_CODE(bref.pack(psi_13, 1)); + HANDLE_CODE(bref.pack(psi_12, 1)); + HANDLE_CODE(bref.pack(psi_11, 1)); + HANDLE_CODE(bref.pack(psi_10, 1)); + HANDLE_CODE(bref.pack(psi_9, 1)); + HANDLE_CODE(bref.pack(psi_8, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 32) { + asn1::log_error( + "Encoding Failed (Uplink data status): Packed length (%d) is not in range of min: 2 and max 32 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Uplink data status +// Reference: 9.11.3.57 +SRSASN_CODE uplink_data_status_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 32) { + asn1::log_error("Decoding Failed (Uplink data status): Length (%d) is not in range of min: 2 and max 32 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(psi_7, 1)); + HANDLE_CODE(bref.unpack(psi_6, 1)); + HANDLE_CODE(bref.unpack(psi_5, 1)); + HANDLE_CODE(bref.unpack(psi_4, 1)); + HANDLE_CODE(bref.unpack(psi_3, 1)); + HANDLE_CODE(bref.unpack(psi_2, 1)); + HANDLE_CODE(bref.unpack(psi_1, 1)); + HANDLE_CODE(bref.unpack(psi_0, 1)); + HANDLE_CODE(bref.unpack(psi_15, 1)); + HANDLE_CODE(bref.unpack(psi_14, 1)); + HANDLE_CODE(bref.unpack(psi_13, 1)); + HANDLE_CODE(bref.unpack(psi_12, 1)); + HANDLE_CODE(bref.unpack(psi_11, 1)); + HANDLE_CODE(bref.unpack(psi_10, 1)); + HANDLE_CODE(bref.unpack(psi_9, 1)); + HANDLE_CODE(bref.unpack(psi_8, 1)); + + if (length > 2) { + bref.advance_bits((length - 2) * 8); + } + return SRSASN_SUCCESS; +} + +// IE: PDU session status +// Reference: 9.11.3.44 +SRSASN_CODE pdu_session_status_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(psi_7, 1)); + HANDLE_CODE(bref.pack(psi_6, 1)); + HANDLE_CODE(bref.pack(psi_5, 1)); + HANDLE_CODE(bref.pack(psi_4, 1)); + HANDLE_CODE(bref.pack(psi_3, 1)); + HANDLE_CODE(bref.pack(psi_2, 1)); + HANDLE_CODE(bref.pack(psi_1, 1)); + HANDLE_CODE(bref.pack(psi_0, 1)); + HANDLE_CODE(bref.pack(psi_15, 1)); + HANDLE_CODE(bref.pack(psi_14, 1)); + HANDLE_CODE(bref.pack(psi_13, 1)); + HANDLE_CODE(bref.pack(psi_12, 1)); + HANDLE_CODE(bref.pack(psi_11, 1)); + HANDLE_CODE(bref.pack(psi_10, 1)); + HANDLE_CODE(bref.pack(psi_9, 1)); + HANDLE_CODE(bref.pack(psi_8, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 32) { + asn1::log_error( + "Encoding Failed (PDU session status): Packed length (%d) is not in range of min: 2 and max 32 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: PDU session status +// Reference: 9.11.3.44 +SRSASN_CODE pdu_session_status_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 32) { + asn1::log_error("Decoding Failed (PDU session status): Length (%d) is not in range of min: 2 and max 32 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(psi_7, 1)); + HANDLE_CODE(bref.unpack(psi_6, 1)); + HANDLE_CODE(bref.unpack(psi_5, 1)); + HANDLE_CODE(bref.unpack(psi_4, 1)); + HANDLE_CODE(bref.unpack(psi_3, 1)); + HANDLE_CODE(bref.unpack(psi_2, 1)); + HANDLE_CODE(bref.unpack(psi_1, 1)); + HANDLE_CODE(bref.unpack(psi_0, 1)); + HANDLE_CODE(bref.unpack(psi_15, 1)); + HANDLE_CODE(bref.unpack(psi_14, 1)); + HANDLE_CODE(bref.unpack(psi_13, 1)); + HANDLE_CODE(bref.unpack(psi_12, 1)); + HANDLE_CODE(bref.unpack(psi_11, 1)); + HANDLE_CODE(bref.unpack(psi_10, 1)); + HANDLE_CODE(bref.unpack(psi_9, 1)); + HANDLE_CODE(bref.unpack(psi_8, 1)); + + if (length > 2) { + bref.advance_bits((length - 2) * 8); + } + return SRSASN_SUCCESS; +} + +// IE: MICO indication +// Reference: 9.11.3.31 +SRSASN_CODE mico_indication_t::pack(asn1::bit_ref& bref) +{ + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(bref.pack(sprti, 1)); + HANDLE_CODE(bref.pack(aai, 1)); + return SRSASN_SUCCESS; +} + +// IE: MICO indication +// Reference: 9.11.3.31 +SRSASN_CODE mico_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(bref.unpack(sprti, 1)); + HANDLE_CODE(bref.unpack(aai, 1)); + return SRSASN_SUCCESS; +} + +// IE: UE status +// Reference: 9.11.3.56 +SRSASN_CODE ue_status_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 6 Spare bits + HANDLE_CODE(bref.pack(0x0, 6)); + HANDLE_CODE(bref.pack(n1_mode_reg, 1)); + HANDLE_CODE(bref.pack(s1_mode_reg, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (UE status): Packed length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: UE status +// Reference: 9.11.3.56 +SRSASN_CODE ue_status_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (UE status): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 6 Spare bits + bref.advance_bits(6); + HANDLE_CODE(bref.unpack(n1_mode_reg, 1)); + HANDLE_CODE(bref.unpack(s1_mode_reg, 1)); + return SRSASN_SUCCESS; +} + +// IE: Allowed PDU session status +// Reference: 9.11.3.13 +SRSASN_CODE allowed_pdu_session_status_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(psi_7, 1)); + HANDLE_CODE(bref.pack(psi_6, 1)); + HANDLE_CODE(bref.pack(psi_5, 1)); + HANDLE_CODE(bref.pack(psi_4, 1)); + HANDLE_CODE(bref.pack(psi_3, 1)); + HANDLE_CODE(bref.pack(psi_2, 1)); + HANDLE_CODE(bref.pack(psi_1, 1)); + HANDLE_CODE(bref.pack(psi_0, 1)); + HANDLE_CODE(bref.pack(psi_15, 1)); + HANDLE_CODE(bref.pack(psi_14, 1)); + HANDLE_CODE(bref.pack(psi_13, 1)); + HANDLE_CODE(bref.pack(psi_12, 1)); + HANDLE_CODE(bref.pack(psi_11, 1)); + HANDLE_CODE(bref.pack(psi_10, 1)); + HANDLE_CODE(bref.pack(psi_9, 1)); + HANDLE_CODE(bref.pack(psi_8, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 32) { + asn1::log_error( + "Encoding Failed (Allowed PDU session status): Packed length (%d) is not in range of min: 2 and max 32 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Allowed PDU session status +// Reference: 9.11.3.13 +SRSASN_CODE allowed_pdu_session_status_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 32) { + asn1::log_error( + "Decoding Failed (Allowed PDU session status): Length (%d) is not in range of min: 2 and max 32 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(psi_7, 1)); + HANDLE_CODE(bref.unpack(psi_6, 1)); + HANDLE_CODE(bref.unpack(psi_5, 1)); + HANDLE_CODE(bref.unpack(psi_4, 1)); + HANDLE_CODE(bref.unpack(psi_3, 1)); + HANDLE_CODE(bref.unpack(psi_2, 1)); + HANDLE_CODE(bref.unpack(psi_1, 1)); + HANDLE_CODE(bref.unpack(psi_0, 1)); + HANDLE_CODE(bref.unpack(psi_15, 1)); + HANDLE_CODE(bref.unpack(psi_14, 1)); + HANDLE_CODE(bref.unpack(psi_13, 1)); + HANDLE_CODE(bref.unpack(psi_12, 1)); + HANDLE_CODE(bref.unpack(psi_11, 1)); + HANDLE_CODE(bref.unpack(psi_10, 1)); + HANDLE_CODE(bref.unpack(psi_9, 1)); + HANDLE_CODE(bref.unpack(psi_8, 1)); + + if (length > 2) { + bref.advance_bits((length - 2) * 8); + } + return SRSASN_SUCCESS; +} + +// IE: UE usage setting +// Reference: 9.11.3.55 +SRSASN_CODE ue_usage_setting_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 7 Spare bits + HANDLE_CODE(bref.pack(0x0, 7)); + HANDLE_CODE(ue_usage_setting.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (UE usage setting): Packed length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: UE usage setting +// Reference: 9.11.3.55 +SRSASN_CODE ue_usage_setting_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (UE usage setting): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 7 Spare bits + bref.advance_bits(7); + HANDLE_CODE(ue_usage_setting.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GS DRX parameters +// Reference: 9.11.3.2A +SRSASN_CODE drx_parameters_5gs_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 4 Spare bits + HANDLE_CODE(bref.pack(0x0, 4)); + HANDLE_CODE(drx_value.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (5GS DRX parameters): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS DRX parameters +// Reference: 9.11.3.2A +SRSASN_CODE drx_parameters_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (5GS DRX parameters): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 4 Spare bits + bref.advance_bits(4); + HANDLE_CODE(drx_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: EPS NAS message container +// Reference: 9.11.3.24 +SRSASN_CODE eps_nas_message_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE(bref.pack_bytes(eps_nas_message_container.data(), eps_nas_message_container.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: EPS NAS message container +// Reference: 9.11.3.24 +SRSASN_CODE eps_nas_message_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + eps_nas_message_container.resize(length); + HANDLE_CODE(bref.unpack_bytes(eps_nas_message_container.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: LADN indication +// Reference: 9.11.3.29 +SRSASN_CODE ladn_indication_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + for (auto& dnn : ladn_dnn_values) { + HANDLE_CODE(dnn.pack(bref)); + } + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MIN 0 not check because auf uint underflow + if (length > 808) { + asn1::log_error("Encoding Failed (LADN indication): Packed length (%d) is not in range of max 808 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: LADN indication +// Reference: 9.11.3.29 +SRSASN_CODE ladn_indication_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MIN 0 not check because auf uint underflow + if (length > 808) { + asn1::log_error("Decoding Failed (LADN indication): Length (%d) is not in range of max 808 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + asn1::cbit_ref bref_start = bref; + while (floorl(bref.distance(bref_start) / 8) < length) { + dnn_t dnn; + dnn.unpack(bref); + ladn_dnn_values.push_back(dnn); + } + return SRSASN_SUCCESS; +} + +// IE: Payload container type +// Reference: 9.11.3.40 +SRSASN_CODE payload_container_type_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(payload_container_type.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Payload container type +// Reference: 9.11.3.40 +SRSASN_CODE payload_container_type_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(payload_container_type.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Payload container +// Reference: 9.11.3.39 +SRSASN_CODE payload_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE(bref.pack_bytes(payload_container_contents.data(), payload_container_contents.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error("Encoding Failed (Payload container): Packed length (%d) is not in range of min: 1 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Payload container +// Reference: 9.11.3.39 +SRSASN_CODE payload_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error("Decoding Failed (Payload container): Length (%d) is not in range of min: 1 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + payload_container_contents.resize(length); + HANDLE_CODE(bref.unpack_bytes(payload_container_contents.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Network slicing indication +// Reference: 9.11.3.36 +SRSASN_CODE network_slicing_indication_t::pack(asn1::bit_ref& bref) +{ + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(bref.pack(nssci, 1)); + HANDLE_CODE(bref.pack(dcni, 1)); + return SRSASN_SUCCESS; +} + +// IE: Network slicing indication +// Reference: 9.11.3.36 +SRSASN_CODE network_slicing_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(bref.unpack(nssci, 1)); + HANDLE_CODE(bref.unpack(dcni, 1)); + return SRSASN_SUCCESS; +} + +// IE: 5GS update type +// Reference: 9.11.3.9A +SRSASN_CODE update_type_5gs_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(pnb_eps_c_io_t.pack(bref)); + HANDLE_CODE(pnb_5gs_c_io_t.pack(bref)); + HANDLE_CODE(ng_ran_rcu.pack(bref)); + HANDLE_CODE(sms_requested.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS update type +// Reference: 9.11.3.9A +SRSASN_CODE update_type_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(pnb_eps_c_io_t.unpack(bref)); + HANDLE_CODE(pnb_5gs_c_io_t.unpack(bref)); + HANDLE_CODE(ng_ran_rcu.unpack(bref)); + HANDLE_CODE(sms_requested.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Mobile station classmark 2 +// Reference: 9.11.3.31C +SRSASN_CODE mobile_station_classmark_2_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 3) { + asn1::log_error("Encoding Failed (Mobile station classmark 2): Packed length (%d) does not equal expected length 3", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Mobile station classmark 2 +// Reference: 9.11.3.31C +SRSASN_CODE mobile_station_classmark_2_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 3) { + asn1::log_error("Decoding Failed (Mobile station classmark 2): Length (%d) does not equal expected length 3", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Supported codec list +// Reference: 9.11.3.51A +SRSASN_CODE supported_codec_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 3) { + asn1::log_error("Encoding Failed (Supported codec list): Packed length (%d) is not in range of min: 3 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Supported codec list +// Reference: 9.11.3.51A +SRSASN_CODE supported_codec_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 3) { + asn1::log_error("Decoding Failed (Supported codec list): Length (%d) is not in range of min: 3 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: message container +// Reference: 9.11.3.33 +SRSASN_CODE message_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE(bref.pack_bytes(nas_message_container.data(), nas_message_container.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + if (length < 1 || length > 65532) { + asn1::log_error( + "Encoding Failed (message container): Packed length (%d) is not in range of min: 1 and max 65532 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: message container +// Reference: 9.11.3.33 +SRSASN_CODE message_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + if (length < 1 || length > 65532) { + asn1::log_error("Decoding Failed (message container): Length (%d) is not in range of min: 1 and max 65532 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + nas_message_container.resize(length); + HANDLE_CODE(bref.unpack_bytes(nas_message_container.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: EPS bearer context status +// Reference: 9.11.3.23A +SRSASN_CODE eps_bearer_context_status_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(ebi_7, 1)); + HANDLE_CODE(bref.pack(ebi_6, 1)); + HANDLE_CODE(bref.pack(ebi_5, 1)); + HANDLE_CODE(bref.pack(ebi_4, 1)); + HANDLE_CODE(bref.pack(ebi_3, 1)); + HANDLE_CODE(bref.pack(ebi_2, 1)); + HANDLE_CODE(bref.pack(ebi_1, 1)); + HANDLE_CODE(bref.pack(ebi_0, 1)); + HANDLE_CODE(bref.pack(ebi_15, 1)); + HANDLE_CODE(bref.pack(ebi_14, 1)); + HANDLE_CODE(bref.pack(ebi_13, 1)); + HANDLE_CODE(bref.pack(ebi_12, 1)); + HANDLE_CODE(bref.pack(ebi_11, 1)); + HANDLE_CODE(bref.pack(ebi_10, 1)); + HANDLE_CODE(bref.pack(ebi_9, 1)); + HANDLE_CODE(bref.pack(ebi_8, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 2) { + asn1::log_error("Encoding Failed (EPS bearer context status): Packed length (%d) does not equal expected length 2", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: EPS bearer context status +// Reference: 9.11.3.23A +SRSASN_CODE eps_bearer_context_status_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 2) { + asn1::log_error("Decoding Failed (EPS bearer context status): Length (%d) does not equal expected length 2", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(ebi_7, 1)); + HANDLE_CODE(bref.unpack(ebi_6, 1)); + HANDLE_CODE(bref.unpack(ebi_5, 1)); + HANDLE_CODE(bref.unpack(ebi_4, 1)); + HANDLE_CODE(bref.unpack(ebi_3, 1)); + HANDLE_CODE(bref.unpack(ebi_2, 1)); + HANDLE_CODE(bref.unpack(ebi_1, 1)); + HANDLE_CODE(bref.unpack(ebi_0, 1)); + HANDLE_CODE(bref.unpack(ebi_15, 1)); + HANDLE_CODE(bref.unpack(ebi_14, 1)); + HANDLE_CODE(bref.unpack(ebi_13, 1)); + HANDLE_CODE(bref.unpack(ebi_12, 1)); + HANDLE_CODE(bref.unpack(ebi_11, 1)); + HANDLE_CODE(bref.unpack(ebi_10, 1)); + HANDLE_CODE(bref.unpack(ebi_9, 1)); + HANDLE_CODE(bref.unpack(ebi_8, 1)); + return SRSASN_SUCCESS; +} + +// IE: Extended DRX parameters +// Reference: 9.11.3.26A +SRSASN_CODE extended_drx_parameters_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(paging__time__window.pack(bref)); + HANDLE_CODE(e_drx_value.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (Extended DRX parameters): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Extended DRX parameters +// Reference: 9.11.3.26A +SRSASN_CODE extended_drx_parameters_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (Extended DRX parameters): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(paging__time__window.unpack(bref)); + HANDLE_CODE(e_drx_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer 3 +// Reference: 9.11.2.5 +SRSASN_CODE gprs_timer_3_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(unit.pack(bref)); + HANDLE_CODE(bref.pack(timer_value, 5)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (GPRS timer 3): Packed length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer 3 +// Reference: 9.11.2.5 +SRSASN_CODE gprs_timer_3_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (GPRS timer 3): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(unit.unpack(bref)); + HANDLE_CODE(bref.unpack(timer_value, 5)); + return SRSASN_SUCCESS; +} + +// IE: UE radio capability ID +// Reference: 9.11.3.68 +SRSASN_CODE ue_radio_capability_id_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(ue_radio_capability_id.data(), ue_radio_capability_id.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: UE radio capability ID +// Reference: 9.11.3.68 +SRSASN_CODE ue_radio_capability_id_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + ue_radio_capability_id.resize(length); + HANDLE_CODE(bref.unpack_bytes(ue_radio_capability_id.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Mapped NSSAI +// Reference: 9.11.3.31B +SRSASN_CODE mapped_nssai_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 40) { + asn1::log_error("Encoding Failed (Mapped NSSAI): Packed length (%d) is not in range of min: 2 and max 40 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Mapped NSSAI +// Reference: 9.11.3.31B +SRSASN_CODE mapped_nssai_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 40) { + asn1::log_error("Decoding Failed (Mapped NSSAI): Length (%d) is not in range of min: 2 and max 40 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Additional information requested +// Reference: 9.11.3.12A +SRSASN_CODE additional_information_requested_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 7 Spare bits + HANDLE_CODE(bref.pack(0x0, 7)); + HANDLE_CODE(bref.pack(cipher_key, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Additional information requested +// Reference: 9.11.3.12A +SRSASN_CODE additional_information_requested_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); // 7 Spare bits + bref.advance_bits(7); + HANDLE_CODE(bref.unpack(cipher_key, 1)); + return SRSASN_SUCCESS; +} + +// IE: WUS assistance information +// Reference: 9.11.3.71 +SRSASN_CODE wus_assistance_information_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1) { + asn1::log_error("Encoding Failed (WUS assistance information): Packed length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: WUS assistance information +// Reference: 9.11.3.71 +SRSASN_CODE wus_assistance_information_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1) { + asn1::log_error("Decoding Failed (WUS assistance information): Length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: N5GC indication +// Reference: 9.11.3.72 +SRSASN_CODE n5gc_indication_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(n5gcreg, 1)); + return SRSASN_SUCCESS; +} + +// IE: N5GC indication +// Reference: 9.11.3.72 +SRSASN_CODE n5gc_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(n5gcreg, 1)); + return SRSASN_SUCCESS; +} + +// IE: NB-N1 mode DRX parameters +// Reference: 9.11.3.73 +SRSASN_CODE nb_n1_mode_drx_parameters_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 4 Spare bits + HANDLE_CODE(bref.pack(0x0, 4)); + HANDLE_CODE(nb_n1_mode_drx_value.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (NB-N1 mode DRX parameters): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: NB-N1 mode DRX parameters +// Reference: 9.11.3.73 +SRSASN_CODE nb_n1_mode_drx_parameters_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (NB-N1 mode DRX parameters): Length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 4 Spare bits + bref.advance_bits(4); + HANDLE_CODE(nb_n1_mode_drx_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GS registration result +// Reference: 9.11.3.6 +SRSASN_CODE registration_result_5gs_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(emergency_registered.pack(bref)); + HANDLE_CODE(nssaa_to_be_performed.pack(bref)); + HANDLE_CODE(sms_allowed.pack(bref)); + HANDLE_CODE(registration_result.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (5GS registration result): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS registration result +// Reference: 9.11.3.6 +SRSASN_CODE registration_result_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (5GS registration result): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(emergency_registered.unpack(bref)); + HANDLE_CODE(nssaa_to_be_performed.unpack(bref)); + HANDLE_CODE(sms_allowed.unpack(bref)); + HANDLE_CODE(registration_result.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: PLMN list +// Reference: 9.11.3.45 +SRSASN_CODE plmn_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: PLMN list +// Reference: 9.11.3.45 +SRSASN_CODE plmn_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: 5GS tracking area identity list +// Reference: 9.11.3.9 +SRSASN_CODE tracking_area_identity_list_5gs_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 7) { + asn1::log_error( + "Encoding Failed (5GS tracking area identity list): Packed length (%d) does not equal expected length 7", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS tracking area identity list +// Reference: 9.11.3.9 +SRSASN_CODE tracking_area_identity_list_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 7) { + asn1::log_error("Decoding Failed (5GS tracking area identity list): Length (%d) does not equal expected length 7", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Rejected NSSAI +// Reference: 9.11.3.46 +SRSASN_CODE rejected_nssai_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Rejected NSSAI +// Reference: 9.11.3.46 +SRSASN_CODE rejected_nssai_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: 5GS network feature support +// Reference: 9.11.3.5 +SRSASN_CODE network_feature_support_5gs_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 3) { + asn1::log_error( + "Encoding Failed (5GS network feature support): Packed length (%d) is not in range of min: 1 and max 3 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GS network feature support +// Reference: 9.11.3.5 +SRSASN_CODE network_feature_support_5gs_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 3) { + asn1::log_error( + "Decoding Failed (5GS network feature support): Length (%d) is not in range of min: 1 and max 3 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: PDU session reactivation result +// Reference: 9.11.3.42 +SRSASN_CODE pdu_session_reactivation_result_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(psi_7, 1)); + HANDLE_CODE(bref.pack(psi_6, 1)); + HANDLE_CODE(bref.pack(psi_5, 1)); + HANDLE_CODE(bref.pack(psi_4, 1)); + HANDLE_CODE(bref.pack(psi_3, 1)); + HANDLE_CODE(bref.pack(psi_2, 1)); + HANDLE_CODE(bref.pack(psi_1, 1)); + HANDLE_CODE(bref.pack(psi_0, 1)); + HANDLE_CODE(bref.pack(psi_15, 1)); + HANDLE_CODE(bref.pack(psi_14, 1)); + HANDLE_CODE(bref.pack(psi_13, 1)); + HANDLE_CODE(bref.pack(psi_12, 1)); + HANDLE_CODE(bref.pack(psi_11, 1)); + HANDLE_CODE(bref.pack(psi_10, 1)); + HANDLE_CODE(bref.pack(psi_9, 1)); + HANDLE_CODE(bref.pack(psi_8, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 32) { + asn1::log_error("Encoding Failed (PDU session reactivation result): Packed length (%d) is not in range of min: 2 " + "and max 32 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: PDU session reactivation result +// Reference: 9.11.3.42 +SRSASN_CODE pdu_session_reactivation_result_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 32) { + asn1::log_error( + "Decoding Failed (PDU session reactivation result): Length (%d) is not in range of min: 2 and max 32 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + HANDLE_CODE(bref.unpack(psi_7, 1)); + HANDLE_CODE(bref.unpack(psi_6, 1)); + HANDLE_CODE(bref.unpack(psi_5, 1)); + HANDLE_CODE(bref.unpack(psi_4, 1)); + HANDLE_CODE(bref.unpack(psi_3, 1)); + HANDLE_CODE(bref.unpack(psi_2, 1)); + HANDLE_CODE(bref.unpack(psi_1, 1)); + HANDLE_CODE(bref.unpack(psi_0, 1)); + + HANDLE_CODE(bref.unpack(psi_15, 1)); + HANDLE_CODE(bref.unpack(psi_14, 1)); + HANDLE_CODE(bref.unpack(psi_13, 1)); + HANDLE_CODE(bref.unpack(psi_12, 1)); + HANDLE_CODE(bref.unpack(psi_11, 1)); + HANDLE_CODE(bref.unpack(psi_10, 1)); + HANDLE_CODE(bref.unpack(psi_9, 1)); + HANDLE_CODE(bref.unpack(psi_8, 1)); + + if (length > 2) { + HANDLE_CODE(bref.advance_bits((length - 2) * 8)); + } + return SRSASN_SUCCESS; +} + +// IE: PDU session reactivation result error cause +// Reference: 9.11.3.43 +SRSASN_CODE pdu_session_reactivation_result_error_cause_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + if (length < 2 || length > 512) { + asn1::log_error("Encoding Failed (PDU session reactivation result error cause): Packed length (%d) is not in range " + "of min: 2 and max 512 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: PDU session reactivation result error cause +// Reference: 9.11.3.43 +SRSASN_CODE pdu_session_reactivation_result_error_cause_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + if (length < 2 || length > 512) { + asn1::log_error("Decoding Failed (PDU session reactivation result error cause): Length (%d) is not in range of " + "min: 2 and max 512 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: LADN information +// Reference: 9.11.3.30 +SRSASN_CODE ladn_information_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MIN 0 not check because auf uint underflow + if (length > 1712) { + asn1::log_error("Encoding Failed (LADN information): Packed length (%d) is not in range of max 1712 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: LADN information +// Reference: 9.11.3.30 +SRSASN_CODE ladn_information_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MIN 0 not check because auf uint underflow + if (length > 1712) { + asn1::log_error("Decoding Failed (LADN information): Length (%d) is not in range of max 1712 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Service area list +// Reference: 9.11.3.49 +SRSASN_CODE service_area_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Service area list +// Reference: 9.11.3.49 +SRSASN_CODE service_area_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer 2 +// Reference: 9.11.2.4 +SRSASN_CODE gprs_timer_2_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(timer_value, 8)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (GPRS timer 2): Packed length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer 2 +// Reference: 9.11.2.4 +SRSASN_CODE gprs_timer_2_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (GPRS timer 2): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(timer_value, 8)); + return SRSASN_SUCCESS; +} + +// IE: Emergency number list +// Reference: 9.11.3.23 +SRSASN_CODE emergency_number_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 3 || length > 48) { + asn1::log_error( + "Encoding Failed (Emergency number list): Packed length (%d) is not in range of min: 3 and max 48 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Emergency number list +// Reference: 9.11.3.23 +SRSASN_CODE emergency_number_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 3 || length > 48) { + asn1::log_error("Decoding Failed (Emergency number list): Length (%d) is not in range of min: 3 and max 48 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Extended emergency number list +// Reference: 9.11.3.26 +SRSASN_CODE extended_emergency_number_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error( + "Encoding Failed (Extended emergency number list): Packed length (%d) is not in range of min: 4 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Extended emergency number list +// Reference: 9.11.3.26 +SRSASN_CODE extended_emergency_number_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error("Decoding Failed (Extended emergency number list): Length (%d) is not in range of min: 4 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: SOR transparent container +// Reference: 9.11.3.51 +SRSASN_CODE sor_transparent_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + if (length < 17) { + asn1::log_error("Encoding Failed (SOR transparent container): Packed length (%d) is not in range of min: 17 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: SOR transparent container +// Reference: 9.11.3.51 +SRSASN_CODE sor_transparent_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + if (length < 17) { + asn1::log_error("Decoding Failed (SOR transparent container): Length (%d) is not in range of min: 17 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: EAP message +// Reference: 9.11.2.2 +SRSASN_CODE eap_message_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE(bref.pack_bytes(eap_message.data(), eap_message.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + if (length < 4 || length > 1500) { + asn1::log_error("Encoding Failed (EAP message): Packed length (%d) is not in range of min: 4 and max 1500 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: EAP message +// Reference: 9.11.2.2 +SRSASN_CODE eap_message_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + if (length < 4 || length > 1500) { + asn1::log_error("Decoding Failed (EAP message): Length (%d) is not in range of min: 4 and max 1500 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + eap_message.resize(length); + HANDLE_CODE(bref.unpack_bytes(eap_message.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: NSSAI inclusion mode +// Reference: 9.11.3.37A +SRSASN_CODE nssai_inclusion_mode_t::pack(asn1::bit_ref& bref) +{ + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(nssai_inclusion_mode.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: NSSAI inclusion mode +// Reference: 9.11.3.37A +SRSASN_CODE nssai_inclusion_mode_t::unpack(asn1::cbit_ref& bref) +{ + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(nssai_inclusion_mode.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Operator-defined access category definitions +// Reference: 9.11.3.38 +SRSASN_CODE operator_defined_access_category_definitions_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Operator-defined access category definitions +// Reference: 9.11.3.38 +SRSASN_CODE operator_defined_access_category_definitions_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Non-3GPP NW provided policies +// Reference: 9.11.3.36A +SRSASN_CODE non_3_gpp_nw_provided_policies_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(n3_en, 1)); + return SRSASN_SUCCESS; +} + +// IE: Non-3GPP NW provided policies +// Reference: 9.11.3.36A +SRSASN_CODE non_3_gpp_nw_provided_policies_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(n3_en, 1)); + return SRSASN_SUCCESS; +} + +// IE: UE radio capability ID deletion indication +// Reference: 9.11.3.69 +SRSASN_CODE ue_radio_capability_id_deletion_indication_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(deletion_request.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: UE radio capability ID deletion indication +// Reference: 9.11.3.69 +SRSASN_CODE ue_radio_capability_id_deletion_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(deletion_request.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Ciphering key data +// Reference: 9.11.3.18C +SRSASN_CODE ciphering_key_data_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + if (length < 31 || length > 2672) { + asn1::log_error( + "Encoding Failed (Ciphering key data): Packed length (%d) is not in range of min: 31 and max 2672 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Ciphering key data +// Reference: 9.11.3.18C +SRSASN_CODE ciphering_key_data_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + if (length < 31 || length > 2672) { + asn1::log_error("Decoding Failed (Ciphering key data): Length (%d) is not in range of min: 31 and max 2672 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: CAG information list +// Reference: 9.11.3.18A +SRSASN_CODE cag_information_list_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: CAG information list +// Reference: 9.11.3.18A +SRSASN_CODE cag_information_list_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Truncated 5G-S-TMSI configuration +// Reference: 9.11.3.70 +SRSASN_CODE truncated_5g_s_tmsi_configuration_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(truncated_amf__set_id_value, 4)); + HANDLE_CODE(bref.pack(truncated_amf__pointer_value, 4)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error( + "Encoding Failed (Truncated 5G-S-TMSI configuration): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Truncated 5G-S-TMSI configuration +// Reference: 9.11.3.70 +SRSASN_CODE truncated_5g_s_tmsi_configuration_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (Truncated 5G-S-TMSI configuration): Length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(truncated_amf__set_id_value, 4)); + HANDLE_CODE(bref.unpack(truncated_amf__pointer_value, 4)); + return SRSASN_SUCCESS; +} + +// IE: 5GMM cause +// Reference: 9.11.3.2 +SRSASN_CODE cause_5gmm_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(cause_5gmm.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GMM cause +// Reference: 9.11.3.2 +SRSASN_CODE cause_5gmm_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(cause_5gmm.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: De-registration type +// Reference: 9.11.3.20 +SRSASN_CODE de_registration_type_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(switch_off.pack(bref)); + HANDLE_CODE(re_registration_required.pack(bref)); + HANDLE_CODE(access_type.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: De-registration type +// Reference: 9.11.3.20 +SRSASN_CODE de_registration_type_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(switch_off.unpack(bref)); + HANDLE_CODE(re_registration_required.unpack(bref)); + HANDLE_CODE(access_type.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Spare half octet +// Reference: 9.5 +SRSASN_CODE spare_half_octet_t::pack(asn1::bit_ref& bref) +{ + // 4 Spare bits + HANDLE_CODE(bref.pack(0x0, 4)); + return SRSASN_SUCCESS; +} + +// IE: Spare half octet +// Reference: 9.5 +SRSASN_CODE spare_half_octet_t::unpack(asn1::cbit_ref& bref) +{ + // 4 Spare bits + bref.advance_bits(4); + return SRSASN_SUCCESS; +} + +// IE: Service type +// Reference: 9.11.3.50 +SRSASN_CODE service_type_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(service_type_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Service type +// Reference: 9.11.3.50 +SRSASN_CODE service_type_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(service_type_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Configuration update indication +// Reference: 9.11.3.18 +SRSASN_CODE configuration_update_indication_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(control_plane_service_type_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Configuration update indication +// Reference: 9.11.3.18 +SRSASN_CODE configuration_update_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(control_plane_service_type_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Network name +// Reference: 9.11.3.35 +SRSASN_CODE network_name_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Network name +// Reference: 9.11.3.35 +SRSASN_CODE network_name_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Time zone +// Reference: 9.11.3.52 +SRSASN_CODE time_zone_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(bref.pack(year, 8)); + HANDLE_CODE(bref.pack(month, 8)); + HANDLE_CODE(bref.pack(day, 8)); + HANDLE_CODE(bref.pack(hour, 8)); + HANDLE_CODE(bref.pack(second, 8)); + HANDLE_CODE(bref.pack(time_zone, 8)); + return SRSASN_SUCCESS; +} + +// IE: Time zone +// Reference: 9.11.3.52 +SRSASN_CODE time_zone_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(year, 8)); + HANDLE_CODE(bref.unpack(month, 8)); + HANDLE_CODE(bref.unpack(day, 8)); + HANDLE_CODE(bref.unpack(hour, 8)); + HANDLE_CODE(bref.unpack(second, 8)); + HANDLE_CODE(bref.unpack(time_zone, 8)); + return SRSASN_SUCCESS; +} + +// IE: Time zone and time +// Reference: 9.11.3.53 +SRSASN_CODE time_zone_and_time_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(bref.pack(time_zone, 8)); + return SRSASN_SUCCESS; +} + +// IE: Time zone and time +// Reference: 9.11.3.53 +SRSASN_CODE time_zone_and_time_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(time_zone, 8)); + return SRSASN_SUCCESS; +} + +// IE: Daylight saving time +// Reference: 9.11.3.19 +SRSASN_CODE daylight_saving_time_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(value.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (Daylight saving time): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Daylight saving time +// Reference: 9.11.3.19 +SRSASN_CODE daylight_saving_time_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (Daylight saving time): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: SMS indication +// Reference: 9.11.3.50A +SRSASN_CODE sms_indication_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(sms_availability_indication, 1)); + return SRSASN_SUCCESS; +} + +// IE: SMS indication +// Reference: 9.11.3.50A +SRSASN_CODE sms_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(sms_availability_indication, 1)); + return SRSASN_SUCCESS; +} + +// IE: Additional configuration indication +// Reference: 9.11.3.74 +SRSASN_CODE additional_configuration_indication_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(scmr.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Additional configuration indication +// Reference: 9.11.3.74 +SRSASN_CODE additional_configuration_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(scmr.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: ABBA +// Reference: 9.11.3.10 +SRSASN_CODE abba_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(abba_contents.data(), abba_contents.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2) { + asn1::log_error("Encoding Failed (ABBA): Packed length (%d) is not in range of min: 2 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: ABBA +// Reference: 9.11.3.10 +SRSASN_CODE abba_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2) { + asn1::log_error("Decoding Failed (ABBA): Length (%d) is not in range of min: 2 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + abba_contents.resize(length); + HANDLE_CODE(bref.unpack_bytes(abba_contents.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Authentication parameter RAND +// Reference: 9.11.3.16 +SRSASN_CODE authentication_parameter_rand_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(bref.pack_bytes(rand.data(), 16)); + return SRSASN_SUCCESS; +} + +// IE: Authentication parameter RAND +// Reference: 9.11.3.16 +SRSASN_CODE authentication_parameter_rand_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack_bytes(rand.data(), 16)); + return SRSASN_SUCCESS; +} + +// IE: Authentication parameter AUTN +// Reference: 9.11.3.15 +SRSASN_CODE authentication_parameter_autn_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(autn.data(), autn.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 16) { + asn1::log_error( + "Encoding Failed (Authentication parameter AUTN): Packed length (%d) does not equal expected length 16", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Authentication parameter AUTN +// Reference: 9.11.3.15 +SRSASN_CODE authentication_parameter_autn_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 16) { + asn1::log_error("Decoding Failed (Authentication parameter AUTN): Length (%d) does not equal expected length 16", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + autn.resize(length); + HANDLE_CODE(bref.unpack_bytes(autn.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Authentication response parameter +// Reference: 9.11.3.17 +SRSASN_CODE authentication_response_parameter_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(res.data(), res.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 16) { + asn1::log_error( + "Encoding Failed (Authentication response parameter): Packed length (%d) does not equal expected length 16", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Authentication response parameter +// Reference: 9.11.3.17 +SRSASN_CODE authentication_response_parameter_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 16) { + asn1::log_error( + "Decoding Failed (Authentication response parameter): Length (%d) does not equal expected length 16", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + res.resize(length); + HANDLE_CODE(bref.unpack_bytes(res.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Authentication failure parameter +// Reference: 9.11.3.14 +SRSASN_CODE authentication_failure_parameter_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(auth_failure.data(), auth_failure.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 14) { + asn1::log_error( + "Encoding Failed (Authentication failure parameter): Packed length (%d) does not equal expected length 14", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Authentication failure parameter +// Reference: 9.11.3.14 +SRSASN_CODE authentication_failure_parameter_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 14) { + asn1::log_error("Decoding Failed (Authentication failure parameter): Length (%d) does not equal expected length 14", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + auth_failure.resize(length); + HANDLE_CODE(bref.unpack_bytes(auth_failure.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: 5GS identity type +// Reference: 9.11.3.3 +SRSASN_CODE identity_type_5gs_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(type_of_identity.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GS identity type +// Reference: 9.11.3.3 +SRSASN_CODE identity_type_5gs_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(type_of_identity.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: security algorithms +// Reference: 9.11.3.34 +SRSASN_CODE security_algorithms_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(ciphering_algorithm.pack(bref)); + HANDLE_CODE(integrity_protection_algorithm.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: security algorithms +// Reference: 9.11.3.34 +SRSASN_CODE security_algorithms_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(ciphering_algorithm.unpack(bref)); + HANDLE_CODE(integrity_protection_algorithm.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: IMEISV request +// Reference: 9.11.3.28 +SRSASN_CODE imeisv_request_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(imeisv_request.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: IMEISV request +// Reference: 9.11.3.28 +SRSASN_CODE imeisv_request_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(imeisv_request.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: EPS NAS security algorithms +// Reference: 9.11.3.25 +SRSASN_CODE eps_nas_security_algorithms_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(ciphering_algorithm.pack(bref)); + + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(integrity_protection_algorithm.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: EPS NAS security algorithms +// Reference: 9.11.3.25 +SRSASN_CODE eps_nas_security_algorithms_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(ciphering_algorithm.unpack(bref)); + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(integrity_protection_algorithm.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Additional 5G security information +// Reference: 9.11.3.12 +SRSASN_CODE additional_5g_security_information_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 6 Spare bits + HANDLE_CODE(bref.pack(0x0, 6)); + HANDLE_CODE(bref.pack(rinmr, 1)); + HANDLE_CODE(bref.pack(hdp, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error( + "Encoding Failed (Additional 5G security information): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Additional 5G security information +// Reference: 9.11.3.12 +SRSASN_CODE additional_5g_security_information_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error( + "Decoding Failed (Additional 5G security information): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 6 Spare bits + bref.advance_bits(6); + HANDLE_CODE(bref.unpack(rinmr, 1)); + HANDLE_CODE(bref.unpack(hdp, 1)); + return SRSASN_SUCCESS; +} + +// IE: S1 UE security capability +// Reference: 9.11.3.48A +SRSASN_CODE s1_ue_security_capability_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(eea0, 1)); + HANDLE_CODE(bref.pack(eea1_128, 1)); + HANDLE_CODE(bref.pack(eea2_128, 1)); + HANDLE_CODE(bref.pack(eea3_128, 1)); + HANDLE_CODE(bref.pack(eea4, 1)); + HANDLE_CODE(bref.pack(eea5, 1)); + HANDLE_CODE(bref.pack(eea6, 1)); + HANDLE_CODE(bref.pack(eea7, 1)); + HANDLE_CODE(bref.pack(eia0, 1)); + HANDLE_CODE(bref.pack(eia1_128, 1)); + HANDLE_CODE(bref.pack(eia2_128, 1)); + HANDLE_CODE(bref.pack(eia3_128, 1)); + HANDLE_CODE(bref.pack(eia4, 1)); + HANDLE_CODE(bref.pack(eia5, 1)); + HANDLE_CODE(bref.pack(eia6, 1)); + HANDLE_CODE(bref.pack(eia7, 1)); + HANDLE_CODE(bref.pack(uea0, 1)); + HANDLE_CODE(bref.pack(uea1, 1)); + HANDLE_CODE(bref.pack(uea2, 1)); + HANDLE_CODE(bref.pack(uea3, 1)); + HANDLE_CODE(bref.pack(uea4, 1)); + HANDLE_CODE(bref.pack(uea5, 1)); + HANDLE_CODE(bref.pack(uea6, 1)); + HANDLE_CODE(bref.pack(uea7, 1)); + + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(bref.pack(uia1, 1)); + HANDLE_CODE(bref.pack(uia2, 1)); + HANDLE_CODE(bref.pack(uia3, 1)); + HANDLE_CODE(bref.pack(uia4, 1)); + HANDLE_CODE(bref.pack(uia5, 1)); + HANDLE_CODE(bref.pack(uia6, 1)); + HANDLE_CODE(bref.pack(uia7, 1)); + + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(bref.pack(gea1, 1)); + HANDLE_CODE(bref.pack(gea2, 1)); + HANDLE_CODE(bref.pack(gea3, 1)); + HANDLE_CODE(bref.pack(gea4, 1)); + HANDLE_CODE(bref.pack(gea5, 1)); + HANDLE_CODE(bref.pack(gea6, 1)); + HANDLE_CODE(bref.pack(gea7, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 2 || length > 5) { + asn1::log_error( + "Encoding Failed (S1 UE security capability): Packed length (%d) is not in range of min: 2 and max 5 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: S1 UE security capability +// Reference: 9.11.3.48A +SRSASN_CODE s1_ue_security_capability_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 2 || length > 5) { + asn1::log_error( + "Decoding Failed (S1 UE security capability): Length (%d) is not in range of min: 2 and max 5 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(eea0, 1)); + HANDLE_CODE(bref.unpack(eea1_128, 1)); + HANDLE_CODE(bref.unpack(eea2_128, 1)); + HANDLE_CODE(bref.unpack(eea3_128, 1)); + HANDLE_CODE(bref.unpack(eea4, 1)); + HANDLE_CODE(bref.unpack(eea5, 1)); + HANDLE_CODE(bref.unpack(eea6, 1)); + HANDLE_CODE(bref.unpack(eea7, 1)); + + HANDLE_CODE(bref.unpack(eia0, 1)); + HANDLE_CODE(bref.unpack(eia1_128, 1)); + HANDLE_CODE(bref.unpack(eia2_128, 1)); + HANDLE_CODE(bref.unpack(eia3_128, 1)); + HANDLE_CODE(bref.unpack(eia4, 1)); + HANDLE_CODE(bref.unpack(eia5, 1)); + HANDLE_CODE(bref.unpack(eia6, 1)); + HANDLE_CODE(bref.unpack(eia7, 1)); + + if (length < 3) { + return SRSASN_SUCCESS; + } + + HANDLE_CODE(bref.unpack(uea0, 1)); + HANDLE_CODE(bref.unpack(uea1, 1)); + HANDLE_CODE(bref.unpack(uea2, 1)); + HANDLE_CODE(bref.unpack(uea3, 1)); + HANDLE_CODE(bref.unpack(uea4, 1)); + HANDLE_CODE(bref.unpack(uea5, 1)); + HANDLE_CODE(bref.unpack(uea6, 1)); + HANDLE_CODE(bref.unpack(uea7, 1)); + + if (length < 4) { + return SRSASN_SUCCESS; + } + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(bref.unpack(uia1, 1)); + HANDLE_CODE(bref.unpack(uia2, 1)); + HANDLE_CODE(bref.unpack(uia3, 1)); + HANDLE_CODE(bref.unpack(uia4, 1)); + HANDLE_CODE(bref.unpack(uia5, 1)); + HANDLE_CODE(bref.unpack(uia6, 1)); + HANDLE_CODE(bref.unpack(uia7, 1)); + + if (length < 5) { + return SRSASN_SUCCESS; + } + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(bref.unpack(gea1, 1)); + HANDLE_CODE(bref.unpack(gea2, 1)); + HANDLE_CODE(bref.unpack(gea3, 1)); + HANDLE_CODE(bref.unpack(gea4, 1)); + HANDLE_CODE(bref.unpack(gea5, 1)); + HANDLE_CODE(bref.unpack(gea6, 1)); + HANDLE_CODE(bref.unpack(gea7, 1)); + return SRSASN_SUCCESS; +} + +// IE: Access type +// Reference: 9.11.2.1A +SRSASN_CODE access_type_t::pack(asn1::bit_ref& bref) +{ + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(access_type_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Access type +// Reference: 9.11.2.1A +SRSASN_CODE access_type_t::unpack(asn1::cbit_ref& bref) +{ + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(access_type_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: PDU session identity 2 +// Reference: 9.11.3.41 +SRSASN_CODE pdu_session_identity_2_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(bref.pack(pdu_session_identity_2_value, 8)); + return SRSASN_SUCCESS; +} + +// IE: PDU session identity 2 +// Reference: 9.11.3.41 +SRSASN_CODE pdu_session_identity_2_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(pdu_session_identity_2_value, 8)); + return SRSASN_SUCCESS; +} + +// IE: Request type +// Reference: 9.11.3.47 +SRSASN_CODE request_type_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(request_type_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Request type +// Reference: 9.11.3.47 +SRSASN_CODE request_type_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(request_type_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: S-NSSAI +// Reference: 9.11.2.8 +SRSASN_CODE s_nssai_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + if (length == s_nssai_t::SST_type_::options::sst) { + HANDLE_CODE(bref.pack(sst, 8)); + } else if (length == s_nssai_t::SST_type_::options::sst_and_mapped_hplmn_sst) { + HANDLE_CODE(bref.pack(sst, 8)); + HANDLE_CODE(bref.pack(mapped_hplmn_sst, 8)); + } else if (length == s_nssai_t::SST_type_::options::sst_and_sd) { + HANDLE_CODE(bref.pack(sst, 8)); + HANDLE_CODE(bref.pack(sd, 24)); + } else if (length == s_nssai_t::SST_type_::options::sst_sd_mapped_hplmn_sst_and_mapped_hplmn_sd) { + HANDLE_CODE(bref.pack(sst, 8)); + HANDLE_CODE(bref.pack(sd, 24)); + HANDLE_CODE(bref.pack(mapped_hplmn_sst, 8)); + HANDLE_CODE(bref.pack(mapped_hplmn_sd, 24)); + } else { + asn1::log_error("Not such a length type for s_nssai"); + return SRSASN_ERROR_ENCODE_FAIL; + } + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 8) { + asn1::log_error("Encoding Failed (S-NSSAI): Packed length (%d) is not in range of min: 1 and max 8 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: S-NSSAI +// Reference: 9.11.2.8 +SRSASN_CODE s_nssai_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 8) { + asn1::log_error("Decoding Failed (S-NSSAI): Length (%d) is not in range of min: 1 and max 8 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + if (length == s_nssai_t::SST_type_::options::sst) { + HANDLE_CODE(bref.unpack(sst, 8)); + } else if (length == s_nssai_t::SST_type_::options::sst_and_mapped_hplmn_sst) { + HANDLE_CODE(bref.unpack(sst, 8)); + HANDLE_CODE(bref.unpack(mapped_hplmn_sst, 8)); + } else if (length == s_nssai_t::SST_type_::options::sst_and_sd) { + HANDLE_CODE(bref.unpack(sst, 8)); + HANDLE_CODE(bref.unpack(sd, 24)); + } else if (length == s_nssai_t::SST_type_::options::sst_sd_mapped_hplmn_sst_and_mapped_hplmn_sd) { + HANDLE_CODE(bref.unpack(sst, 8)); + HANDLE_CODE(bref.unpack(sd, 24)); + HANDLE_CODE(bref.unpack(mapped_hplmn_sst, 8)); + HANDLE_CODE(bref.unpack(mapped_hplmn_sd, 24)); + } else { + asn1::log_error("Not such a length type for s_nssai"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// IE: DNN +// Reference: 9.11.2.1B +SRSASN_CODE dnn_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(dnn_value.data(), dnn_value.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 100) { + asn1::log_error("Encoding Failed (DNN): Packed length (%d) is not in range of min: 1 and max 100 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: DNN +// Reference: 9.11.2.1B +SRSASN_CODE dnn_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 100) { + asn1::log_error("Decoding Failed (DNN): Length (%d) is not in range of min: 1 and max 100 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + dnn_value.resize(length); + HANDLE_CODE(bref.unpack_bytes(dnn_value.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Additional information +// Reference: 9.11.2.1 +SRSASN_CODE additional_information_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(additional_information_value.data(), additional_information_value.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1) { + asn1::log_error("Encoding Failed (Additional information): Packed length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Additional information +// Reference: 9.11.2.1 +SRSASN_CODE additional_information_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1) { + asn1::log_error("Decoding Failed (Additional information): Length (%d) is not in range of min: 1 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + additional_information_value.resize(length); + HANDLE_CODE(bref.unpack_bytes(additional_information_value.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: MA PDU session information +// Reference: 9.11.3.31A +SRSASN_CODE ma_pdu_session_information_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(ma_pdu_session_information_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: MA PDU session information +// Reference: 9.11.3.31A +SRSASN_CODE ma_pdu_session_information_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(ma_pdu_session_information_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Release assistance indication +// Reference: 9.11.3.46A +SRSASN_CODE release_assistance_indication_t::pack(asn1::bit_ref& bref) +{ + // 2 Spare bits + HANDLE_CODE(bref.pack(0x0, 2)); + HANDLE_CODE(downlink_data_expected.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Release assistance indication +// Reference: 9.11.3.46A +SRSASN_CODE release_assistance_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 2 Spare bits + bref.advance_bits(2); + HANDLE_CODE(downlink_data_expected.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Integrity protection maximum data rate +// Reference: 9.11.4.7 +SRSASN_CODE integrity_protection_maximum_data_rate_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(max_data_rate_upip_uplink.pack(bref)); + HANDLE_CODE(max_data_rate_upip_downlink.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Integrity protection maximum data rate +// Reference: 9.11.4.7 +SRSASN_CODE integrity_protection_maximum_data_rate_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(max_data_rate_upip_uplink.unpack(bref)); + HANDLE_CODE(max_data_rate_upip_downlink.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: PDU session type +// Reference: 9.11.4.11 +SRSASN_CODE pdu_session_type_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(pdu_session_type_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: PDU session type +// Reference: 9.11.4.11 +SRSASN_CODE pdu_session_type_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(pdu_session_type_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: SSC mode +// Reference: 9.11.4.16 +SRSASN_CODE ssc_mode_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(ssc_mode_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: SSC mode +// Reference: 9.11.4.16 +SRSASN_CODE ssc_mode_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(ssc_mode_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM capability +// Reference: 9.11.4.1 +SRSASN_CODE capability_5gsm_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 13) { + asn1::log_error("Encoding Failed (5GSM capability): Packed length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM capability +// Reference: 9.11.4.1 +SRSASN_CODE capability_5gsm_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 13) { + asn1::log_error("Decoding Failed (5GSM capability): Length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: Maximum number of supported packet filters +// Reference: 9.11.4.9 +SRSASN_CODE maximum_number_of_supported_packet_filters_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(bref.pack(maximum_number_of_supported_packet_filters, 11)); + + // 5 Spare bits + HANDLE_CODE(bref.pack(0x0, 5)); + return SRSASN_SUCCESS; +} + +// IE: Maximum number of supported packet filters +// Reference: 9.11.4.9 +SRSASN_CODE maximum_number_of_supported_packet_filters_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(maximum_number_of_supported_packet_filters, 11)); + // 5 Spare bits + bref.advance_bits(5); + return SRSASN_SUCCESS; +} + +// IE: Always-on PDU session requested +// Reference: 9.11.4.4 +SRSASN_CODE always_on_pdu_session_requested_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(apsi, 1)); + return SRSASN_SUCCESS; +} + +// IE: Always-on PDU session requested +// Reference: 9.11.4.4 +SRSASN_CODE always_on_pdu_session_requested_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(apsi, 1)); + return SRSASN_SUCCESS; +} + +// IE: SM PDU DN request container +// Reference: 9.11.4.15 +SRSASN_CODE sm_pdu_dn_request_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(dn_specific_identity.data(), dn_specific_identity.size())); + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 253) { + asn1::log_error( + "Encoding Failed (SM PDU DN request container): Packed length (%d) is not in range of min: 1 and max 253 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: SM PDU DN request container +// Reference: 9.11.4.15 +SRSASN_CODE sm_pdu_dn_request_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 253) { + asn1::log_error( + "Decoding Failed (SM PDU DN request container): Length (%d) is not in range of min: 1 and max 253 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + dn_specific_identity.resize(length); + HANDLE_CODE(bref.unpack_bytes(dn_specific_identity.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Extended protocol configuration options +// Reference: 9.11.4.6 +SRSASN_CODE extended_protocol_configuration_options_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error( + "Encoding Failed (Extended protocol configuration options): Packed length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Extended protocol configuration options +// Reference: 9.11.4.6 +SRSASN_CODE extended_protocol_configuration_options_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error( + "Decoding Failed (Extended protocol configuration options): Length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: IP header compression configuration +// Reference: 9.11.4.24 +SRSASN_CODE ip_header_compression_configuration_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + // MAX 255 not check because auf uint overflow + if (length < 3) { + asn1::log_error( + "Encoding Failed (IP header compression configuration): Packed length (%d) is not in range of min: 3 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: IP header compression configuration +// Reference: 9.11.4.24 +SRSASN_CODE ip_header_compression_configuration_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + // MAX 255 not check because auf uint overflow + if (length < 3) { + asn1::log_error( + "Decoding Failed (IP header compression configuration): Length (%d) is not in range of min: 3 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: DS-TT Ethernet port MAC address +// Reference: 9.11.4.25 +SRSASN_CODE ds_tt__ethernet_port_mac_address_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(ds_tt__ethernet_port_mac_address_contents.data(), 6)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 6) { + asn1::log_error( + "Encoding Failed (DS-TT Ethernet port MAC address): Packed length (%d) does not equal expected length 6", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: DS-TT Ethernet port MAC address +// Reference: 9.11.4.25 +SRSASN_CODE ds_tt__ethernet_port_mac_address_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 6) { + asn1::log_error("Decoding Failed (DS-TT Ethernet port MAC address): Length (%d) does not equal expected length 6", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack_bytes(ds_tt__ethernet_port_mac_address_contents.data(), 6)); + return SRSASN_SUCCESS; +} + +// IE: UE-DS-TT residence time +// Reference: 9.11.4.26 +SRSASN_CODE ue_ds_tt_residence_time_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack_bytes(ue_ds_tt_residence_time_contents.data(), 8)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 8) { + asn1::log_error("Encoding Failed (UE-DS-TT residence time): Packed length (%d) does not equal expected length 8", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: UE-DS-TT residence time +// Reference: 9.11.4.26 +SRSASN_CODE ue_ds_tt_residence_time_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 8) { + asn1::log_error("Decoding Failed (UE-DS-TT residence time): Length (%d) does not equal expected length 8", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack_bytes(ue_ds_tt_residence_time_contents.data(), 8)); + return SRSASN_SUCCESS; +} + +// IE: Port management information container +// Reference: 9.11.4.27 +SRSASN_CODE port_management_information_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE( + bref.pack_bytes(port_management_information_container.data(), port_management_information_container.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error( + "Encoding Failed (Port management information container): Packed length (%d) is not in range of min: 1 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Port management information container +// Reference: 9.11.4.27 +SRSASN_CODE port_management_information_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 1) { + asn1::log_error( + "Decoding Failed (Port management information container): Length (%d) is not in range of min: 1 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + port_management_information_container.resize(length); + HANDLE_CODE(bref.unpack_bytes(port_management_information_container.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Ethernet header compression configuration +// Reference: 9.11.4.28 +SRSASN_CODE ethernet_header_compression_configuration_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 6 Spare bits + HANDLE_CODE(bref.pack(0x0, 6)); + HANDLE_CODE(cid__length.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (Ethernet header compression configuration): Packed length (%d) does not equal " + "expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Ethernet header compression configuration +// Reference: 9.11.4.28 +SRSASN_CODE ethernet_header_compression_configuration_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error( + "Decoding Failed (Ethernet header compression configuration): Length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 6 Spare bits + bref.advance_bits(6); + HANDLE_CODE(cid__length.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: PDU address +// Reference: 9.11.4.10 +SRSASN_CODE pdu_address_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 4 Spare bits + HANDLE_CODE(bref.pack(0x0, 4)); + HANDLE_CODE(bref.pack(si6_lla, 1)); + HANDLE_CODE(pdu_session_type_value.pack(bref)); + + if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4) { + HANDLE_CODE(bref.pack_bytes(ipv4.data(), 4)); + } else if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6) { + HANDLE_CODE(bref.pack_bytes(ipv6.data(), 16)); + } else if (pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6) { + HANDLE_CODE(bref.pack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.pack_bytes(ipv4.data(), 4)); + } + + if (si6_lla == true) { + HANDLE_CODE(bref.pack_bytes(smf_i_pv6_link_local_address.data(), 16)); + } + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 5 || length > 29) { + asn1::log_error("Encoding Failed (PDU address): Packed length (%d) is not in range of min: 5 and max 29 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: PDU address +// Reference: 9.11.4.10 +SRSASN_CODE pdu_address_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 5 || length > 29) { + asn1::log_error("Decoding Failed (PDU address): Length (%d) is not in range of min: 5 and max 29 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 4 Spare bits + bref.advance_bits(4); + HANDLE_CODE(bref.unpack(si6_lla, 1)); + HANDLE_CODE(pdu_session_type_value.unpack(bref)); + if (length == 5 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4 && + si6_lla == false) { + HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); + } else if (length == 9 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6 && + si6_lla == false) { + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + } else if (length == 13 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6 && + si6_lla == false) { + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); + } else if (length == 25 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv6 && + si6_lla == true) { + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 16)); + } else if (length == 29 && pdu_session_type_value == pdu_address_t::PDU_session_type_value_type_::options::ipv4v6 && + si6_lla == true) { + HANDLE_CODE(bref.unpack_bytes(ipv6.data(), 16)); + HANDLE_CODE(bref.unpack_bytes(ipv4.data(), 4)); + HANDLE_CODE(bref.unpack_bytes(smf_i_pv6_link_local_address.data(), 16)); + } else { + asn1::log_error("Not expected combination of length and type field"); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +// IE: QoS rules +// Reference: 9.11.4.13 +SRSASN_CODE qo_s_rules_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error("Encoding Failed (QoS rules): Packed length (%d) is not in range of min: 4 bytes", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: QoS rules +// Reference: 9.11.4.13 +SRSASN_CODE qo_s_rules_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error("Decoding Failed (QoS rules): Length (%d) is not in range of min: 4 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.advance_bits(length * 8)); + return SRSASN_SUCCESS; +} + +// IE: Session-AMBR +// Reference: 9.11.4.14 +SRSASN_CODE session_ambr_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(unit_session_ambr_for_downlink.pack(bref)); + HANDLE_CODE(bref.pack(session_ambr_for_downlink, 16)); + HANDLE_CODE(unit_session_ambr_for_uplink.pack(bref)); + HANDLE_CODE(bref.pack(session_ambr_for_uplink, 16)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 6) { + asn1::log_error("Encoding Failed (Session-AMBR): Packed length (%d) does not equal expected length 6", length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Session-AMBR +// Reference: 9.11.4.14 +SRSASN_CODE session_ambr_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 6) { + asn1::log_error("Decoding Failed (Session-AMBR): Length (%d) does not equal expected length 6", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(unit_session_ambr_for_downlink.unpack(bref)); + HANDLE_CODE(bref.unpack(session_ambr_for_downlink, 16)); + HANDLE_CODE(unit_session_ambr_for_uplink.unpack(bref)); + HANDLE_CODE(bref.unpack(session_ambr_for_uplink, 16)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM cause +// Reference: 9.11.4.2 +SRSASN_CODE cause_5gsm_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(cause_value.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM cause +// Reference: 9.11.4.2 +SRSASN_CODE cause_5gsm_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(cause_value.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer +// Reference: 9.11.2.3 +SRSASN_CODE gprs_timer_t::pack(asn1::bit_ref& bref) +{ + HANDLE_CODE(unit.pack(bref)); + HANDLE_CODE(bref.pack(timer_value, 5)); + return SRSASN_SUCCESS; +} + +// IE: GPRS timer +// Reference: 9.11.2.3 +SRSASN_CODE gprs_timer_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(unit.unpack(bref)); + HANDLE_CODE(bref.unpack(timer_value, 5)); + return SRSASN_SUCCESS; +} + +// IE: Always-on PDU session indication +// Reference: 9.11.4.3 +SRSASN_CODE always_on_pdu_session_indication_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(apsr, 1)); + return SRSASN_SUCCESS; +} + +// IE: Always-on PDU session indication +// Reference: 9.11.4.3 +SRSASN_CODE always_on_pdu_session_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(apsr, 1)); + return SRSASN_SUCCESS; +} + +// IE: Mapped EPS bearer contexts +// Reference: 9.11.4.8 +SRSASN_CODE mapped_eps_bearer_contexts_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error("Encoding Failed (Mapped EPS bearer contexts): Packed length (%d) is not in range of min: 4 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: Mapped EPS bearer contexts +// Reference: 9.11.4.8 +SRSASN_CODE mapped_eps_bearer_contexts_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 4) { + asn1::log_error("Decoding Failed (Mapped EPS bearer contexts): Length (%d) is not in range of min: 4 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: QoS flow descriptions +// Reference: 9.11.4.12 +SRSASN_CODE qo_s_flow_descriptions_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + // TODO proper packing + + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MAX 65535 not check because auf uint overflow + if (length < 3) { + asn1::log_error("Encoding Failed (QoS flow descriptions): Packed length (%d) is not in range of min: 3 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: QoS flow descriptions +// Reference: 9.11.4.12 +SRSASN_CODE qo_s_flow_descriptions_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MAX 65535 not check because auf uint overflow + if (length < 3) { + asn1::log_error("Decoding Failed (QoS flow descriptions): Length (%d) is not in range of min: 3 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + + // TODO proper unpacking + bref.advance_bits(length * 8); + return SRSASN_SUCCESS; +} + +// IE: 5GSM network feature support +// Reference: 9.11.4.18 +SRSASN_CODE network_feature_support_5gsm_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 7 Spare bits + HANDLE_CODE(bref.pack(0x0, 7)); + HANDLE_CODE(ept_s1.pack(bref)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length < 1 || length > 13) { + asn1::log_error( + "Encoding Failed (5GSM network feature support): Packed length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM network feature support +// Reference: 9.11.4.18 +SRSASN_CODE network_feature_support_5gsm_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length < 1 || length > 13) { + asn1::log_error( + "Decoding Failed (5GSM network feature support): Length (%d) is not in range of min: 1 and max 13 bytes", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 7 Spare bits + bref.advance_bits(7); + HANDLE_CODE(ept_s1.unpack(bref)); + if (length > 1) { + HANDLE_CODE(bref.advance_bits((length - 1) * 8)); + } + return SRSASN_SUCCESS; +} + +// IE: Serving PLMN rate control +// Reference: 9.11.4.20 +SRSASN_CODE serving_plmn_rate_control_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + HANDLE_CODE(bref.pack(serving_plmn_rate_control_value, 16)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 2) { + asn1::log_error("Encoding Failed (Serving PLMN rate control): Packed length (%d) does not equal expected length 2", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Serving PLMN rate control +// Reference: 9.11.4.20 +SRSASN_CODE serving_plmn_rate_control_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 2) { + asn1::log_error("Decoding Failed (Serving PLMN rate control): Length (%d) does not equal expected length 2", + length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + HANDLE_CODE(bref.unpack(serving_plmn_rate_control_value, 16)); + return SRSASN_SUCCESS; +} + +// IE: ATSSS container +// Reference: 9.11.4.22 +SRSASN_CODE atsss_container_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(16)); + + HANDLE_CODE(bref.pack_bytes(nas_message_container.data(), nas_message_container.size())); + bref.align_bytes_zero(); + uint16_t length = (uint16_t)(ceilf(bref.distance(bref_length) / 8) - 2); + + // MIN 0 not check because auf uint underflow + // MAX 65535 not check because auf uint overflow + HANDLE_CODE(bref_length.pack(length, 16)); + return SRSASN_SUCCESS; +} + +// IE: ATSSS container +// Reference: 9.11.4.22 +SRSASN_CODE atsss_container_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 16)); + // MIN 0 not check because auf uint underflow + if (length > 65535) { + asn1::log_error("Decoding Failed (ATSSS container): Length (%d) is not in range of max 65535 bytes", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + nas_message_container.resize(length); + HANDLE_CODE(bref.unpack_bytes(nas_message_container.data(), length)); + return SRSASN_SUCCESS; +} + +// IE: Control plane only indication +// Reference: 9.11.4.23 +SRSASN_CODE control_plane_only_indication_t::pack(asn1::bit_ref& bref) +{ + // 3 Spare bits + HANDLE_CODE(bref.pack(0x0, 3)); + HANDLE_CODE(bref.pack(cpoi, 1)); + return SRSASN_SUCCESS; +} + +// IE: Control plane only indication +// Reference: 9.11.4.23 +SRSASN_CODE control_plane_only_indication_t::unpack(asn1::cbit_ref& bref) +{ + // 3 Spare bits + bref.advance_bits(3); + HANDLE_CODE(bref.unpack(cpoi, 1)); + return SRSASN_SUCCESS; +} + +// IE: Allowed SSC mode +// Reference: 9.11.4.5 +SRSASN_CODE allowed_ssc_mode_t::pack(asn1::bit_ref& bref) +{ + // 1 Spare bits + HANDLE_CODE(bref.pack(0x0, 1)); + HANDLE_CODE(bref.pack(ssc3, 1)); + HANDLE_CODE(bref.pack(ssc2, 1)); + HANDLE_CODE(bref.pack(ssc1, 1)); + return SRSASN_SUCCESS; +} + +// IE: Allowed SSC mode +// Reference: 9.11.4.5 +SRSASN_CODE allowed_ssc_mode_t::unpack(asn1::cbit_ref& bref) +{ + // 1 Spare bits + bref.advance_bits(1); + HANDLE_CODE(bref.unpack(ssc3, 1)); + HANDLE_CODE(bref.unpack(ssc2, 1)); + HANDLE_CODE(bref.unpack(ssc1, 1)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM congestion re-attempt indicator +// Reference: 9.11.4.21 +SRSASN_CODE congestion_re_attempt_indicator_5gsm_t::pack(asn1::bit_ref& bref) +{ + // 7 Spare bits + HANDLE_CODE(bref.pack(0x0, 7)); + HANDLE_CODE(abo.pack(bref)); + return SRSASN_SUCCESS; +} + +// IE: 5GSM congestion re-attempt indicator +// Reference: 9.11.4.21 +SRSASN_CODE congestion_re_attempt_indicator_5gsm_t::unpack(asn1::cbit_ref& bref) +{ + // 7 Spare bits + bref.advance_bits(7); + HANDLE_CODE(abo.unpack(bref)); + return SRSASN_SUCCESS; +} + +// IE: Re-attempt indicator +// Reference: 9.11.4.17 +SRSASN_CODE re_attempt_indicator_t::pack(asn1::bit_ref& bref) +{ + // Save length bref pointer + asn1::bit_ref bref_length = bref; + HANDLE_CODE(bref.advance_bits(8)); + + // 6 Spare bits + HANDLE_CODE(bref.pack(0x0, 6)); + HANDLE_CODE(bref.pack(eplmnc, 1)); + HANDLE_CODE(bref.pack(ratc, 1)); + + bref.align_bytes_zero(); + uint8_t length = (uint8_t)(ceilf(bref.distance(bref_length) / 8) - 1); + + if (length != 1) { + asn1::log_error("Encoding Failed (Re-attempt indicator): Packed length (%d) does not equal expected length 1", + length); + return asn1::SRSASN_ERROR_ENCODE_FAIL; + } + HANDLE_CODE(bref_length.pack(length, 8)); + return SRSASN_SUCCESS; +} + +// IE: Re-attempt indicator +// Reference: 9.11.4.17 +SRSASN_CODE re_attempt_indicator_t::unpack(asn1::cbit_ref& bref) +{ + HANDLE_CODE(bref.unpack(length, 8)); + if (length != 1) { + asn1::log_error("Decoding Failed (Re-attempt indicator): Length (%d) does not equal expected length 1", length); + return asn1::SRSASN_ERROR_DECODE_FAIL; + } + // 6 Spare bits + bref.advance_bits(6); + HANDLE_CODE(bref.unpack(eplmnc, 1)); + HANDLE_CODE(bref.unpack(ratc, 1)); + return SRSASN_SUCCESS; +} + +} // namespace nas_5g +} // namespace srsran diff --git a/lib/src/asn1/nas_5g_msg.cc b/lib/src/asn1/nas_5g_msg.cc new file mode 100644 index 000000000..91af1bca4 --- /dev/null +++ b/lib/src/asn1/nas_5g_msg.cc @@ -0,0 +1,4198 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srsran/asn1/nas_5g_msg.h" +#include "srsran/asn1/nas_5g_ies.h" +#include "srsran/asn1/nas_5g_utils.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/config.h" + +#include +#include +#include + +namespace srsran { +namespace nas_5g { + +SRSASN_CODE registration_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(registration_type_5gs.pack(bref)); + HANDLE_CODE(mobile_identity_5gs.pack(bref)); + + // Optional fields + if (non_current_native_nas_key_set_identifier_present == true) { + HANDLE_CODE(bref.pack(ie_iei_non_current_native_nas_key_set_identifier, 4)); + HANDLE_CODE(non_current_native_nas_key_set_identifier.pack(bref)); + } + if (capability_5gmm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_capability_5gmm, 8)); + HANDLE_CODE(capability_5gmm.pack(bref)); + } + if (ue_security_capability_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_security_capability, 8)); + HANDLE_CODE(ue_security_capability.pack(bref)); + } + if (requested_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_nssai, 8)); + HANDLE_CODE(requested_nssai.pack(bref)); + } + if (last_visited_registered_tai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_last_visited_registered_tai, 8)); + HANDLE_CODE(last_visited_registered_tai.pack(bref)); + } + if (s1_ue_network_capability_present == true) { + HANDLE_CODE(bref.pack(ie_iei_s1_ue_network_capability, 8)); + HANDLE_CODE(s1_ue_network_capability.pack(bref)); + } + if (uplink_data_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_uplink_data_status, 8)); + HANDLE_CODE(uplink_data_status.pack(bref)); + } + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + if (mico_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mico_indication, 4)); + HANDLE_CODE(mico_indication.pack(bref)); + } + if (ue_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_status, 8)); + HANDLE_CODE(ue_status.pack(bref)); + } + if (additional_guti_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_guti, 8)); + HANDLE_CODE(additional_guti.pack(bref)); + } + if (allowed_pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_allowed_pdu_session_status, 8)); + HANDLE_CODE(allowed_pdu_session_status.pack(bref)); + } + if (ue_usage_setting_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_usage_setting, 8)); + HANDLE_CODE(ue_usage_setting.pack(bref)); + } + if (requested_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_drx_parameters, 8)); + HANDLE_CODE(requested_drx_parameters.pack(bref)); + } + if (eps_nas_message_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eps_nas_message_container, 8)); + HANDLE_CODE(eps_nas_message_container.pack(bref)); + } + if (ladn_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ladn_indication, 8)); + HANDLE_CODE(ladn_indication.pack(bref)); + } + if (payload_container_type_present == true) { + HANDLE_CODE(bref.pack(ie_iei_payload_container_type, 4)); + HANDLE_CODE(payload_container_type.pack(bref)); + } + if (payload_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_payload_container, 8)); + HANDLE_CODE(payload_container.pack(bref)); + } + if (network_slicing_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_slicing_indication, 4)); + HANDLE_CODE(network_slicing_indication.pack(bref)); + } + if (update_type_5gs_present == true) { + HANDLE_CODE(bref.pack(ie_iei_update_type_5gs, 8)); + HANDLE_CODE(update_type_5gs.pack(bref)); + } + if (mobile_station_classmark_2_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mobile_station_classmark_2, 8)); + HANDLE_CODE(mobile_station_classmark_2.pack(bref)); + } + if (supported_codecs_present == true) { + HANDLE_CODE(bref.pack(ie_iei_supported_codecs, 8)); + HANDLE_CODE(supported_codecs.pack(bref)); + } + if (nas_message_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_nas_message_container, 8)); + HANDLE_CODE(nas_message_container.pack(bref)); + } + if (eps_bearer_context_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eps_bearer_context_status, 8)); + HANDLE_CODE(eps_bearer_context_status.pack(bref)); + } + if (requested_extended_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_extended_drx_parameters, 8)); + HANDLE_CODE(requested_extended_drx_parameters.pack(bref)); + } + if (t3324_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3324_value, 8)); + HANDLE_CODE(t3324_value.pack(bref)); + } + if (ue_radio_capability_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_radio_capability_id, 8)); + HANDLE_CODE(ue_radio_capability_id.pack(bref)); + } + if (requested_mapped_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_mapped_nssai, 8)); + HANDLE_CODE(requested_mapped_nssai.pack(bref)); + } + if (additional_information_requested_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_information_requested, 8)); + HANDLE_CODE(additional_information_requested.pack(bref)); + } + if (requested_wus_assistance_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_wus_assistance_information, 8)); + HANDLE_CODE(requested_wus_assistance_information.pack(bref)); + } + if (n5gc_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_n5gc_indication, 4)); + HANDLE_CODE(n5gc_indication.pack(bref)); + } + if (requested_nb_n1_mode_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested_nb_n1_mode_drx_parameters, 8)); + HANDLE_CODE(requested_nb_n1_mode_drx_parameters.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE registration_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(registration_type_5gs.unpack(bref)); + HANDLE_CODE(mobile_identity_5gs.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_non_current_native_nas_key_set_identifier: + non_current_native_nas_key_set_identifier_present = true; + HANDLE_CODE(non_current_native_nas_key_set_identifier.unpack(bref)); + break; + case ie_iei_capability_5gmm: + capability_5gmm_present = true; + HANDLE_CODE(capability_5gmm.unpack(bref)); + break; + case ie_iei_ue_security_capability: + ue_security_capability_present = true; + HANDLE_CODE(ue_security_capability.unpack(bref)); + break; + case ie_iei_requested_nssai: + requested_nssai_present = true; + HANDLE_CODE(requested_nssai.unpack(bref)); + break; + case ie_iei_last_visited_registered_tai: + last_visited_registered_tai_present = true; + HANDLE_CODE(last_visited_registered_tai.unpack(bref)); + break; + case ie_iei_s1_ue_network_capability: + s1_ue_network_capability_present = true; + HANDLE_CODE(s1_ue_network_capability.unpack(bref)); + break; + case ie_iei_uplink_data_status: + uplink_data_status_present = true; + HANDLE_CODE(uplink_data_status.unpack(bref)); + break; + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + case ie_iei_mico_indication: + mico_indication_present = true; + HANDLE_CODE(mico_indication.unpack(bref)); + break; + case ie_iei_ue_status: + ue_status_present = true; + HANDLE_CODE(ue_status.unpack(bref)); + break; + case ie_iei_additional_guti: + additional_guti_present = true; + HANDLE_CODE(additional_guti.unpack(bref)); + break; + case ie_iei_allowed_pdu_session_status: + allowed_pdu_session_status_present = true; + HANDLE_CODE(allowed_pdu_session_status.unpack(bref)); + break; + case ie_iei_ue_usage_setting: + ue_usage_setting_present = true; + HANDLE_CODE(ue_usage_setting.unpack(bref)); + break; + case ie_iei_requested_drx_parameters: + requested_drx_parameters_present = true; + HANDLE_CODE(requested_drx_parameters.unpack(bref)); + break; + case ie_iei_eps_nas_message_container: + eps_nas_message_container_present = true; + HANDLE_CODE(eps_nas_message_container.unpack(bref)); + break; + case ie_iei_ladn_indication: + ladn_indication_present = true; + HANDLE_CODE(ladn_indication.unpack(bref)); + break; + case ie_iei_payload_container_type: + payload_container_type_present = true; + HANDLE_CODE(payload_container_type.unpack(bref)); + break; + case ie_iei_payload_container: + payload_container_present = true; + HANDLE_CODE(payload_container.unpack(bref)); + break; + case ie_iei_network_slicing_indication: + network_slicing_indication_present = true; + HANDLE_CODE(network_slicing_indication.unpack(bref)); + break; + case ie_iei_update_type_5gs: + update_type_5gs_present = true; + HANDLE_CODE(update_type_5gs.unpack(bref)); + break; + case ie_iei_mobile_station_classmark_2: + mobile_station_classmark_2_present = true; + HANDLE_CODE(mobile_station_classmark_2.unpack(bref)); + break; + case ie_iei_supported_codecs: + supported_codecs_present = true; + HANDLE_CODE(supported_codecs.unpack(bref)); + break; + case ie_iei_nas_message_container: + nas_message_container_present = true; + HANDLE_CODE(nas_message_container.unpack(bref)); + break; + case ie_iei_eps_bearer_context_status: + eps_bearer_context_status_present = true; + HANDLE_CODE(eps_bearer_context_status.unpack(bref)); + break; + case ie_iei_requested_extended_drx_parameters: + requested_extended_drx_parameters_present = true; + HANDLE_CODE(requested_extended_drx_parameters.unpack(bref)); + break; + case ie_iei_t3324_value: + t3324_value_present = true; + HANDLE_CODE(t3324_value.unpack(bref)); + break; + case ie_iei_ue_radio_capability_id: + ue_radio_capability_id_present = true; + HANDLE_CODE(ue_radio_capability_id.unpack(bref)); + break; + case ie_iei_requested_mapped_nssai: + requested_mapped_nssai_present = true; + HANDLE_CODE(requested_mapped_nssai.unpack(bref)); + break; + case ie_iei_additional_information_requested: + additional_information_requested_present = true; + HANDLE_CODE(additional_information_requested.unpack(bref)); + break; + case ie_iei_requested_wus_assistance_information: + requested_wus_assistance_information_present = true; + HANDLE_CODE(requested_wus_assistance_information.unpack(bref)); + break; + case ie_iei_n5gc_indication: + n5gc_indication_present = true; + HANDLE_CODE(n5gc_indication.unpack(bref)); + break; + case ie_iei_requested_nb_n1_mode_drx_parameters: + requested_nb_n1_mode_drx_parameters_present = true; + HANDLE_CODE(requested_nb_n1_mode_drx_parameters.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE registration_accept_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(registration_result_5gs.pack(bref)); + + // Optional fields + if (guti_5g_present == true) { + HANDLE_CODE(bref.pack(ie_iei_guti_5g, 8)); + HANDLE_CODE(guti_5g.pack(bref)); + } + if (equivalent_plm_ns_present == true) { + HANDLE_CODE(bref.pack(ie_iei_equivalent_plm_ns, 8)); + HANDLE_CODE(equivalent_plm_ns.pack(bref)); + } + if (tai_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_tai_list, 8)); + HANDLE_CODE(tai_list.pack(bref)); + } + if (allowed_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_allowed_nssai, 8)); + HANDLE_CODE(allowed_nssai.pack(bref)); + } + if (rejected_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rejected_nssai, 8)); + HANDLE_CODE(rejected_nssai.pack(bref)); + } + if (configured_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_configured_nssai, 8)); + HANDLE_CODE(configured_nssai.pack(bref)); + } + if (network_feature_support_5gs_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_feature_support_5gs, 8)); + HANDLE_CODE(network_feature_support_5gs.pack(bref)); + } + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + if (pdu_session_reactivation_result_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_reactivation_result, 8)); + HANDLE_CODE(pdu_session_reactivation_result.pack(bref)); + } + if (pdu_session_reactivation_result_error_cause_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_reactivation_result_error_cause, 8)); + HANDLE_CODE(pdu_session_reactivation_result_error_cause.pack(bref)); + } + if (ladn_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ladn_information, 8)); + HANDLE_CODE(ladn_information.pack(bref)); + } + if (mico_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mico_indication, 4)); + HANDLE_CODE(mico_indication.pack(bref)); + } + if (network_slicing_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_slicing_indication, 4)); + HANDLE_CODE(network_slicing_indication.pack(bref)); + } + if (service_area_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_service_area_list, 8)); + HANDLE_CODE(service_area_list.pack(bref)); + } + if (t3512_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3512_value, 8)); + HANDLE_CODE(t3512_value.pack(bref)); + } + if (non_3_gpp_de_registration_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_non_3_gpp_de_registration_timer_value, 8)); + HANDLE_CODE(non_3_gpp_de_registration_timer_value.pack(bref)); + } + if (t3502_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3502_value, 8)); + HANDLE_CODE(t3502_value.pack(bref)); + } + if (emergency_number_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_emergency_number_list, 8)); + HANDLE_CODE(emergency_number_list.pack(bref)); + } + if (extended_emergency_number_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_emergency_number_list, 8)); + HANDLE_CODE(extended_emergency_number_list.pack(bref)); + } + if (sor_transparent_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_sor_transparent_container, 8)); + HANDLE_CODE(sor_transparent_container.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (nssai_inclusion_mode_present == true) { + HANDLE_CODE(bref.pack(ie_iei_nssai_inclusion_mode, 4)); + HANDLE_CODE(nssai_inclusion_mode.pack(bref)); + } + if (operator_defined_access_category_definitions_present == true) { + HANDLE_CODE(bref.pack(ie_iei_operator_defined_access_category_definitions, 8)); + HANDLE_CODE(operator_defined_access_category_definitions.pack(bref)); + } + if (negotiated_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_negotiated_drx_parameters, 8)); + HANDLE_CODE(negotiated_drx_parameters.pack(bref)); + } + if (non_3_gpp_nw_policies_present == true) { + HANDLE_CODE(bref.pack(ie_iei_non_3_gpp_nw_policies, 4)); + HANDLE_CODE(non_3_gpp_nw_policies.pack(bref)); + } + if (eps_bearer_context_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eps_bearer_context_status, 8)); + HANDLE_CODE(eps_bearer_context_status.pack(bref)); + } + if (negotiated_extended_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_negotiated_extended_drx_parameters, 8)); + HANDLE_CODE(negotiated_extended_drx_parameters.pack(bref)); + } + if (t3447_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3447_value, 8)); + HANDLE_CODE(t3447_value.pack(bref)); + } + if (t3448_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3448_value, 8)); + HANDLE_CODE(t3448_value.pack(bref)); + } + if (t3324_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3324_value, 8)); + HANDLE_CODE(t3324_value.pack(bref)); + } + if (ue_radio_capability_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_radio_capability_id, 8)); + HANDLE_CODE(ue_radio_capability_id.pack(bref)); + } + if (ue_radio_capability_id_deletion_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_radio_capability_id_deletion_indication, 4)); + HANDLE_CODE(ue_radio_capability_id_deletion_indication.pack(bref)); + } + if (pending_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pending_nssai, 8)); + HANDLE_CODE(pending_nssai.pack(bref)); + } + if (ciphering_key_data_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ciphering_key_data, 8)); + HANDLE_CODE(ciphering_key_data.pack(bref)); + } + if (cag_information_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cag_information_list, 8)); + HANDLE_CODE(cag_information_list.pack(bref)); + } + if (truncated_5g_s_tmsi_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_truncated_5g_s_tmsi_configuration, 8)); + HANDLE_CODE(truncated_5g_s_tmsi_configuration.pack(bref)); + } + if (negotiated_wus_assistance_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_negotiated_wus_assistance_information, 8)); + HANDLE_CODE(negotiated_wus_assistance_information.pack(bref)); + } + if (negotiated_nb_n1_mode_drx_parameters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_negotiated_nb_n1_mode_drx_parameters, 8)); + HANDLE_CODE(negotiated_nb_n1_mode_drx_parameters.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE registration_accept_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(registration_result_5gs.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_guti_5g: + guti_5g_present = true; + HANDLE_CODE(guti_5g.unpack(bref)); + break; + case ie_iei_equivalent_plm_ns: + equivalent_plm_ns_present = true; + HANDLE_CODE(equivalent_plm_ns.unpack(bref)); + break; + case ie_iei_tai_list: + tai_list_present = true; + HANDLE_CODE(tai_list.unpack(bref)); + break; + case ie_iei_allowed_nssai: + allowed_nssai_present = true; + HANDLE_CODE(allowed_nssai.unpack(bref)); + break; + case ie_iei_rejected_nssai: + rejected_nssai_present = true; + HANDLE_CODE(rejected_nssai.unpack(bref)); + break; + case ie_iei_configured_nssai: + configured_nssai_present = true; + HANDLE_CODE(configured_nssai.unpack(bref)); + break; + case ie_iei_network_feature_support_5gs: + network_feature_support_5gs_present = true; + HANDLE_CODE(network_feature_support_5gs.unpack(bref)); + break; + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + case ie_iei_pdu_session_reactivation_result: + pdu_session_reactivation_result_present = true; + HANDLE_CODE(pdu_session_reactivation_result.unpack(bref)); + break; + case ie_iei_pdu_session_reactivation_result_error_cause: + pdu_session_reactivation_result_error_cause_present = true; + HANDLE_CODE(pdu_session_reactivation_result_error_cause.unpack(bref)); + break; + case ie_iei_ladn_information: + ladn_information_present = true; + HANDLE_CODE(ladn_information.unpack(bref)); + break; + case ie_iei_mico_indication: + mico_indication_present = true; + HANDLE_CODE(mico_indication.unpack(bref)); + break; + case ie_iei_network_slicing_indication: + network_slicing_indication_present = true; + HANDLE_CODE(network_slicing_indication.unpack(bref)); + break; + case ie_iei_service_area_list: + service_area_list_present = true; + HANDLE_CODE(service_area_list.unpack(bref)); + break; + case ie_iei_t3512_value: + t3512_value_present = true; + HANDLE_CODE(t3512_value.unpack(bref)); + break; + case ie_iei_non_3_gpp_de_registration_timer_value: + non_3_gpp_de_registration_timer_value_present = true; + HANDLE_CODE(non_3_gpp_de_registration_timer_value.unpack(bref)); + break; + case ie_iei_t3502_value: + t3502_value_present = true; + HANDLE_CODE(t3502_value.unpack(bref)); + break; + case ie_iei_emergency_number_list: + emergency_number_list_present = true; + HANDLE_CODE(emergency_number_list.unpack(bref)); + break; + case ie_iei_extended_emergency_number_list: + extended_emergency_number_list_present = true; + HANDLE_CODE(extended_emergency_number_list.unpack(bref)); + break; + case ie_iei_sor_transparent_container: + sor_transparent_container_present = true; + HANDLE_CODE(sor_transparent_container.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_nssai_inclusion_mode: + nssai_inclusion_mode_present = true; + HANDLE_CODE(nssai_inclusion_mode.unpack(bref)); + break; + case ie_iei_operator_defined_access_category_definitions: + operator_defined_access_category_definitions_present = true; + HANDLE_CODE(operator_defined_access_category_definitions.unpack(bref)); + break; + case ie_iei_negotiated_drx_parameters: + negotiated_drx_parameters_present = true; + HANDLE_CODE(negotiated_drx_parameters.unpack(bref)); + break; + case ie_iei_non_3_gpp_nw_policies: + non_3_gpp_nw_policies_present = true; + HANDLE_CODE(non_3_gpp_nw_policies.unpack(bref)); + break; + case ie_iei_eps_bearer_context_status: + eps_bearer_context_status_present = true; + HANDLE_CODE(eps_bearer_context_status.unpack(bref)); + break; + case ie_iei_negotiated_extended_drx_parameters: + negotiated_extended_drx_parameters_present = true; + HANDLE_CODE(negotiated_extended_drx_parameters.unpack(bref)); + break; + case ie_iei_t3447_value: + t3447_value_present = true; + HANDLE_CODE(t3447_value.unpack(bref)); + break; + case ie_iei_t3448_value: + t3448_value_present = true; + HANDLE_CODE(t3448_value.unpack(bref)); + break; + case ie_iei_t3324_value: + t3324_value_present = true; + HANDLE_CODE(t3324_value.unpack(bref)); + break; + case ie_iei_ue_radio_capability_id: + ue_radio_capability_id_present = true; + HANDLE_CODE(ue_radio_capability_id.unpack(bref)); + break; + case ie_iei_ue_radio_capability_id_deletion_indication: + ue_radio_capability_id_deletion_indication_present = true; + HANDLE_CODE(ue_radio_capability_id_deletion_indication.unpack(bref)); + break; + case ie_iei_pending_nssai: + pending_nssai_present = true; + HANDLE_CODE(pending_nssai.unpack(bref)); + break; + case ie_iei_ciphering_key_data: + ciphering_key_data_present = true; + HANDLE_CODE(ciphering_key_data.unpack(bref)); + break; + case ie_iei_cag_information_list: + cag_information_list_present = true; + HANDLE_CODE(cag_information_list.unpack(bref)); + break; + case ie_iei_truncated_5g_s_tmsi_configuration: + truncated_5g_s_tmsi_configuration_present = true; + HANDLE_CODE(truncated_5g_s_tmsi_configuration.unpack(bref)); + break; + case ie_iei_negotiated_wus_assistance_information: + negotiated_wus_assistance_information_present = true; + HANDLE_CODE(negotiated_wus_assistance_information.unpack(bref)); + break; + case ie_iei_negotiated_nb_n1_mode_drx_parameters: + negotiated_nb_n1_mode_drx_parameters_present = true; + HANDLE_CODE(negotiated_nb_n1_mode_drx_parameters.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE registration_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (sor_transparent_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_sor_transparent_container, 8)); + HANDLE_CODE(sor_transparent_container.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE registration_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_sor_transparent_container: + sor_transparent_container_present = true; + HANDLE_CODE(sor_transparent_container.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE registration_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.pack(bref)); + + // Optional fields + if (t3346_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3346_value, 8)); + HANDLE_CODE(t3346_value.pack(bref)); + } + if (t3502_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3502_value, 8)); + HANDLE_CODE(t3502_value.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (rejected_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rejected_nssai, 8)); + HANDLE_CODE(rejected_nssai.pack(bref)); + } + if (cag_information_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cag_information_list, 8)); + HANDLE_CODE(cag_information_list.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE registration_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_t3346_value: + t3346_value_present = true; + HANDLE_CODE(t3346_value.unpack(bref)); + break; + case ie_iei_t3502_value: + t3502_value_present = true; + HANDLE_CODE(t3502_value.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_rejected_nssai: + rejected_nssai_present = true; + HANDLE_CODE(rejected_nssai.unpack(bref)); + break; + case ie_iei_cag_information_list: + cag_information_list_present = true; + HANDLE_CODE(cag_information_list.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE deregistration_request_ue_originating_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(de_registration_type.pack(bref)); + HANDLE_CODE(mobile_identity_5gs.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE deregistration_request_ue_originating_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(de_registration_type.unpack(bref)); + HANDLE_CODE(mobile_identity_5gs.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE deregistration_accept_ue_originating_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE deregistration_accept_ue_originating_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE deregistration_request_ue_terminated_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(de_registration_type.pack(bref)); + + // Optional fields + if (cause_5gmm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gmm, 8)); + HANDLE_CODE(cause_5gmm.pack(bref)); + } + if (t3346_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3346_value, 8)); + HANDLE_CODE(t3346_value.pack(bref)); + } + if (rejected_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rejected_nssai, 8)); + HANDLE_CODE(rejected_nssai.pack(bref)); + } + if (cag_information_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cag_information_list, 8)); + HANDLE_CODE(cag_information_list.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE deregistration_request_ue_terminated_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(de_registration_type.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_cause_5gmm: + cause_5gmm_present = true; + HANDLE_CODE(cause_5gmm.unpack(bref)); + break; + case ie_iei_t3346_value: + t3346_value_present = true; + HANDLE_CODE(t3346_value.unpack(bref)); + break; + case ie_iei_rejected_nssai: + rejected_nssai_present = true; + HANDLE_CODE(rejected_nssai.unpack(bref)); + break; + case ie_iei_cag_information_list: + cag_information_list_present = true; + HANDLE_CODE(cag_information_list.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE deregistration_accept_ue_terminated_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE deregistration_accept_ue_terminated_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE service_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(service_type.pack(bref)); + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(s_tmsi_5g.pack(bref)); + + // Optional fields + if (uplink_data_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_uplink_data_status, 8)); + HANDLE_CODE(uplink_data_status.pack(bref)); + } + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + if (allowed_pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_allowed_pdu_session_status, 8)); + HANDLE_CODE(allowed_pdu_session_status.pack(bref)); + } + if (nas_message_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_nas_message_container, 8)); + HANDLE_CODE(nas_message_container.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE service_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(service_type.unpack(bref)); + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(s_tmsi_5g.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_uplink_data_status: + uplink_data_status_present = true; + HANDLE_CODE(uplink_data_status.unpack(bref)); + break; + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + case ie_iei_allowed_pdu_session_status: + allowed_pdu_session_status_present = true; + HANDLE_CODE(allowed_pdu_session_status.unpack(bref)); + break; + case ie_iei_nas_message_container: + nas_message_container_present = true; + HANDLE_CODE(nas_message_container.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE service_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + if (pdu_session_reactivation_result_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_reactivation_result, 8)); + HANDLE_CODE(pdu_session_reactivation_result.pack(bref)); + } + if (pdu_session_reactivation_result_error_cause_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_reactivation_result_error_cause, 8)); + HANDLE_CODE(pdu_session_reactivation_result_error_cause.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (t3448_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3448_value, 8)); + HANDLE_CODE(t3448_value.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE service_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + case ie_iei_pdu_session_reactivation_result: + pdu_session_reactivation_result_present = true; + HANDLE_CODE(pdu_session_reactivation_result.unpack(bref)); + break; + case ie_iei_pdu_session_reactivation_result_error_cause: + pdu_session_reactivation_result_error_cause_present = true; + HANDLE_CODE(pdu_session_reactivation_result_error_cause.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_t3448_value: + t3448_value_present = true; + HANDLE_CODE(t3448_value.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE service_accept_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.pack(bref)); + + // Optional fields + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + if (t3346_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3346_value, 8)); + HANDLE_CODE(t3346_value.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (t3448_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3448_value, 8)); + HANDLE_CODE(t3448_value.pack(bref)); + } + if (cag_information_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cag_information_list, 8)); + HANDLE_CODE(cag_information_list.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE service_accept_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + case ie_iei_t3346_value: + t3346_value_present = true; + HANDLE_CODE(t3346_value.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_t3448_value: + t3448_value_present = true; + HANDLE_CODE(t3448_value.unpack(bref)); + break; + case ie_iei_cag_information_list: + cag_information_list_present = true; + HANDLE_CODE(cag_information_list.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE configuration_update_command_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (configuration_update_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_configuration_update_indication, 4)); + HANDLE_CODE(configuration_update_indication.pack(bref)); + } + if (guti_5g_present == true) { + HANDLE_CODE(bref.pack(ie_iei_guti_5g, 8)); + HANDLE_CODE(guti_5g.pack(bref)); + } + if (tai_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_tai_list, 8)); + HANDLE_CODE(tai_list.pack(bref)); + } + if (allowed_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_allowed_nssai, 8)); + HANDLE_CODE(allowed_nssai.pack(bref)); + } + if (service_area_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_service_area_list, 8)); + HANDLE_CODE(service_area_list.pack(bref)); + } + if (full_name_for_network_present == true) { + HANDLE_CODE(bref.pack(ie_iei_full_name_for_network, 8)); + HANDLE_CODE(full_name_for_network.pack(bref)); + } + if (short_name_for_network_present == true) { + HANDLE_CODE(bref.pack(ie_iei_short_name_for_network, 8)); + HANDLE_CODE(short_name_for_network.pack(bref)); + } + if (local_time_zone_present == true) { + HANDLE_CODE(bref.pack(ie_iei_local_time_zone, 8)); + HANDLE_CODE(local_time_zone.pack(bref)); + } + if (universal_time_and_local_time_zone_present == true) { + HANDLE_CODE(bref.pack(ie_iei_universal_time_and_local_time_zone, 8)); + HANDLE_CODE(universal_time_and_local_time_zone.pack(bref)); + } + if (network_daylight_saving_time_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_daylight_saving_time, 8)); + HANDLE_CODE(network_daylight_saving_time.pack(bref)); + } + if (ladn_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ladn_information, 8)); + HANDLE_CODE(ladn_information.pack(bref)); + } + if (mico_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mico_indication, 4)); + HANDLE_CODE(mico_indication.pack(bref)); + } + if (network_slicing_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_slicing_indication, 4)); + HANDLE_CODE(network_slicing_indication.pack(bref)); + } + if (configured_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_configured_nssai, 8)); + HANDLE_CODE(configured_nssai.pack(bref)); + } + if (rejected_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rejected_nssai, 8)); + HANDLE_CODE(rejected_nssai.pack(bref)); + } + if (operator_defined_access_category_definitions_present == true) { + HANDLE_CODE(bref.pack(ie_iei_operator_defined_access_category_definitions, 8)); + HANDLE_CODE(operator_defined_access_category_definitions.pack(bref)); + } + if (sms_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_sms_indication, 4)); + HANDLE_CODE(sms_indication.pack(bref)); + } + if (t3447_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_t3447_value, 8)); + HANDLE_CODE(t3447_value.pack(bref)); + } + if (cag_information_list_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cag_information_list, 8)); + HANDLE_CODE(cag_information_list.pack(bref)); + } + if (ue_radio_capability_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_radio_capability_id, 8)); + HANDLE_CODE(ue_radio_capability_id.pack(bref)); + } + if (ue_radio_capability_id_deletion_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_radio_capability_id_deletion_indication, 4)); + HANDLE_CODE(ue_radio_capability_id_deletion_indication.pack(bref)); + } + if (registration_result_5gs_present == true) { + HANDLE_CODE(bref.pack(ie_iei_registration_result_5gs, 8)); + HANDLE_CODE(registration_result_5gs.pack(bref)); + } + if (truncated_5g_s_tmsi_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_truncated_5g_s_tmsi_configuration, 8)); + HANDLE_CODE(truncated_5g_s_tmsi_configuration.pack(bref)); + } + if (additional_configuration_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_configuration_indication, 4)); + HANDLE_CODE(additional_configuration_indication.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE configuration_update_command_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_configuration_update_indication: + configuration_update_indication_present = true; + HANDLE_CODE(configuration_update_indication.unpack(bref)); + break; + case ie_iei_guti_5g: + guti_5g_present = true; + HANDLE_CODE(guti_5g.unpack(bref)); + break; + case ie_iei_tai_list: + tai_list_present = true; + HANDLE_CODE(tai_list.unpack(bref)); + break; + case ie_iei_allowed_nssai: + allowed_nssai_present = true; + HANDLE_CODE(allowed_nssai.unpack(bref)); + break; + case ie_iei_service_area_list: + service_area_list_present = true; + HANDLE_CODE(service_area_list.unpack(bref)); + break; + case ie_iei_full_name_for_network: + full_name_for_network_present = true; + HANDLE_CODE(full_name_for_network.unpack(bref)); + break; + case ie_iei_short_name_for_network: + short_name_for_network_present = true; + HANDLE_CODE(short_name_for_network.unpack(bref)); + break; + case ie_iei_local_time_zone: + local_time_zone_present = true; + HANDLE_CODE(local_time_zone.unpack(bref)); + break; + case ie_iei_universal_time_and_local_time_zone: + universal_time_and_local_time_zone_present = true; + HANDLE_CODE(universal_time_and_local_time_zone.unpack(bref)); + break; + case ie_iei_network_daylight_saving_time: + network_daylight_saving_time_present = true; + HANDLE_CODE(network_daylight_saving_time.unpack(bref)); + break; + case ie_iei_ladn_information: + ladn_information_present = true; + HANDLE_CODE(ladn_information.unpack(bref)); + break; + case ie_iei_mico_indication: + mico_indication_present = true; + HANDLE_CODE(mico_indication.unpack(bref)); + break; + case ie_iei_network_slicing_indication: + network_slicing_indication_present = true; + HANDLE_CODE(network_slicing_indication.unpack(bref)); + break; + case ie_iei_configured_nssai: + configured_nssai_present = true; + HANDLE_CODE(configured_nssai.unpack(bref)); + break; + case ie_iei_rejected_nssai: + rejected_nssai_present = true; + HANDLE_CODE(rejected_nssai.unpack(bref)); + break; + case ie_iei_operator_defined_access_category_definitions: + operator_defined_access_category_definitions_present = true; + HANDLE_CODE(operator_defined_access_category_definitions.unpack(bref)); + break; + case ie_iei_sms_indication: + sms_indication_present = true; + HANDLE_CODE(sms_indication.unpack(bref)); + break; + case ie_iei_t3447_value: + t3447_value_present = true; + HANDLE_CODE(t3447_value.unpack(bref)); + break; + case ie_iei_cag_information_list: + cag_information_list_present = true; + HANDLE_CODE(cag_information_list.unpack(bref)); + break; + case ie_iei_ue_radio_capability_id: + ue_radio_capability_id_present = true; + HANDLE_CODE(ue_radio_capability_id.unpack(bref)); + break; + case ie_iei_ue_radio_capability_id_deletion_indication: + ue_radio_capability_id_deletion_indication_present = true; + HANDLE_CODE(ue_radio_capability_id_deletion_indication.unpack(bref)); + break; + case ie_iei_registration_result_5gs: + registration_result_5gs_present = true; + HANDLE_CODE(registration_result_5gs.unpack(bref)); + break; + case ie_iei_truncated_5g_s_tmsi_configuration: + truncated_5g_s_tmsi_configuration_present = true; + HANDLE_CODE(truncated_5g_s_tmsi_configuration.unpack(bref)); + break; + case ie_iei_additional_configuration_indication: + additional_configuration_indication_present = true; + HANDLE_CODE(additional_configuration_indication.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE configuration_update_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE configuration_update_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE authentication_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(abba.pack(bref)); + + // Optional fields + if (authentication_parameter_rand_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authentication_parameter_rand, 8)); + HANDLE_CODE(authentication_parameter_rand.pack(bref)); + } + if (authentication_parameter_autn_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authentication_parameter_autn, 8)); + HANDLE_CODE(authentication_parameter_autn.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE authentication_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(abba.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_authentication_parameter_rand: + authentication_parameter_rand_present = true; + HANDLE_CODE(authentication_parameter_rand.unpack(bref)); + break; + case ie_iei_authentication_parameter_autn: + authentication_parameter_autn_present = true; + HANDLE_CODE(authentication_parameter_autn.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE authentication_response_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (authentication_response_parameter_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authentication_response_parameter, 8)); + HANDLE_CODE(authentication_response_parameter.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE authentication_response_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_authentication_response_parameter: + authentication_response_parameter_present = true; + HANDLE_CODE(authentication_response_parameter.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE authentication_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE authentication_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE authentication_failure_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.pack(bref)); + + // Optional fields + if (authentication_failure_parameter_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authentication_failure_parameter, 8)); + HANDLE_CODE(authentication_failure_parameter.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE authentication_failure_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_authentication_failure_parameter: + authentication_failure_parameter_present = true; + HANDLE_CODE(authentication_failure_parameter.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE authentication_result_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(eap_message.pack(bref)); + + // Optional fields + if (abba_present == true) { + HANDLE_CODE(bref.pack(ie_iei_abba, 8)); + HANDLE_CODE(abba.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE authentication_result_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(eap_message.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_abba: + abba_present = true; + HANDLE_CODE(abba.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE identity_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(identity_type.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE identity_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(identity_type.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE identity_response_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(mobile_identity.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE identity_response_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(mobile_identity.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE security_mode_command_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(selected_nas_security_algorithms.pack(bref)); + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(ng_ksi.pack(bref)); + HANDLE_CODE(replayed_ue_security_capabilities.pack(bref)); + + // Optional fields + if (imeisv_request_present == true) { + HANDLE_CODE(bref.pack(ie_iei_imeisv_request, 4)); + HANDLE_CODE(imeisv_request.pack(bref)); + } + if (selected_eps_nas_security_algorithms_present == true) { + HANDLE_CODE(bref.pack(ie_iei_selected_eps_nas_security_algorithms, 8)); + HANDLE_CODE(selected_eps_nas_security_algorithms.pack(bref)); + } + if (additional_5g_security_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_5g_security_information, 8)); + HANDLE_CODE(additional_5g_security_information.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (abba_present == true) { + HANDLE_CODE(bref.pack(ie_iei_abba, 8)); + HANDLE_CODE(abba.pack(bref)); + } + if (replayed_s1_ue_security_capabilities_present == true) { + HANDLE_CODE(bref.pack(ie_iei_replayed_s1_ue_security_capabilities, 8)); + HANDLE_CODE(replayed_s1_ue_security_capabilities.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE security_mode_command_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(selected_nas_security_algorithms.unpack(bref)); + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(ng_ksi.unpack(bref)); + HANDLE_CODE(replayed_ue_security_capabilities.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_imeisv_request: + imeisv_request_present = true; + HANDLE_CODE(imeisv_request.unpack(bref)); + break; + case ie_iei_selected_eps_nas_security_algorithms: + selected_eps_nas_security_algorithms_present = true; + HANDLE_CODE(selected_eps_nas_security_algorithms.unpack(bref)); + break; + case ie_iei_additional_5g_security_information: + additional_5g_security_information_present = true; + HANDLE_CODE(additional_5g_security_information.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_abba: + abba_present = true; + HANDLE_CODE(abba.unpack(bref)); + break; + case ie_iei_replayed_s1_ue_security_capabilities: + replayed_s1_ue_security_capabilities_present = true; + HANDLE_CODE(replayed_s1_ue_security_capabilities.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE security_mode_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (imeisv_present == true) { + HANDLE_CODE(bref.pack(ie_iei_imeisv, 8)); + HANDLE_CODE(imeisv.pack(bref)); + } + if (nas_message_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_nas_message_container, 8)); + HANDLE_CODE(nas_message_container.pack(bref)); + } + if (non_imeisv_pei_present == true) { + HANDLE_CODE(bref.pack(ie_iei_non_imeisv_pei, 8)); + HANDLE_CODE(non_imeisv_pei.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE security_mode_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_imeisv: + imeisv_present = true; + HANDLE_CODE(imeisv.unpack(bref)); + break; + case ie_iei_nas_message_container: + nas_message_container_present = true; + HANDLE_CODE(nas_message_container.unpack(bref)); + break; + case ie_iei_non_imeisv_pei: + non_imeisv_pei_present = true; + HANDLE_CODE(non_imeisv_pei.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE security_mode_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE security_mode_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE status_5gmm_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE status_5gmm_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gmm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE notification_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(access_type.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE notification_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(access_type.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE notification_response_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (pdu_session_status_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_status, 8)); + HANDLE_CODE(pdu_session_status.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE notification_response_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_status: + pdu_session_status_present = true; + HANDLE_CODE(pdu_session_status.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE ul_nas_transport_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(payload_container_type.pack(bref)); + HANDLE_CODE(payload_container.pack(bref)); + + // Optional fields + if (pdu_session_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_id, 8)); + HANDLE_CODE(pdu_session_id.pack(bref)); + } + if (old_pdu_session_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_old_pdu_session_id, 8)); + HANDLE_CODE(old_pdu_session_id.pack(bref)); + } + if (request_type_present == true) { + HANDLE_CODE(bref.pack(ie_iei_request_type, 4)); + HANDLE_CODE(request_type.pack(bref)); + } + if (s_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_s_nssai, 8)); + HANDLE_CODE(s_nssai.pack(bref)); + } + if (dnn_present == true) { + HANDLE_CODE(bref.pack(ie_iei_dnn, 8)); + HANDLE_CODE(dnn.pack(bref)); + } + if (additional_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_information, 8)); + HANDLE_CODE(additional_information.pack(bref)); + } + if (ma_pdu_session_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ma_pdu_session_information, 4)); + HANDLE_CODE(ma_pdu_session_information.pack(bref)); + } + if (release_assistance_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_release_assistance_indication, 4)); + HANDLE_CODE(release_assistance_indication.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE ul_nas_transport_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(payload_container_type.unpack(bref)); + HANDLE_CODE(payload_container.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_id: + pdu_session_id_present = true; + HANDLE_CODE(pdu_session_id.unpack(bref)); + break; + case ie_iei_old_pdu_session_id: + old_pdu_session_id_present = true; + HANDLE_CODE(old_pdu_session_id.unpack(bref)); + break; + case ie_iei_request_type: + request_type_present = true; + HANDLE_CODE(request_type.unpack(bref)); + break; + case ie_iei_s_nssai: + s_nssai_present = true; + HANDLE_CODE(s_nssai.unpack(bref)); + break; + case ie_iei_dnn: + dnn_present = true; + HANDLE_CODE(dnn.unpack(bref)); + break; + case ie_iei_additional_information: + additional_information_present = true; + HANDLE_CODE(additional_information.unpack(bref)); + break; + case ie_iei_ma_pdu_session_information: + ma_pdu_session_information_present = true; + HANDLE_CODE(ma_pdu_session_information.unpack(bref)); + break; + case ie_iei_release_assistance_indication: + release_assistance_indication_present = true; + HANDLE_CODE(release_assistance_indication.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE dl_nas_transport_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.pack(bref)); + HANDLE_CODE(payload_container_type.pack(bref)); + HANDLE_CODE(payload_container.pack(bref)); + + // Optional fields + if (pdu_session_id_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_id, 8)); + HANDLE_CODE(pdu_session_id.pack(bref)); + } + if (additional_information_present == true) { + HANDLE_CODE(bref.pack(ie_iei_additional_information, 8)); + HANDLE_CODE(additional_information.pack(bref)); + } + if (cause_5gmm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gmm, 8)); + HANDLE_CODE(cause_5gmm.pack(bref)); + } + if (back_off_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_back_off_timer_value, 8)); + HANDLE_CODE(back_off_timer_value.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE dl_nas_transport_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(spare_half_octet.unpack(bref)); + HANDLE_CODE(payload_container_type.unpack(bref)); + HANDLE_CODE(payload_container.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_id: + pdu_session_id_present = true; + HANDLE_CODE(pdu_session_id.unpack(bref)); + break; + case ie_iei_additional_information: + additional_information_present = true; + HANDLE_CODE(additional_information.unpack(bref)); + break; + case ie_iei_cause_5gmm: + cause_5gmm_present = true; + HANDLE_CODE(cause_5gmm.unpack(bref)); + break; + case ie_iei_back_off_timer_value: + back_off_timer_value_present = true; + HANDLE_CODE(back_off_timer_value.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_establishment_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(integrity_protection_maximum_data_rate.pack(bref)); + + // Optional fields + if (pdu_session_type_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_session_type, 4)); + HANDLE_CODE(pdu_session_type.pack(bref)); + } + if (ssc_mode_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ssc_mode, 4)); + HANDLE_CODE(ssc_mode.pack(bref)); + } + if (capability_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_capability_5gsm, 8)); + HANDLE_CODE(capability_5gsm.pack(bref)); + } + if (maximum_number_of_supported_packet_filters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_maximum_number_of_supported_packet_filters, 8)); + HANDLE_CODE(maximum_number_of_supported_packet_filters.pack(bref)); + } + if (always_on_pdu_session_requested_present == true) { + HANDLE_CODE(bref.pack(ie_iei_always_on_pdu_session_requested, 4)); + HANDLE_CODE(always_on_pdu_session_requested.pack(bref)); + } + if (sm_pdu_dn_request_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_sm_pdu_dn_request_container, 8)); + HANDLE_CODE(sm_pdu_dn_request_container.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (ip_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ip_header_compression_configuration, 8)); + HANDLE_CODE(ip_header_compression_configuration.pack(bref)); + } + if (ds_tt__ethernet_port_mac_address_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ds_tt__ethernet_port_mac_address, 8)); + HANDLE_CODE(ds_tt__ethernet_port_mac_address.pack(bref)); + } + if (ue_ds_tt_residence_time_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ue_ds_tt_residence_time, 8)); + HANDLE_CODE(ue_ds_tt_residence_time.pack(bref)); + } + if (port_management_information_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_port_management_information_container, 8)); + HANDLE_CODE(port_management_information_container.pack(bref)); + } + if (ethernet_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ethernet_header_compression_configuration, 8)); + HANDLE_CODE(ethernet_header_compression_configuration.pack(bref)); + } + if (suggested_interface_identifier_present == true) { + HANDLE_CODE(bref.pack(ie_iei_suggested_interface_identifier, 8)); + HANDLE_CODE(suggested_interface_identifier.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_establishment_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(integrity_protection_maximum_data_rate.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_pdu_session_type: + pdu_session_type_present = true; + HANDLE_CODE(pdu_session_type.unpack(bref)); + break; + case ie_iei_ssc_mode: + ssc_mode_present = true; + HANDLE_CODE(ssc_mode.unpack(bref)); + break; + case ie_iei_capability_5gsm: + capability_5gsm_present = true; + HANDLE_CODE(capability_5gsm.unpack(bref)); + break; + case ie_iei_maximum_number_of_supported_packet_filters: + maximum_number_of_supported_packet_filters_present = true; + HANDLE_CODE(maximum_number_of_supported_packet_filters.unpack(bref)); + break; + case ie_iei_always_on_pdu_session_requested: + always_on_pdu_session_requested_present = true; + HANDLE_CODE(always_on_pdu_session_requested.unpack(bref)); + break; + case ie_iei_sm_pdu_dn_request_container: + sm_pdu_dn_request_container_present = true; + HANDLE_CODE(sm_pdu_dn_request_container.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_ip_header_compression_configuration: + ip_header_compression_configuration_present = true; + HANDLE_CODE(ip_header_compression_configuration.unpack(bref)); + break; + case ie_iei_ds_tt__ethernet_port_mac_address: + ds_tt__ethernet_port_mac_address_present = true; + HANDLE_CODE(ds_tt__ethernet_port_mac_address.unpack(bref)); + break; + case ie_iei_ue_ds_tt_residence_time: + ue_ds_tt_residence_time_present = true; + HANDLE_CODE(ue_ds_tt_residence_time.unpack(bref)); + break; + case ie_iei_port_management_information_container: + port_management_information_container_present = true; + HANDLE_CODE(port_management_information_container.unpack(bref)); + break; + case ie_iei_ethernet_header_compression_configuration: + ethernet_header_compression_configuration_present = true; + HANDLE_CODE(ethernet_header_compression_configuration.unpack(bref)); + break; + case ie_iei_suggested_interface_identifier: + suggested_interface_identifier_present = true; + HANDLE_CODE(suggested_interface_identifier.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_establishment_accept_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(selected_ssc_mode.pack(bref)); + HANDLE_CODE(selected_pdu_session_type.pack(bref)); + HANDLE_CODE(authorized__qo_s_rules.pack(bref)); + HANDLE_CODE(session_ambr.pack(bref)); + + // Optional fields + if (cause_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gsm, 8)); + HANDLE_CODE(cause_5gsm.pack(bref)); + } + if (pdu_address_present == true) { + HANDLE_CODE(bref.pack(ie_iei_pdu_address, 8)); + HANDLE_CODE(pdu_address.pack(bref)); + } + if (rq_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rq_timer_value, 8)); + HANDLE_CODE(rq_timer_value.pack(bref)); + } + if (s_nssai_present == true) { + HANDLE_CODE(bref.pack(ie_iei_s_nssai, 8)); + HANDLE_CODE(s_nssai.pack(bref)); + } + if (always_on_pdu_session_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_always_on_pdu_session_indication, 4)); + HANDLE_CODE(always_on_pdu_session_indication.pack(bref)); + } + if (mapped_eps_bearer_contexts_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mapped_eps_bearer_contexts, 8)); + HANDLE_CODE(mapped_eps_bearer_contexts.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (authorized__qo_s_flow_descriptions_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authorized__qo_s_flow_descriptions, 8)); + HANDLE_CODE(authorized__qo_s_flow_descriptions.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (dnn_present == true) { + HANDLE_CODE(bref.pack(ie_iei_dnn, 8)); + HANDLE_CODE(dnn.pack(bref)); + } + if (network_feature_support_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_network_feature_support_5gsm, 8)); + HANDLE_CODE(network_feature_support_5gsm.pack(bref)); + } + if (serving_plmn_rate_control_present == true) { + HANDLE_CODE(bref.pack(ie_iei_serving_plmn_rate_control, 8)); + HANDLE_CODE(serving_plmn_rate_control.pack(bref)); + } + if (atsss_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_atsss_container, 8)); + HANDLE_CODE(atsss_container.pack(bref)); + } + if (control_plane_only_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_control_plane_only_indication, 4)); + HANDLE_CODE(control_plane_only_indication.pack(bref)); + } + if (ip_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ip_header_compression_configuration, 8)); + HANDLE_CODE(ip_header_compression_configuration.pack(bref)); + } + if (ethernet_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ethernet_header_compression_configuration, 8)); + HANDLE_CODE(ethernet_header_compression_configuration.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_establishment_accept_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(selected_ssc_mode.unpack(bref)); + HANDLE_CODE(selected_pdu_session_type.unpack(bref)); + HANDLE_CODE(authorized__qo_s_rules.unpack(bref)); + HANDLE_CODE(session_ambr.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_cause_5gsm: + cause_5gsm_present = true; + HANDLE_CODE(cause_5gsm.unpack(bref)); + break; + case ie_iei_pdu_address: + pdu_address_present = true; + HANDLE_CODE(pdu_address.unpack(bref)); + break; + case ie_iei_rq_timer_value: + rq_timer_value_present = true; + HANDLE_CODE(rq_timer_value.unpack(bref)); + break; + case ie_iei_s_nssai: + s_nssai_present = true; + HANDLE_CODE(s_nssai.unpack(bref)); + break; + case ie_iei_always_on_pdu_session_indication: + always_on_pdu_session_indication_present = true; + HANDLE_CODE(always_on_pdu_session_indication.unpack(bref)); + break; + case ie_iei_mapped_eps_bearer_contexts: + mapped_eps_bearer_contexts_present = true; + HANDLE_CODE(mapped_eps_bearer_contexts.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_authorized__qo_s_flow_descriptions: + authorized__qo_s_flow_descriptions_present = true; + HANDLE_CODE(authorized__qo_s_flow_descriptions.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_dnn: + dnn_present = true; + HANDLE_CODE(dnn.unpack(bref)); + break; + case ie_iei_network_feature_support_5gsm: + network_feature_support_5gsm_present = true; + HANDLE_CODE(network_feature_support_5gsm.unpack(bref)); + break; + case ie_iei_serving_plmn_rate_control: + serving_plmn_rate_control_present = true; + HANDLE_CODE(serving_plmn_rate_control.unpack(bref)); + break; + case ie_iei_atsss_container: + atsss_container_present = true; + HANDLE_CODE(atsss_container.unpack(bref)); + break; + case ie_iei_control_plane_only_indication: + control_plane_only_indication_present = true; + HANDLE_CODE(control_plane_only_indication.unpack(bref)); + break; + case ie_iei_ip_header_compression_configuration: + ip_header_compression_configuration_present = true; + HANDLE_CODE(ip_header_compression_configuration.unpack(bref)); + break; + case ie_iei_ethernet_header_compression_configuration: + ethernet_header_compression_configuration_present = true; + HANDLE_CODE(ethernet_header_compression_configuration.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_establishment_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + if (back_off_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_back_off_timer_value, 8)); + HANDLE_CODE(back_off_timer_value.pack(bref)); + } + if (allowed_ssc_mode_present == true) { + HANDLE_CODE(bref.pack(ie_iei_allowed_ssc_mode, 4)); + HANDLE_CODE(allowed_ssc_mode.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (congestion_re_attempt_indicator_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_congestion_re_attempt_indicator_5gsm, 8)); + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (re_attempt_indicator_present == true) { + HANDLE_CODE(bref.pack(ie_iei_re_attempt_indicator, 8)); + HANDLE_CODE(re_attempt_indicator.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_establishment_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_back_off_timer_value: + back_off_timer_value_present = true; + HANDLE_CODE(back_off_timer_value.unpack(bref)); + break; + case ie_iei_allowed_ssc_mode: + allowed_ssc_mode_present = true; + HANDLE_CODE(allowed_ssc_mode.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_congestion_re_attempt_indicator_5gsm: + congestion_re_attempt_indicator_5gsm_present = true; + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_re_attempt_indicator: + re_attempt_indicator_present = true; + HANDLE_CODE(re_attempt_indicator.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_authentication_command_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(eap_message.pack(bref)); + + // Optional fields + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_authentication_command_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(eap_message.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_authentication_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(eap_message.pack(bref)); + + // Optional fields + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_authentication_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(eap_message.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_authentication_result_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_authentication_result_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_modification_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (capability_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_capability_5gsm, 8)); + HANDLE_CODE(capability_5gsm.pack(bref)); + } + if (cause_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gsm, 8)); + HANDLE_CODE(cause_5gsm.pack(bref)); + } + if (maximum_number_of_supported_packet_filters_present == true) { + HANDLE_CODE(bref.pack(ie_iei_maximum_number_of_supported_packet_filters, 8)); + HANDLE_CODE(maximum_number_of_supported_packet_filters.pack(bref)); + } + if (always_on_pdu_session_requested_present == true) { + HANDLE_CODE(bref.pack(ie_iei_always_on_pdu_session_requested, 4)); + HANDLE_CODE(always_on_pdu_session_requested.pack(bref)); + } + if (integrity_protection_maximum_data_rate_present == true) { + HANDLE_CODE(bref.pack(ie_iei_integrity_protection_maximum_data_rate, 8)); + HANDLE_CODE(integrity_protection_maximum_data_rate.pack(bref)); + } + if (requested__qo_s_rules_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested__qo_s_rules, 8)); + HANDLE_CODE(requested__qo_s_rules.pack(bref)); + } + if (requested__qo_s_flow_descriptions_present == true) { + HANDLE_CODE(bref.pack(ie_iei_requested__qo_s_flow_descriptions, 8)); + HANDLE_CODE(requested__qo_s_flow_descriptions.pack(bref)); + } + if (mapped_eps_bearer_contexts_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mapped_eps_bearer_contexts, 8)); + HANDLE_CODE(mapped_eps_bearer_contexts.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (port_management_information_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_port_management_information_container, 8)); + HANDLE_CODE(port_management_information_container.pack(bref)); + } + if (ip_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ip_header_compression_configuration, 8)); + HANDLE_CODE(ip_header_compression_configuration.pack(bref)); + } + if (ethernet_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ethernet_header_compression_configuration, 8)); + HANDLE_CODE(ethernet_header_compression_configuration.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_modification_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_capability_5gsm: + capability_5gsm_present = true; + HANDLE_CODE(capability_5gsm.unpack(bref)); + break; + case ie_iei_cause_5gsm: + cause_5gsm_present = true; + HANDLE_CODE(cause_5gsm.unpack(bref)); + break; + case ie_iei_maximum_number_of_supported_packet_filters: + maximum_number_of_supported_packet_filters_present = true; + HANDLE_CODE(maximum_number_of_supported_packet_filters.unpack(bref)); + break; + case ie_iei_always_on_pdu_session_requested: + always_on_pdu_session_requested_present = true; + HANDLE_CODE(always_on_pdu_session_requested.unpack(bref)); + break; + case ie_iei_integrity_protection_maximum_data_rate: + integrity_protection_maximum_data_rate_present = true; + HANDLE_CODE(integrity_protection_maximum_data_rate.unpack(bref)); + break; + case ie_iei_requested__qo_s_rules: + requested__qo_s_rules_present = true; + HANDLE_CODE(requested__qo_s_rules.unpack(bref)); + break; + case ie_iei_requested__qo_s_flow_descriptions: + requested__qo_s_flow_descriptions_present = true; + HANDLE_CODE(requested__qo_s_flow_descriptions.unpack(bref)); + break; + case ie_iei_mapped_eps_bearer_contexts: + mapped_eps_bearer_contexts_present = true; + HANDLE_CODE(mapped_eps_bearer_contexts.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_port_management_information_container: + port_management_information_container_present = true; + HANDLE_CODE(port_management_information_container.unpack(bref)); + break; + case ie_iei_ip_header_compression_configuration: + ip_header_compression_configuration_present = true; + HANDLE_CODE(ip_header_compression_configuration.unpack(bref)); + break; + case ie_iei_ethernet_header_compression_configuration: + ethernet_header_compression_configuration_present = true; + HANDLE_CODE(ethernet_header_compression_configuration.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_modification_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + if (back_off_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_back_off_timer_value, 8)); + HANDLE_CODE(back_off_timer_value.pack(bref)); + } + if (congestion_re_attempt_indicator_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_congestion_re_attempt_indicator_5gsm, 8)); + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (re_attempt_indicator_present == true) { + HANDLE_CODE(bref.pack(ie_iei_re_attempt_indicator, 8)); + HANDLE_CODE(re_attempt_indicator.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_modification_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_back_off_timer_value: + back_off_timer_value_present = true; + HANDLE_CODE(back_off_timer_value.unpack(bref)); + break; + case ie_iei_congestion_re_attempt_indicator_5gsm: + congestion_re_attempt_indicator_5gsm_present = true; + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_re_attempt_indicator: + re_attempt_indicator_present = true; + HANDLE_CODE(re_attempt_indicator.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_modification_command_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (cause_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gsm, 8)); + HANDLE_CODE(cause_5gsm.pack(bref)); + } + if (session_ambr_present == true) { + HANDLE_CODE(bref.pack(ie_iei_session_ambr, 8)); + HANDLE_CODE(session_ambr.pack(bref)); + } + if (rq_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_rq_timer_value, 8)); + HANDLE_CODE(rq_timer_value.pack(bref)); + } + if (always_on_pdu_session_indication_present == true) { + HANDLE_CODE(bref.pack(ie_iei_always_on_pdu_session_indication, 4)); + HANDLE_CODE(always_on_pdu_session_indication.pack(bref)); + } + if (authorized__qo_s_rules_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authorized__qo_s_rules, 8)); + HANDLE_CODE(authorized__qo_s_rules.pack(bref)); + } + if (mapped_eps_bearer_contexts_present == true) { + HANDLE_CODE(bref.pack(ie_iei_mapped_eps_bearer_contexts, 8)); + HANDLE_CODE(mapped_eps_bearer_contexts.pack(bref)); + } + if (authorized__qo_s_flow_descriptions_present == true) { + HANDLE_CODE(bref.pack(ie_iei_authorized__qo_s_flow_descriptions, 8)); + HANDLE_CODE(authorized__qo_s_flow_descriptions.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (atsss_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_atsss_container, 8)); + HANDLE_CODE(atsss_container.pack(bref)); + } + if (ip_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ip_header_compression_configuration, 8)); + HANDLE_CODE(ip_header_compression_configuration.pack(bref)); + } + if (port_management_information_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_port_management_information_container, 8)); + HANDLE_CODE(port_management_information_container.pack(bref)); + } + if (serving_plmn_rate_control_present == true) { + HANDLE_CODE(bref.pack(ie_iei_serving_plmn_rate_control, 8)); + HANDLE_CODE(serving_plmn_rate_control.pack(bref)); + } + if (ethernet_header_compression_configuration_present == true) { + HANDLE_CODE(bref.pack(ie_iei_ethernet_header_compression_configuration, 8)); + HANDLE_CODE(ethernet_header_compression_configuration.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_modification_command_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_cause_5gsm: + cause_5gsm_present = true; + HANDLE_CODE(cause_5gsm.unpack(bref)); + break; + case ie_iei_session_ambr: + session_ambr_present = true; + HANDLE_CODE(session_ambr.unpack(bref)); + break; + case ie_iei_rq_timer_value: + rq_timer_value_present = true; + HANDLE_CODE(rq_timer_value.unpack(bref)); + break; + case ie_iei_always_on_pdu_session_indication: + always_on_pdu_session_indication_present = true; + HANDLE_CODE(always_on_pdu_session_indication.unpack(bref)); + break; + case ie_iei_authorized__qo_s_rules: + authorized__qo_s_rules_present = true; + HANDLE_CODE(authorized__qo_s_rules.unpack(bref)); + break; + case ie_iei_mapped_eps_bearer_contexts: + mapped_eps_bearer_contexts_present = true; + HANDLE_CODE(mapped_eps_bearer_contexts.unpack(bref)); + break; + case ie_iei_authorized__qo_s_flow_descriptions: + authorized__qo_s_flow_descriptions_present = true; + HANDLE_CODE(authorized__qo_s_flow_descriptions.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_atsss_container: + atsss_container_present = true; + HANDLE_CODE(atsss_container.unpack(bref)); + break; + case ie_iei_ip_header_compression_configuration: + ip_header_compression_configuration_present = true; + HANDLE_CODE(ip_header_compression_configuration.unpack(bref)); + break; + case ie_iei_port_management_information_container: + port_management_information_container_present = true; + HANDLE_CODE(port_management_information_container.unpack(bref)); + break; + case ie_iei_serving_plmn_rate_control: + serving_plmn_rate_control_present = true; + HANDLE_CODE(serving_plmn_rate_control.unpack(bref)); + break; + case ie_iei_ethernet_header_compression_configuration: + ethernet_header_compression_configuration_present = true; + HANDLE_CODE(ethernet_header_compression_configuration.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_modification_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (port_management_information_container_present == true) { + HANDLE_CODE(bref.pack(ie_iei_port_management_information_container, 8)); + HANDLE_CODE(port_management_information_container.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_modification_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_port_management_information_container: + port_management_information_container_present = true; + HANDLE_CODE(port_management_information_container.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_modification_command_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_modification_command_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_release_request_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (cause_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gsm, 8)); + HANDLE_CODE(cause_5gsm.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_release_request_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_cause_5gsm: + cause_5gsm_present = true; + HANDLE_CODE(cause_5gsm.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_release_reject_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_release_reject_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_release_command_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + if (back_off_timer_value_present == true) { + HANDLE_CODE(bref.pack(ie_iei_back_off_timer_value, 8)); + HANDLE_CODE(back_off_timer_value.pack(bref)); + } + if (eap_message_present == true) { + HANDLE_CODE(bref.pack(ie_iei_eap_message, 8)); + HANDLE_CODE(eap_message.pack(bref)); + } + if (congestion_re_attempt_indicator_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_congestion_re_attempt_indicator_5gsm, 8)); + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + if (access_type_present == true) { + HANDLE_CODE(bref.pack(ie_iei_access_type, 4)); + HANDLE_CODE(access_type.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_release_command_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_back_off_timer_value: + back_off_timer_value_present = true; + HANDLE_CODE(back_off_timer_value.unpack(bref)); + break; + case ie_iei_eap_message: + eap_message_present = true; + HANDLE_CODE(eap_message.unpack(bref)); + break; + case ie_iei_congestion_re_attempt_indicator_5gsm: + congestion_re_attempt_indicator_5gsm_present = true; + HANDLE_CODE(congestion_re_attempt_indicator_5gsm.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + case ie_iei_access_type: + access_type_present = true; + HANDLE_CODE(access_type.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE pdu_session_release_complete_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + + // Optional fields + if (cause_5gsm_present == true) { + HANDLE_CODE(bref.pack(ie_iei_cause_5gsm, 8)); + HANDLE_CODE(cause_5gsm.pack(bref)); + } + if (extended_protocol_configuration_options_present == true) { + HANDLE_CODE(bref.pack(ie_iei_extended_protocol_configuration_options, 8)); + HANDLE_CODE(extended_protocol_configuration_options.pack(bref)); + } + + return SRSASN_SUCCESS; +} +SRSASN_CODE pdu_session_release_complete_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + case ie_iei_cause_5gsm: + cause_5gsm_present = true; + HANDLE_CODE(cause_5gsm.unpack(bref)); + break; + case ie_iei_extended_protocol_configuration_options: + extended_protocol_configuration_options_present = true; + HANDLE_CODE(extended_protocol_configuration_options.unpack(bref)); + break; + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +SRSASN_CODE status_5gsm_t::pack(asn1::bit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.pack(bref)); + + // Optional fields + + return SRSASN_SUCCESS; +} +SRSASN_CODE status_5gsm_t::unpack(asn1::cbit_ref& bref) +{ + // Mandatory fields + HANDLE_CODE(cause_5gsm.unpack(bref)); + + // Optional fields + + while (bref.distance_bytes_end() > 0) { + // some iei are only 1/2 byte long which are > 8 + // otherwise a complete byte + uint8_t iei; + HANDLE_CODE(bref.unpack(iei, 4)); + if (iei < 8) { + uint8_t iei_tmp; + HANDLE_CODE(bref.unpack(iei_tmp, 4)); + iei = iei << 4 | iei_tmp; + } + + switch (iei) { + default: + asn1::log_error("Invalid IE %x", iei); + break; + } + } + + return SRSASN_SUCCESS; +} + +// Include from nas5g/infiles/nas_5g_msg.cc.in + +SRSASN_CODE nas_5gs_hdr::unpack_outer(asn1::cbit_ref& bref) +{ + unpack_enum(bref, &extended_protocol_discriminator); + // Security header type associated with a spare half octet; or PDU session identity + switch (extended_protocol_discriminator) { + case extended_protocol_discriminator_5gmm: + HANDLE_CODE(bref.advance_bits(4)); // spare + unpack_enum(bref, &security_header_type); + if (security_header_type == plain_5gs_nas_message) { + HANDLE_CODE(message_type.unpack(bref)); + } else { + HANDLE_CODE(bref.unpack(message_authentication_code, 32)); + HANDLE_CODE(bref.unpack(sequence_number, 8)); + } + break; + case extended_protocol_discriminator_5gsm: + // The PDU session identity and the procedure transaction identity are only used in messages with extended + // protocol discriminator 5GS session management. Octet 2a with the procedure transaction identity shall only be + // included in these messages. + HANDLE_CODE(bref.unpack(pdu_session_identity, 8)); + HANDLE_CODE(bref.unpack(procedure_transaction_identity, 8)); + HANDLE_CODE(message_type.unpack(bref)); + break; + default: + asn1::log_error("Unsupported extended protocol discriminator %x\n", extended_protocol_discriminator); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_hdr::unpack(asn1::cbit_ref& bref) +{ + unpack_outer(bref); + if (security_header_type != plain_5gs_nas_message) { + unpack_enum(bref, &inner_extended_protocol_discriminator); + // Security header type associated with a spare half octet; or PDU session identity + switch (inner_extended_protocol_discriminator) { + case extended_protocol_discriminator_5gmm: + HANDLE_CODE(bref.advance_bits(4)); // spare + unpack_enum(bref, &inner_security_header_type); + if (inner_security_header_type == plain_5gs_nas_message) { + HANDLE_CODE(message_type.unpack(bref)); + } else { + asn1::log_error("Expected inner security type to be plain\n"); + return SRSASN_ERROR_DECODE_FAIL; + } + break; + case extended_protocol_discriminator_5gsm: + // The PDU session identity and the procedure transaction identity are only used in messages with extended + // protocol discriminator 5GS session management. Octet 2a with the procedure transaction identity shall only be + // included in these messages. + HANDLE_CODE(bref.unpack(pdu_session_identity, 8)); + HANDLE_CODE(bref.unpack(procedure_transaction_identity, 8)); + HANDLE_CODE(message_type.unpack(bref)); + break; + default: + asn1::log_error("Unsupported extended protocol discriminator %x\n", inner_extended_protocol_discriminator); + return SRSASN_ERROR_DECODE_FAIL; + } + } + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_hdr::pack_outer(asn1::bit_ref& bref) +{ + pack_enum(bref, extended_protocol_discriminator); + // Security header type associated with a spare half octet; or PDU session identity + switch (extended_protocol_discriminator) { + case extended_protocol_discriminator_5gmm: + HANDLE_CODE(bref.pack(0x0, 4)); // spare + pack_enum(bref, security_header_type); + if (security_header_type == plain_5gs_nas_message) { + HANDLE_CODE(message_type.pack(bref)); + } else { + HANDLE_CODE(bref.pack(message_authentication_code, 32)); + HANDLE_CODE(bref.pack(sequence_number, 8)); + } + break; + case extended_protocol_discriminator_5gsm: + // The PDU session identity and the procedure transaction identity are only used in messages with extended + // protocol discriminator 5GS session management. Octet 2a with the procedure transaction identity shall only be + // included in these messages. + HANDLE_CODE(bref.pack(pdu_session_identity, 8)); + HANDLE_CODE(bref.pack(procedure_transaction_identity, 8)); + HANDLE_CODE(message_type.pack(bref)); + break; + default: + asn1::log_error("Unsupported extended protocol discriminator %x\n", extended_protocol_discriminator); + return SRSASN_ERROR_DECODE_FAIL; + } + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_hdr::pack(asn1::bit_ref& bref) +{ + pack_outer(bref); + if (security_header_type != plain_5gs_nas_message) { + pack_enum(bref, inner_extended_protocol_discriminator); + if (inner_extended_protocol_discriminator == extended_protocol_discriminator_5gsm) { + HANDLE_CODE(bref.pack(pdu_session_identity, 4)); + } else { + HANDLE_CODE(bref.pack(0x0, 4)); + } + pack_enum(bref, inner_security_header_type); + if (inner_extended_protocol_discriminator == extended_protocol_discriminator_5gsm) { + HANDLE_CODE(bref.pack(procedure_transaction_identity, 8)); + } + HANDLE_CODE(message_type.pack(bref)); + } + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::pack(unique_byte_buffer_t& buf) +{ + asn1::bit_ref msg_bref(buf->msg, buf->get_tailroom()); + HANDLE_CODE(pack(msg_bref)); + buf->N_bytes = msg_bref.distance_bytes(); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::pack(std::vector buf) +{ + buf.resize(SRSRAN_MAX_BUFFER_SIZE_BYTES); + asn1::bit_ref msg_bref(buf.data(), buf.size()); + HANDLE_CODE(pack(msg_bref)); + buf.resize(msg_bref.distance_bytes()); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::pack(asn1::bit_ref& msg_bref) +{ + HANDLE_CODE(hdr.pack(msg_bref)); + switch (hdr.message_type) { + case msg_types::options::registration_request: { + registration_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::registration_accept: { + registration_accept_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::registration_complete: { + registration_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::registration_reject: { + registration_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::deregistration_request_ue_originating: { + deregistration_request_ue_originating_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::deregistration_accept_ue_originating: { + deregistration_accept_ue_originating_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::deregistration_request_ue_terminated: { + deregistration_request_ue_terminated_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::deregistration_accept_ue_terminated: { + deregistration_accept_ue_terminated_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::service_request: { + service_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::service_reject: { + service_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::service_accept: { + service_accept_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::configuration_update_command: { + configuration_update_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::configuration_update_complete: { + configuration_update_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::authentication_request: { + authentication_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::authentication_response: { + authentication_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::authentication_reject: { + authentication_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::authentication_failure: { + authentication_failure_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::authentication_result: { + authentication_result_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::identity_request: { + identity_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::identity_response: { + identity_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::security_mode_command: { + security_mode_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::security_mode_complete: { + security_mode_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::security_mode_reject: { + security_mode_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::status_5gmm: { + status_5gmm_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::notification: { + notification_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::notification_response: { + notification_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::ul_nas_transport: { + ul_nas_transport_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::dl_nas_transport: { + dl_nas_transport_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_request: { + pdu_session_establishment_request_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_accept: { + pdu_session_establishment_accept_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_reject: { + pdu_session_establishment_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_command: { + pdu_session_authentication_command_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_complete: { + pdu_session_authentication_complete_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_result: { + pdu_session_authentication_result_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_request: { + pdu_session_modification_request_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_reject: { + pdu_session_modification_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_command: { + pdu_session_modification_command_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_complete: { + pdu_session_modification_complete_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_command_reject: { + pdu_session_modification_command_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_request: { + pdu_session_release_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_reject: { + pdu_session_release_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_command: { + pdu_session_release_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_complete: { + pdu_session_release_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + case msg_types::options::status_5gsm: { + status_5gsm_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->pack(msg_bref)); + break; + } + + default: + break; + } + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::unpack_outer_hdr(const unique_byte_buffer_t& buf) +{ + asn1::cbit_ref msg_bref(buf->msg, buf->N_bytes); + HANDLE_CODE(hdr.unpack_outer(msg_bref)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::unpack_outer_hdr(const std::vector buf) +{ + asn1::cbit_ref msg_bref(buf.data(), buf.size()); + HANDLE_CODE(hdr.unpack_outer(msg_bref)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::unpack(const unique_byte_buffer_t& buf) +{ + asn1::cbit_ref msg_bref(buf->msg, buf->N_bytes); + HANDLE_CODE(unpack(msg_bref)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::unpack(const std::vector buf) +{ + asn1::cbit_ref msg_bref(buf.data(), buf.size()); + HANDLE_CODE(unpack(msg_bref)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE nas_5gs_msg::unpack(asn1::cbit_ref& msg_bref) +{ + HANDLE_CODE(hdr.unpack(msg_bref)); + switch (hdr.message_type) { + case msg_types::options::registration_request: { + msg_container = srslog::detail::any{registration_request_t()}; + registration_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::registration_accept: { + msg_container = srslog::detail::any{registration_accept_t()}; + registration_accept_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::registration_complete: { + msg_container = srslog::detail::any{registration_complete_t()}; + registration_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::registration_reject: { + msg_container = srslog::detail::any{registration_reject_t()}; + registration_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::deregistration_request_ue_originating: { + msg_container = srslog::detail::any{deregistration_request_ue_originating_t()}; + deregistration_request_ue_originating_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::deregistration_accept_ue_originating: { + msg_container = srslog::detail::any{deregistration_accept_ue_originating_t()}; + deregistration_accept_ue_originating_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::deregistration_request_ue_terminated: { + msg_container = srslog::detail::any{deregistration_request_ue_terminated_t()}; + deregistration_request_ue_terminated_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::deregistration_accept_ue_terminated: { + msg_container = srslog::detail::any{deregistration_accept_ue_terminated_t()}; + deregistration_accept_ue_terminated_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::service_request: { + msg_container = srslog::detail::any{service_request_t()}; + service_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::service_reject: { + msg_container = srslog::detail::any{service_reject_t()}; + service_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::service_accept: { + msg_container = srslog::detail::any{service_accept_t()}; + service_accept_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::configuration_update_command: { + msg_container = srslog::detail::any{configuration_update_command_t()}; + configuration_update_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::configuration_update_complete: { + msg_container = srslog::detail::any{configuration_update_complete_t()}; + configuration_update_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::authentication_request: { + msg_container = srslog::detail::any{authentication_request_t()}; + authentication_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::authentication_response: { + msg_container = srslog::detail::any{authentication_response_t()}; + authentication_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::authentication_reject: { + msg_container = srslog::detail::any{authentication_reject_t()}; + authentication_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::authentication_failure: { + msg_container = srslog::detail::any{authentication_failure_t()}; + authentication_failure_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::authentication_result: { + msg_container = srslog::detail::any{authentication_result_t()}; + authentication_result_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::identity_request: { + msg_container = srslog::detail::any{identity_request_t()}; + identity_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::identity_response: { + msg_container = srslog::detail::any{identity_response_t()}; + identity_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::security_mode_command: { + msg_container = srslog::detail::any{security_mode_command_t()}; + security_mode_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::security_mode_complete: { + msg_container = srslog::detail::any{security_mode_complete_t()}; + security_mode_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::security_mode_reject: { + msg_container = srslog::detail::any{security_mode_reject_t()}; + security_mode_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::status_5gmm: { + msg_container = srslog::detail::any{status_5gmm_t()}; + status_5gmm_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::notification: { + msg_container = srslog::detail::any{notification_t()}; + notification_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::notification_response: { + msg_container = srslog::detail::any{notification_response_t()}; + notification_response_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::ul_nas_transport: { + msg_container = srslog::detail::any{ul_nas_transport_t()}; + ul_nas_transport_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::dl_nas_transport: { + msg_container = srslog::detail::any{dl_nas_transport_t()}; + dl_nas_transport_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_request: { + msg_container = srslog::detail::any{pdu_session_establishment_request_t()}; + pdu_session_establishment_request_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_accept: { + msg_container = srslog::detail::any{pdu_session_establishment_accept_t()}; + pdu_session_establishment_accept_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_establishment_reject: { + msg_container = srslog::detail::any{pdu_session_establishment_reject_t()}; + pdu_session_establishment_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_command: { + msg_container = srslog::detail::any{pdu_session_authentication_command_t()}; + pdu_session_authentication_command_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_complete: { + msg_container = srslog::detail::any{pdu_session_authentication_complete_t()}; + pdu_session_authentication_complete_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_authentication_result: { + msg_container = srslog::detail::any{pdu_session_authentication_result_t()}; + pdu_session_authentication_result_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_request: { + msg_container = srslog::detail::any{pdu_session_modification_request_t()}; + pdu_session_modification_request_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_reject: { + msg_container = srslog::detail::any{pdu_session_modification_reject_t()}; + pdu_session_modification_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_command: { + msg_container = srslog::detail::any{pdu_session_modification_command_t()}; + pdu_session_modification_command_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_complete: { + msg_container = srslog::detail::any{pdu_session_modification_complete_t()}; + pdu_session_modification_complete_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_modification_command_reject: { + msg_container = srslog::detail::any{pdu_session_modification_command_reject_t()}; + pdu_session_modification_command_reject_t* msg = + srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_request: { + msg_container = srslog::detail::any{pdu_session_release_request_t()}; + pdu_session_release_request_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_reject: { + msg_container = srslog::detail::any{pdu_session_release_reject_t()}; + pdu_session_release_reject_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_command: { + msg_container = srslog::detail::any{pdu_session_release_command_t()}; + pdu_session_release_command_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::pdu_session_release_complete: { + msg_container = srslog::detail::any{pdu_session_release_complete_t()}; + pdu_session_release_complete_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + case msg_types::options::status_5gsm: { + msg_container = srslog::detail::any{status_5gsm_t()}; + status_5gsm_t* msg = srslog::detail::any_cast(&msg_container); + HANDLE_CODE(msg->unpack(msg_bref)); + break; + } + + default: + break; + } + return SRSASN_SUCCESS; +} + +} // namespace nas_5g +} // namespace srsran diff --git a/lib/src/asn1/nas_5g_utils.cc b/lib/src/asn1/nas_5g_utils.cc new file mode 100644 index 000000000..24915c8c8 --- /dev/null +++ b/lib/src/asn1/nas_5g_utils.cc @@ -0,0 +1,56 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/asn1/nas_5g_utils.h" + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/common.h" +#include "srsran/config.h" + +#include +#include +#include + +namespace srsran { +namespace nas_5g { + +SRSASN_CODE unpack_mcc_mnc(uint8_t* mcc_bytes, uint8_t* mnc_bytes, asn1::cbit_ref& bref) +{ + // MCC digit 2 | MCC digit 1 | octet 5 + // MNC digit 3 | MCC digit 3 | octet 6 + // MNC digit 2 | MNC digit 1 | octet 7 + HANDLE_CODE(bref.unpack(mcc_bytes[1], 4)); + HANDLE_CODE(bref.unpack(mcc_bytes[0], 4)); + HANDLE_CODE(bref.unpack(mnc_bytes[2], 4)); + HANDLE_CODE(bref.unpack(mcc_bytes[2], 4)); + HANDLE_CODE(bref.unpack(mnc_bytes[1], 4)); + HANDLE_CODE(bref.unpack(mnc_bytes[0], 4)); + return SRSASN_SUCCESS; +} + +SRSASN_CODE pack_mcc_mnc(uint8_t* mcc_bytes, uint8_t* mnc_bytes, asn1::bit_ref& bref) +{ + // MCC digit 2 | MCC digit 1 | octet 5 + // MNC digit 3 | MCC digit 3 | octet 6 + // MNC digit 2 | MNC digit 1 | octet 7 + HANDLE_CODE(bref.pack(mcc_bytes[1], 4)); + HANDLE_CODE(bref.pack(mcc_bytes[0], 4)); + HANDLE_CODE(bref.pack(mnc_bytes[2], 4)); + HANDLE_CODE(bref.pack(mcc_bytes[2], 4)); + HANDLE_CODE(bref.pack(mnc_bytes[1], 4)); + HANDLE_CODE(bref.pack(mnc_bytes[0], 4)); + return SRSASN_SUCCESS; +} + +} // namespace nas_5g +} // namespace srsran \ No newline at end of file diff --git a/lib/test/asn1/CMakeLists.txt b/lib/test/asn1/CMakeLists.txt index 5ee4ff156..1c7054213 100644 --- a/lib/test/asn1/CMakeLists.txt +++ b/lib/test/asn1/CMakeLists.txt @@ -59,3 +59,6 @@ target_link_libraries(rrc_asn1_decoder rrc_asn1) add_executable(nas_decoder nas_decoder.cc) target_link_libraries(nas_decoder srsran_asn1) + +add_executable(nas_5g_msg_test nas_5g_msg_test.cc) +target_link_libraries(nas_5g_msg_test nas_5g_msg) \ No newline at end of file diff --git a/lib/test/asn1/nas_5g_msg_test.cc b/lib/test/asn1/nas_5g_msg_test.cc new file mode 100644 index 000000000..440602b9f --- /dev/null +++ b/lib/test/asn1/nas_5g_msg_test.cc @@ -0,0 +1,1610 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include +#include + +#include "srsran/asn1/nas_5g_msg.h" +#include "srsran/common/buffer_pool.h" +#include "srsran/common/nas_pcap.h" +#include "srsran/common/test_common.h" +#include "srsran/srslog/srslog.h" + +using namespace srsran::nas_5g; + +#define HAVE_PCAP 0 + +inline void print_msg(const srsran::unique_byte_buffer_t& msg) +{ + printf("\t"); + for (uint32_t i = 0; i < msg->N_bytes; i++) { + printf("0x%02x ", msg->msg[i]); + if ((i + 1) % 16 == 0) { + printf("\n\t"); + } + } + printf("\n"); +} + +inline void hex_dump(uint8_t* buf, uint32_t buf_length) +{ + printf("\t"); + for (uint32_t i = 0; i < buf_length; i++) { + printf("0x%02x ", buf[i]); + if ((i + 1) % 16 == 0) { + printf("\n\t"); + } + } + printf("\n"); +} + +void copy_msg_to_buffer(srsran::unique_byte_buffer_t& pdu, srsran::const_byte_span msg) +{ + pdu = srsran::make_byte_buffer(); + memcpy(pdu->msg, msg.data(), msg.size()); + pdu->N_bytes = msg.size(); +} + +int registration_request_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + uint8_t reg_request[] = {0x7e, 0x00, 0x41, 0x79, 0x00, 0x0b, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2e, 0x02, 0xf0, 0xf0, 0x17, 0x07, 0xf0, 0xf0, 0xc0, 0xc0, 0x01, 0x80, 0x30}; + // Non-Access-Stratum 5GS (NAS)PDU + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Registration request (0x41) + // 5GS registration type + // .... 1... = Follow-On Request bit (FOR): Follow-on request pending + // .... .001 = 5GS registration type: initial registration (1) + // NAS key set identifier + // 0... .... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .111 .... = NAS key set identifier: 7 + // 5GS mobile identity + // Length: 11 + // .... 0... = Odd/even indication: Even number of identity digits + // .... .010 = Type of identity: 5G-GUTI (2) + // Mobile Country Code (MCC): Unknown (0) + // Mobile Network Code (MNC): Unknown (000) + // AMF Region ID: 0 + // 0000 0000 00.. .... = AMF Set ID: 0 + // ..00 0000 = AMF Pointer: 0 + // 5G-TMSI: 0 (0x00000000) + // + // UE security capability + // Element ID: 0x2e + // Length: 2 + // 1... .... = 5G-EA0: Supported + // .1.. .... = 128-5G-EA1: Supported + // ..1. .... = 128-5G-EA2: Supported + // ...1 .... = 128-5G-EA3: Supported + // .... 0... = 5G-EA4: Not supported + // .... .0.. = 5G-EA5: Not supported + // .... ..0. = 5G-EA6: Not supported + // .... ...0 = 5G-EA7: Not supported + // 1... .... = 5G-IA0: Supported + // .1.. .... = 128-5G-IA1: Supported + // ..1. .... = 128-5G-IA2: Supported + // ...1 .... = 128-5G-IA3: Supported + // .... 0... = 5G-IA4: Not supported + // .... .0.. = 5G-IA5: Not supported + // .... ..0. = 5G-IA6: Not supported + // .... ...0 = 5G-IA7: Not supported + // UE network capability + // Element ID: 0x17 + // Length: 7 + // 1... .... = EEA0: Supported + // .1.. .... = 128-EEA1: Supported + // ..1. .... = 128-EEA2: Supported + // ...1 .... = 128-EEA3: Supported + // .... 0... = EEA4: Not supported + // .... .0.. = EEA5: Not supported + // .... ..0. = EEA6: Not supported + // .... ...0 = EEA7: Not supported + // 1... .... = EIA0: Supported + // .1.. .... = 128-EIA1: Supported + // ..1. .... = 128-EIA2: Supported + // ...1 .... = 128-EIA3: Supported + // .... 0... = EIA4: Not supported + // .... .0.. = EIA5: Not supported + // .... ..0. = EIA6: Not supported + // .... ...0 = EIA7: Not supported + // 1... .... = UEA0: Supported + // .1.. .... = UEA1: Supported + // ..0. .... = UEA2: Not supported + // ...0 .... = UEA3: Not supported + // .... 0... = UEA4: Not supported + // .... .0.. = UEA5: Not supported + // .... ..0. = UEA6: Not supported + // .... ...0 = UEA7: Not supported + // 1... .... = UCS2 support (UCS2): The UE has no preference between the use of the default alphabet and + // the use of UCS2 .1.. .... = UMTS integrity algorithm UIA1: Supported + // ..0. .... = UMTS integrity algorithm UIA2: Not supported + // ...0 .... = UMTS integrity algorithm UIA3: Not supported + // .... 0... = UMTS integrity algorithm UIA4: Not supported + // .... .0.. = UMTS integrity algorithm UIA5: Not supported + // .... ..0. = UMTS integrity algorithm UIA6: Not supported + // .... ...0 = UMTS integrity algorithm UIA7: Not supported + // 0... .... = ProSe direct discovery: Not supported + // .0.. .... = ProSe: Not supported + // ..0. .... = H.245 After SRVCC Handover: Not supported + // ...0 .... = Access class control for CSFB: Not supported + // .... 0... = LTE Positioning Protocol: Not supported + // .... .0.. = Location services (LCS) notification mechanisms: Not supported + // .... ..0. = SRVCC from E-UTRAN to cdma2000 1xCS: Not supported + // .... ...1 = Notification procedure: Supported + // 1... .... = Extended protocol configuration options: Supported + // .0.. .... = Header compression for control plane CIoT EPS optimization: Not supported + // ..0. .... = EMM-REGISTERED w/o PDN connectivity: Not supported + // ...0 .... = S1-U data transfer: Not supported + // .... 0... = User plane CIoT EPS optimization: Not supported + // .... .0.. = Control plane CIoT EPS optimization: Not supported + // .... ..0. = ProSe UE-to-network relay: Not supported + // .... ...0 = ProSe direct communication: Not supported + // 0... .... = Signalling for a maximum number of 15 EPS bearer contexts: Not supported + // .0.. .... = Service gap control: Not supported + // ..1. .... = N1 mode: Supported + // ...1 .... = Dual connectivity with NR: Supported + // .... 0... = Control plane data backoff: Not supported + // .... .0.. = Restriction on use of enhanced coverage: Not supported + // .... ..0. = V2X communication over PC5: Not supported + // .... ...0 = Multiple DRB: Not supported + + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, reg_request); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_request); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_request); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + registration_request_t& reg_request_msg = nas_msg.registration_request(); + TESTASSERT(reg_request_msg.registration_type_5gs.registration_type == + registration_type_5gs_t::registration_type_type_::options::initial_registration); + TESTASSERT(reg_request_msg.registration_type_5gs.follow_on_request_bit == + registration_type_5gs_t::follow_on_request_bit_type_::options::follow_on_request_pending); + TESTASSERT(reg_request_msg.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(reg_request_msg.ng_ksi.nas_key_set_identifier == + key_set_identifier_t::nas_key_set_identifier_type_::options::no_key_is_available_or_reserved); + TESTASSERT(reg_request_msg.mobile_identity_5gs.length == 11); + TESTASSERT(reg_request_msg.mobile_identity_5gs.type() == mobile_identity_5gs_t::identity_types_::options::guti_5g); + mobile_identity_5gs_t::guti_5g_s guti_5g_ = reg_request_msg.mobile_identity_5gs.guti_5g(); + TESTASSERT(guti_5g_.amf_pointer == 0x0); + TESTASSERT(guti_5g_.amf_region_id == 0x0); + TESTASSERT(guti_5g_.amf_set_id == 0); + TESTASSERT(guti_5g_.mcc[0] == 0); + TESTASSERT(guti_5g_.mcc[1] == 0); + TESTASSERT(guti_5g_.mcc[2] == 0); + TESTASSERT(guti_5g_.mnc[0] == 0); + TESTASSERT(guti_5g_.mnc[1] == 0); + TESTASSERT(guti_5g_.mnc[2] == 0); + TESTASSERT(reg_request_msg.ue_security_capability_present == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea0_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea1_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea2_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea3_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea3_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ea4_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ea5_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ea6_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ea7_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ia0_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ia1_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ia2_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ia3_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ia3_128_5g_supported == true); + TESTASSERT(reg_request_msg.ue_security_capability.ia4_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ia5_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ia6_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.ia7_5g_supported == false); + TESTASSERT(reg_request_msg.ue_security_capability.eps_caps_present == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability_present == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.length == 7); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea0_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea1_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea2_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea3_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea4_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea6_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eea7_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia0_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia1_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia2_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia3_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia4_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia6_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.eia7_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea0_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea1_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea2_128_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea3_128_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea4_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea6_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uea7_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.ucs2_support == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia1_128_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia2_128_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia3_128_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia4_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia6_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.uia7_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.pro_se_dd_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.pro_se_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.h245_ash_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.acc_csfb_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.llp_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.lcs_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.srvcc_capability_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.nf_capability_supported == true); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.e_pco_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.hc_cp_c_io_t_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.e_rw_o_pdn_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.s1_u_data_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.up_c_io_t_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.cp_c_io_t_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.pro_se_relay_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.pro_se_dc_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.max_15_eps_bearer_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.sgc_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.n1mode_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.dcnr_supported == true); + TESTASSERT(reg_request_msg.s1_ue_network_capability.cp_backoff_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.restrict_ec_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.v2_x_pc5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.multiple_drb_supported == false); + + TESTASSERT(reg_request_msg.s1_ue_network_capability.nr_pc5_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.up_mt_edt_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.cp_mt_edt_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.wus_supported == false); + TESTASSERT(reg_request_msg.s1_ue_network_capability.racs_supported == false); + + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + + printf("buf_cmp->N_bytes %d buf->N_bytes %d\n", buf_cmp->N_bytes, buf->N_bytes); + printf("\n"); + print_msg(buf); + printf("\n"); + print_msg(buf_cmp); + printf("\n"); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + return SRSRAN_SUCCESS; +} + +int registration_request_unpacking_packing_test_2(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Registration request (0x41) + // 5GS registration type + // .... 1... = Follow-On Request bit (FOR): Follow-on request pending + // .... .001 = 5GS registration type: initial registration (1) + // NAS key set identifier + // 0... .... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .111 .... = NAS key set identifier: 7 + // 5GS mobile identity + // Length: 54 + // 0... .... = Spare: 0 + // .000 .... = SUPI format: IMSI (0) + // .... 0... = Spare: 0 + // .... .001 = Type of identity: SUCI (1) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // Routing indicator: 17 + // .... 0010 = Protection scheme Id: ECIES scheme profile B (2) + // Home network public key identifier: 27 + // Scheme output: 03 99 7e e4 01 2d e3 6c 86 e2 29 97 c8 99 70 4b 0f 61 3a bd 6c 3b 1c 9c … + // ECC ephemeral public key: 03 99 7e e4 01 2d e3 6c 86 e2 29 97 c8 99 70 4b 0f 61 3a bd 6c 3b 1c 9c … + // Ciphertext: cb bd 5d 27 34 + // MAC tag: 0x1e8b9e3328184bec + // UE security capability + // Element ID: 0x2e + // Length: 2 + // 1... .... = 5G-EA0: Supported + // .0.. .... = 128-5G-EA1: Not supported + // ..0. .... = 128-5G-EA2: Not supported + // ...0 .... = 128-5G-EA3: Not supported + // .... 0... = 5G-EA4: Not supported + // .... .0.. = 5G-EA5: Not supported + // .... ..0. = 5G-EA6: Not supported + // .... ...0 = 5G-EA7: Not supported + // 0... .... = 5G-IA0: Not supported + // .0.. .... = 128-5G-IA1: Not supported + // ..1. .... = 128-5G-IA2: Supported + // ...0 .... = 128-5G-IA3: Not supported + // .... 0... = 5G-IA4: Not supported + // .... .0.. = 5G-IA5: Not supported + // .... ..0. = 5G-IA6: Not supported + // .... ...0 = 5G-IA7: Not supported + + uint8_t reg_request[] = {0x7e, 0x00, 0x41, 0x79, 0x00, 0x36, 0x01, 0x00, 0xf1, 0x10, 0x71, 0xff, 0x02, + 0x1b, 0x03, 0x99, 0x7e, 0xe4, 0x01, 0x2d, 0xe3, 0x6c, 0x86, 0xe2, 0x29, 0x97, + 0xc8, 0x99, 0x70, 0x4b, 0x0f, 0x61, 0x3a, 0xbd, 0x6c, 0x3b, 0x1c, 0x9c, 0xa7, + 0x8a, 0x4b, 0x14, 0x7e, 0x22, 0xaf, 0xb0, 0x64, 0xcb, 0xbd, 0x5d, 0x27, 0x34, + 0x1e, 0x8b, 0x9e, 0x33, 0x28, 0x18, 0x4b, 0xec, 0x2e, 0x02, 0x80, 0x20}; + + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, reg_request); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_request); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_request); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + registration_request_t& reg_request_msg = nas_msg.registration_request(); + TESTASSERT(reg_request_msg.registration_type_5gs.registration_type == + registration_type_5gs_t::registration_type_type_::options::initial_registration); + TESTASSERT(reg_request_msg.registration_type_5gs.follow_on_request_bit == + registration_type_5gs_t::follow_on_request_bit_type_::options::follow_on_request_pending); + TESTASSERT(reg_request_msg.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(reg_request_msg.ng_ksi.nas_key_set_identifier == + key_set_identifier_t::nas_key_set_identifier_type_::options::no_key_is_available_or_reserved); + TESTASSERT(reg_request_msg.mobile_identity_5gs.length == 54); + TESTASSERT(reg_request_msg.mobile_identity_5gs.type() == mobile_identity_5gs_t::identity_types_::options::suci); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().supi_format.value == + mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mcc[0] == 0); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mcc[1] == 0); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mcc[2] == 1); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mnc[0] == 0); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mnc[1] == 1); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().mnc[2] == 0xf); + + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().routing_indicator[0] == 1); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().routing_indicator[1] == 7); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().routing_indicator[2] == 0xf); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().routing_indicator[3] == 0xf); + + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().protection_scheme_id == + mobile_identity_5gs_t::suci_s::protection_scheme_id_type_::options::ecies_scheme_profile_b); + TESTASSERT(reg_request_msg.mobile_identity_5gs.suci().home_network_public_key_identifier == 27); + + hex_dump(reg_request_msg.mobile_identity_5gs.suci().scheme_output.data(), + reg_request_msg.mobile_identity_5gs.suci().scheme_output.size()); + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + + printf("buf_cmp->N_bytes %d buf->N_bytes %d\n", buf_cmp->N_bytes, buf->N_bytes); + printf("\n"); + print_msg(buf); + printf("\n"); + print_msg(buf_cmp); + printf("\n"); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + return SRSRAN_SUCCESS; +} + +int deregistration_request_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0001 = Security header type: Integrity protected (1) + // Message authentication code: 0x6f0325f5 + // Sequence number: 2 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Deregistration request (UE originating) (0x45) + // De-registration type + // .... 1... = Switch off: Switch off + // .... .0.. = Re-registration required: re-registration not required + // .... ..01 = Access type: 3GPP access (1) + // NAS key set identifier + // 0... .... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .000 .... = NAS key set identifier: 0 + // 5GS mobile identity + // Length: 11 + // .... 0... = Odd/even indication: Even number of identity digits + // .... .010 = Type of identity: 5G-GUTI (2) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // AMF Region ID: 202 + // 1111 1110 00.. .... = AMF Set ID: 1016 + // ..00 0000 = AMF Pointer: 0 + // 5G-TMSI: 1 (0x00000001) + // + uint8_t dereg_request[] = {0x7e, 0x01, 0x6f, 0x03, 0x25, 0xf5, 0x02, 0x7e, 0x00, 0x45, 0x09, 0x00, + 0x0b, 0x02, 0x00, 0xf1, 0x10, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x01}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, dereg_request); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0x6f0325f5); + TESTASSERT(nas_msg.hdr.sequence_number == 2); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::deregistration_request_ue_originating); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + deregistration_request_ue_originating_t& dereg_request_msg = nas_msg.deregistration_request_ue_originating(); + TESTASSERT(dereg_request_msg.de_registration_type.switch_off == + de_registration_type_t::switch_off_type_::options::switch_off); + TESTASSERT(dereg_request_msg.de_registration_type.re_registration_required == + de_registration_type_t::re_registration_required_type_::options::re_registration_not_required); + TESTASSERT(dereg_request_msg.de_registration_type.access_type == + de_registration_type_t::access_type_type_::options::access_3_gpp); + TESTASSERT(dereg_request_msg.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(dereg_request_msg.ng_ksi.nas_key_set_identifier == 0); + TESTASSERT(dereg_request_msg.mobile_identity_5gs.length == 11); + TESTASSERT(dereg_request_msg.mobile_identity_5gs.type() == mobile_identity_5gs_t::identity_types_::options::guti_5g); + mobile_identity_5gs_t::guti_5g_s guti_5g_ = dereg_request_msg.mobile_identity_5gs.guti_5g(); + TESTASSERT(guti_5g_.amf_pointer == 0x0); + TESTASSERT(guti_5g_.amf_region_id == 202); + TESTASSERT(guti_5g_.amf_set_id == 1016); + TESTASSERT(guti_5g_.mcc[0] == 0); + TESTASSERT(guti_5g_.mcc[1] == 0); + TESTASSERT(guti_5g_.mcc[2] == 1); + TESTASSERT(guti_5g_.mnc[0] == 0); + TESTASSERT(guti_5g_.mnc[1] == 1); + TESTASSERT(guti_5g_.mnc[2] == 0xf); + TESTASSERT(guti_5g_.tmsi_5g == 0x00000001); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int authentication_request_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Authentication request (0x56) + // 0000 .... = Spare Half Octet: 0 + // NAS key set identifier - ngKSI + // .... 0... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .... .000 = NAS key set identifier: 0 + // ABBA + // Length: 2 + // ABBA Contents: 0x0000 + // Authentication Parameter RAND - 5G authentication challenge + // Element ID: 0x21 + // RAND value: 16 46 24 32 75 b8 b9 c7 18 b6 05 c6 ff 03 96 71 + // Authentication Parameter AUTN (UMTS and EPS authentication challenge) - 5G authentication challenge + // Element ID: 0x20 + // Length: 16 + // AUTN value: a3 09 26 e4 2e ea 80 00 f6 87 d5 ba a2 d9 56 ed + // SQN xor AK: a3 09 26 e4 2e ea + // AMF: 80 00 + // MAC: f6 87 d5 ba a2 d9 56 ed + + uint8_t auth_request[] = {0x7e, 0x00, 0x56, 0x00, 0x02, 0x00, 0x00, 0x21, 0x16, 0x46, 0x24, 0x32, 0x75, 0xb8, + 0xb9, 0xc7, 0x18, 0xb6, 0x05, 0xc6, 0xff, 0x03, 0x96, 0x71, 0x20, 0x10, 0xa3, 0x09, + 0x26, 0xe4, 0x2e, 0xea, 0x80, 0x00, 0xf6, 0x87, 0xd5, 0xba, 0xa2, 0xd9, 0x56, 0xed}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, auth_request); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + + nas_5gs_msg nas_msg; + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::authentication_request); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + authentication_request_t& auth_request_msg = nas_msg.authentication_request(); + TESTASSERT(auth_request_msg.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(auth_request_msg.ng_ksi.nas_key_set_identifier == 0); + TESTASSERT(auth_request_msg.abba.length == 2); + TESTASSERT(auth_request_msg.abba.abba_contents[0] == 0x00); + TESTASSERT(auth_request_msg.abba.abba_contents[1] == 0x00); + TESTASSERT(auth_request_msg.authentication_parameter_rand_present == true); + TESTASSERT(auth_request_msg.authentication_parameter_rand.rand[0] == 0x16); + TESTASSERT(auth_request_msg.authentication_parameter_rand.rand[15] == 0x71); + TESTASSERT(auth_request_msg.authentication_parameter_autn_present == true); + TESTASSERT(auth_request_msg.authentication_parameter_autn.length == 16); + TESTASSERT(auth_request_msg.authentication_parameter_autn.autn[0] == 0xa3); + TESTASSERT(auth_request_msg.authentication_parameter_autn.autn[15] == 0xed); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int authentication_resp_request_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Authentication response (0x57) + // Authentication response parameter + // Element ID: 0x2d + // Length: 16 + // RES: a1 1f 51 a4 1d a9 b5 29 b3 3b 04 3a e1 e2 02 08 + + uint8_t auth_resp_buf[] = {0x7e, 0x00, 0x57, 0x2d, 0x10, 0xa1, 0x1f, 0x51, 0xa4, 0x1d, 0xa9, + 0xb5, 0x29, 0xb3, 0x3b, 0x04, 0x3a, 0xe1, 0xe2, 0x02, 0x08}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, auth_resp_buf); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::authentication_response); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::authentication_response); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + authentication_response_t& auth_resp = nas_msg.authentication_response(); + + TESTASSERT(auth_resp.authentication_response_parameter_present == true); + TESTASSERT(auth_resp.authentication_response_parameter.length == 16); + TESTASSERT(auth_resp.authentication_response_parameter.res.size() == 16); + TESTASSERT(auth_resp.authentication_response_parameter.res[0] == 0xa1); + TESTASSERT(auth_resp.authentication_response_parameter.res[15] == 0x08); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int security_command_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Security mode command (0x5d) + // NAS security algorithms + // 0000 .... = Type of ciphering algorithm: 5G-EA0 (null ciphering algorithm) (0) + // .... 0010 = Type of integrity protection algorithm: 128-5G-IA2 (2) + // 0000 .... = Spare Half Octet: 0 + // NAS key set identifier - ngKSI + // .... 0... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .... .000 = NAS key set identifier: 0 + // UE security capability - Replayed UE security capabilities + // Length: 4 + // 1... .... = 5G-EA0: Supported + // .1.. .... = 128-5G-EA1: Supported + // ..1. .... = 128-5G-EA2: Supported + // ...1 .... = 128-5G-EA3: Supported + // .... 0... = 5G-EA4: Not supported + // .... .0.. = 5G-EA5: Not supported + // .... ..0. = 5G-EA6: Not supported + // .... ...0 = 5G-EA7: Not supported + // 0... .... = 5G-IA0: Not supported + // .1.. .... = 128-5G-IA1: Supported + // ..1. .... = 128-5G-IA2: Supported + // ...1 .... = 128-5G-IA3: Supported + // .... 0... = 5G-IA4: Not supported + // .... .0.. = 5G-IA5: Not supported + // .... ..0. = 5G-IA6: Not supported + // .... ...0 = 5G-IA7: Not supported + // 1... .... = EEA0: Supported + // .1.. .... = 128-EEA1: Supported + // ..1. .... = 128-EEA2: Supported + // ...1 .... = 128-EEA3: Supported + // .... 0... = EEA4: Not supported + // .... .0.. = EEA5: Not supported + // .... ..0. = EEA6: Not supported + // .... ...0 = EEA7: Not supported + // 0... .... = EIA0: Not supported + // .1.. .... = 128-EIA1: Supported + // ..1. .... = 128-EIA2: Supported + // ...1 .... = 128-EIA3: Supported + // .... 0... = EIA4: Not supported + // .... .0.. = EIA5: Not supported + // .... ..0. = EIA6: Not supported + // .... ...0 = EIA7: Not supported + // IMEISV request + // 1110 .... = Element ID: 0xe- + // .... 0... = Spare bit(s): 0x00 + // .... .001 = IMEISV request: IMEISV requested (1) + // Additional 5G security information + // Element ID: 0x36 + // Length: 1 + // .... 0... = Spare: 0 + // .... .0.. = Spare: 0 + // .... ..0. = Retransmission of initial NAS message request(RINMR): Not Requested + // .... ...0 = Horizontal derivation parameter (HDP): Not required + + uint8_t sec_command[] = {0x7e, 0x03, 0x53, 0x3f, 0xcb, 0x29, 0x00, 0x7e, 0x00, 0x5d, 0x02, + 0x00, 0x04, 0xf0, 0x70, 0xf0, 0x70, 0xe1, 0x36, 0x01, 0x00}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, sec_command); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_with_new_5G_nas_context); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0x533fcb29); + TESTASSERT(nas_msg.hdr.sequence_number == 0); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::security_mode_command); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + security_mode_command_t& sec_command_msg = nas_msg.security_mode_command(); + TESTASSERT(sec_command_msg.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(sec_command_msg.ng_ksi.nas_key_set_identifier == 0); + + TESTASSERT(sec_command_msg.selected_nas_security_algorithms.ciphering_algorithm == + security_algorithms_t::ciphering_algorithm_type_::options::ea0_5g); + TESTASSERT(sec_command_msg.selected_nas_security_algorithms.integrity_protection_algorithm == + security_algorithms_t::integrity_protection_algorithm_type_::options::ia2_128_5g); + + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea0_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea1_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea2_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea3_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea4_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea5_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea6_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ea7_5g_supported == false); + + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia0_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia1_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia2_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia3_128_5g_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia4_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia5_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia6_5g_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.ia7_5g_supported == false); + + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eps_caps_present == true); + + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea0_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea1_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea2_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea3_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea4_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea5_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea6_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eea7_supported == false); + + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia0_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia1_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia2_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia3_128_supported == true); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia4_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia5_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia6_supported == false); + TESTASSERT(sec_command_msg.replayed_ue_security_capabilities.eia7_supported == false); + + TESTASSERT(sec_command_msg.imeisv_request_present == true); + TESTASSERT(sec_command_msg.imeisv_request.imeisv_request == true); + + TESTASSERT(sec_command_msg.additional_5g_security_information_present == true); + TESTASSERT(sec_command_msg.additional_5g_security_information.length == 1); + TESTASSERT(sec_command_msg.additional_5g_security_information.rinmr == false); + TESTASSERT(sec_command_msg.additional_5g_security_information.hdp == false); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + + printf("buf_cmp->N_bytes %d buf->N_bytes %d\n", buf_cmp->N_bytes, buf->N_bytes); + printf("\n"); + print_msg(buf); + printf("\n"); + print_msg(buf_cmp); + printf("\n"); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int security_complete_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0100 = Security header type: Integrity protected and ciphered with new 5GS security context (4) + // Message authentication code: 0x4088e4e4 + // Sequence number: 0 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Security mode complete (0x5e) + // 5GS mobile identity + // Element ID: 0x77 + // Length: 9 + // .... 0... = Odd/even indication: Even number of identity digits + // .... .101 = Type of identity: IMEISV (5) + // IMEISV: 8651160458202125 + // NAS message container + // Element ID: 0x71 + // Length: 87 + // Non-Access-Stratum 5GS (NAS)PDU + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Registration request (0x41) + // 5GS registration type + // .... 1... = Follow-On Request bit (FOR): Follow-on request pending + // .... .001 = 5GS registration type: initial registration (1) + // NAS key set identifier + // 0... .... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .111 .... = NAS key set identifier: 7 + // 5GS mobile identity + // Length: 54 + // 0... .... = Spare: 0 + // .000 .... = SUPI format: IMSI (0) + // .... 0... = Spare: 0 + // .... .001 = Type of identity: SUCI (1) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // Routing indicator: 17 + // .... 0010 = Protection scheme Id: ECIES scheme profile B (2) + // Home network public key identifier: 27 + // Scheme output: 03 e3 42 42 99 67 4b 24 bc 8c 8a 54 e2 f9 06 5b f6 92 09 63 b0 9e 37 26 … + // ECC ephemeral public key: 03 e3 42 42 99 67 4b 24 bc 8c 8a 54 e2 f9 06 5b f6 92 09 63 b0 + // 9e 37 26 … Ciphertext: 00 f9 6d 57 82 MAC tag: 0xbf257ecba4d6ce2d + // 5GMM capability + // Element ID: 0x10 + // Length: 1 + // 0... .... = Spare: 0 + // .0.. .... = Spare: 0 + // ..0. .... = Spare: 0 + // ...0 .... = Spare: 0 + // .... 0... = Spare: 0 + // .... .0.. = LTE Positioning Protocol (LPP) capability: Not Requested + // .... ..1. = HO attach: Supported + // .... ...1 = S1 mode: Requested + // UE security capability + // Element ID: 0x2e + // Length: 4 + // 1... .... = 5G-EA0: Supported + // .1.. .... = 128-5G-EA1: Supported + // ..1. .... = 128-5G-EA2: Supported + // ...1 .... = 128-5G-EA3: Supported + // .... 0... = 5G-EA4: Not supported + // .... .0.. = 5G-EA5: Not supported + // .... ..0. = 5G-EA6: Not supported + // .... ...0 = 5G-EA7: Not supported + // 0... .... = 5G-IA0: Not supported + // .1.. .... = 128-5G-IA1: Supported + // ..1. .... = 128-5G-IA2: Supported + // ...1 .... = 128-5G-IA3: Supported + // .... 0... = 5G-IA4: Not supported + // .... .0.. = 5G-IA5: Not supported + // .... ..0. = 5G-IA6: Not supported + // .... ...0 = 5G-IA7: Not supported + // 1... .... = EEA0: Supported + // .1.. .... = 128-EEA1: Supported + // ..1. .... = 128-EEA2: Supported + // ...1 .... = 128-EEA3: Supported + // .... 0... = EEA4: Not supported + // .... .0.. = EEA5: Not supported + // .... ..0. = EEA6: Not supported + // .... ...0 = EEA7: Not supported + // 0... .... = EIA0: Not supported + // .1.. .... = 128-EIA1: Supported + // ..1. .... = 128-EIA2: Supported + // ...1 .... = 128-EIA3: Supported + // .... 0... = EIA4: Not supported + // .... .0.. = EIA5: Not supported + // .... ..0. = EIA6: Not supported + // .... ...0 = EIA7: Not supported + // UE network capability + // Element ID: 0x17 + // Length: 7 + // 1... .... = EEA0: Supported + // .1.. .... = 128-EEA1: Supported + // ..1. .... = 128-EEA2: Supported + // ...1 .... = 128-EEA3: Supported + // .... 0... = EEA4: Not supported + // .... .0.. = EEA5: Not supported + // .... ..0. = EEA6: Not supported + // .... ...0 = EEA7: Not supported + // 0... .... = EIA0: Not supported + // .1.. .... = 128-EIA1: Supported + // ..1. .... = 128-EIA2: Supported + // ...1 .... = 128-EIA3: Supported + // .... 0... = EIA4: Not supported + // .... .0.. = EIA5: Not supported + // .... ..0. = EIA6: Not supported + // .... ...0 = EIA7: Not supported + // 1... .... = UEA0: Supported + // .1.. .... = UEA1: Supported + // ..0. .... = UEA2: Not supported + // ...0 .... = UEA3: Not supported + // .... 0... = UEA4: Not supported + // .... .0.. = UEA5: Not supported + // .... ..0. = UEA6: Not supported + // .... ...0 = UEA7: Not supported + // 0... .... = UCS2 support (UCS2): The UE has a preference for the default alphabet + // .1.. .... = UMTS integrity algorithm UIA1: Supported + // ..0. .... = UMTS integrity algorithm UIA2: Not supported + // ...0 .... = UMTS integrity algorithm UIA3: Not supported + // .... 0... = UMTS integrity algorithm UIA4: Not supported + // .... .0.. = UMTS integrity algorithm UIA5: Not supported + // .... ..0. = UMTS integrity algorithm UIA6: Not supported + // .... ...0 = UMTS integrity algorithm UIA7: Not supported + // 0... .... = ProSe direct discovery: Not supported + // .0.. .... = ProSe: Not supported + // ..0. .... = H.245 After SRVCC Handover: Not supported + // ...1 .... = Access class control for CSFB: Supported + // .... 0... = LTE Positioning Protocol: Not supported + // .... .0.. = Location services (LCS) notification mechanisms: Not supported + // .... ..0. = SRVCC from E-UTRAN to cdma2000 1xCS: Not supported + // .... ...1 = Notification procedure: Supported + // 1... .... = Extended protocol configuration options: Supported + // .0.. .... = Header compression for control plane CIoT EPS optimization: Not supported + // ..0. .... = EMM-REGISTERED w/o PDN connectivity: Not supported + // ...0 .... = S1-U data transfer: Not supported + // .... 0... = User plane CIoT EPS optimization: Not supported + // .... .0.. = Control plane CIoT EPS optimization: Not supported + // .... ..0. = ProSe UE-to-network relay: Not supported + // .... ...0 = ProSe direct communication: Not supported + // 1... .... = Signalling for a maximum number of 15 EPS bearer contexts: Supported + // .0.. .... = Service gap control: Not supported + // ..1. .... = N1 mode: Supported + // ...1 .... = Dual connectivity with NR: Supported + // .... 0... = Control plane data backoff: Not supported + // .... .0.. = Restriction on use of enhanced coverage: Not supported + // .... ..0. = V2X communication over PC5: Not supported + // .... ...0 = Multiple DRB: Not supported + // UE's usage setting + // Element ID: 0x18 + // Length: 1 + // .... 0... = Spare: 0 + // .... .0.. = Spare: 0 + // .... ..0. = Spare: 0 + // .... ...1 = UE's usage setting: Data centric + // LADN indication + // Element ID: 0x74 + // Length: 0 + // 5GS update type + // Element ID: 0x53 + // Length: 1 + // .... 0... = Spare: 0 + // .... .0.. = Spare: 0 + // .... ..0. = NG-RAN Radio Capability Update (NG-RAN-RCU): Not Needed + // .... ...1 = SMS requested: SMS over NAS supported + + uint8_t sec_complete[] = { + 0x7e, 0x04, 0x40, 0x88, 0xe4, 0xe4, 0x00, 0x7e, 0x00, 0x5e, 0x77, 0x00, 0x09, 0x85, 0x56, 0x11, 0x06, 0x54, 0x28, + 0x20, 0x21, 0xf5, 0x71, 0x00, 0x57, 0x7e, 0x00, 0x41, 0x79, 0x00, 0x36, 0x01, 0x00, 0xf1, 0x10, 0x71, 0xff, 0x02, + 0x1b, 0x03, 0xe3, 0x42, 0x42, 0x99, 0x67, 0x4b, 0x24, 0xbc, 0x8c, 0x8a, 0x54, 0xe2, 0xf9, 0x06, 0x5b, 0xf6, 0x92, + 0x09, 0x63, 0xb0, 0x9e, 0x37, 0x26, 0x13, 0x48, 0xf5, 0xfe, 0xdc, 0xa2, 0x42, 0x07, 0x91, 0x00, 0xf9, 0x6d, 0x57, + 0x82, 0xbf, 0x25, 0x7e, 0xcb, 0xa4, 0xd6, 0xce, 0x2d, 0x10, 0x01, 0x03, 0x2e, 0x04, 0xf0, 0x70, 0xf0, 0x70, 0x17, + 0x07, 0xf0, 0x70, 0xc0, 0x40, 0x11, 0x80, 0xb0, 0x18, 0x01, 0x01, 0x74, 0x00, 0x00, 0x53, 0x01, 0x01}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, sec_complete); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered_with_new_5G_nas_context); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0x4088e4e4); + TESTASSERT(nas_msg.hdr.sequence_number == 0); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::security_mode_complete); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + security_mode_complete_t& sec_complete_msg = nas_msg.security_mode_complete(); + + TESTASSERT(sec_complete_msg.imeisv_present == true); + TESTASSERT(sec_complete_msg.imeisv.type() == mobile_identity_5gs_t::identity_types_::options::imeisv); + mobile_identity_5gs_t::imeisv_s imeisv = sec_complete_msg.imeisv.imeisv(); + + TESTASSERT(imeisv.odd_even_indicator == false); + TESTASSERT(imeisv.imeisv[0] == 8); + TESTASSERT(imeisv.imeisv[1] == 6); + TESTASSERT(imeisv.imeisv[2] == 5); + TESTASSERT(imeisv.imeisv[3] == 1); + TESTASSERT(imeisv.imeisv[4] == 1); + TESTASSERT(imeisv.imeisv[5] == 6); + TESTASSERT(imeisv.imeisv[6] == 0); + TESTASSERT(imeisv.imeisv[7] == 4); + TESTASSERT(imeisv.imeisv[8] == 5); + TESTASSERT(imeisv.imeisv[9] == 8); + TESTASSERT(imeisv.imeisv[10] == 2); + TESTASSERT(imeisv.imeisv[11] == 0); + TESTASSERT(imeisv.imeisv[12] == 2); + TESTASSERT(imeisv.imeisv[13] == 1); + TESTASSERT(imeisv.imeisv[14] == 2); + TESTASSERT(imeisv.imeisv[15] == 5); + + TESTASSERT(sec_complete_msg.nas_message_container_present == true); + TESTASSERT(sec_complete_msg.nas_message_container.length == 87); + TESTASSERT(sec_complete_msg.nas_message_container.nas_message_container.size() == 87); + nas_5gs_msg inner_message; + TESTASSERT(inner_message.unpack(sec_complete_msg.nas_message_container.nas_message_container) == SRSRAN_SUCCESS); + // TODO check content of inner message + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int registration_accept_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0010 = Security header type: Integrity protected and ciphered (2) + // Message authentication code: 0xd2b078f7 + // Sequence number: 1 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Registration accept (0x42) + // 5GS registration result + // Length: 1 + // ...0 .... = NSSAA Performed: False + // .... 0... = SMS over NAS: Not Allowed + // .... .001 = 5GS registration result: 3GPP access (1) + // 5GS mobile identity - 5G-GUTI + // Element ID: 0x77 + // Length: 11 + // .... 0... = Odd/even indication: Even number of identity digits + // .... .010 = Type of identity: 5G-GUTI (2) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // AMF Region ID: 202 + // 1111 1110 00.. .... = AMF Set ID: 1016 + // ..00 0000 = AMF Pointer: 0 + // 5G-TMSI: 3 (0x00000003) + // + // 5GS tracking area identity list + // Element ID: 0x54 + // Length: 7 + // Partial tracking area list 1 + // .00. .... = Type of list: list of TACs belonging to one PLMN, with non-consecutive TAC values (0) + // ...0 0000 = Number of elements: 1 element (0) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // TAC: 1 + // NSSAI - Allowed NSSAI + // Element ID: 0x15 + // Length: 10 + // S-NSSAI 1 + // Length: 4 + // Slice/service type (SST): 1 + // Slice differentiator (SD): 66051 + // S-NSSAI 2 + // Length: 4 + // Slice/service type (SST): 1 + // Slice differentiator (SD): 1122867 + // GPRS Timer 3 - T3512 value + // Element ID: 0x5e + // Length: 1 + // GPRS Timer: 60 min + // 000. .... = Unit: value is incremented in multiples of 10 minutes (0) + // ...0 0110 = Timer value: 6 + // GPRS Timer 2 - T3502 value + // Element ID: 0x16 + // Length: 1 + // GPRS Timer: 12 min + // 001. .... = Unit: value is incremented in multiples of 1 minute (1) + // ...0 1100 = Timer value: 12 + + uint8_t reg_accept[] = {0x7e, 0x02, 0xd2, 0xb0, 0x78, 0xf7, 0x01, 0x7e, 0x00, 0x42, 0x01, 0x01, 0x77, 0x00, + 0x0b, 0xf2, 0x00, 0xf1, 0x10, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03, 0x54, 0x07, + 0x00, 0x00, 0xf1, 0x10, 0x00, 0x00, 0x01, 0x15, 0x0a, 0x04, 0x01, 0x01, 0x02, 0x03, + 0x04, 0x01, 0x11, 0x22, 0x33, 0x5e, 0x01, 0x06, 0x16, 0x01, 0x2c}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, reg_accept); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + // Unpacking + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0xd2b078f7); + TESTASSERT(nas_msg.hdr.sequence_number == 1); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_accept); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + return SRSRAN_SUCCESS; +} + +int registration_complete_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0010 = Security header type: Integrity protected and ciphered (2) + // Message authentication code: 0xa0b88817 + // Sequence number: 1 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Registration complete (0x43) + + uint8_t reg_complete[] = {0x7e, 0x02, 0xa0, 0xb8, 0x88, 0x17, 0x01, 0x7e, 0x00, 0x43}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, reg_complete); + +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + nas_5gs_msg nas_msg; + + // Unpacking + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0xa0b88817); + TESTASSERT(nas_msg.hdr.sequence_number == 1); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::registration_complete); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + + return SRSRAN_SUCCESS; +} + +int deregistration_request_unpacking_packing_test_2(srsran::nas_pcap* pcap) +{ + // NAS-PDU: 7e 02 b1 b8 76 98 02 7e 00 45 09 00 0b f2 00 f1 10 ca fe 00 00 00 00 03 + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0010 = Security header type: Integrity protected and ciphered (2) + // Message authentication code: 0xb1b87698 + // Sequence number: 2 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: Deregistration request (UE originating) (0x45) + // De-registration type + // .... 1... = Switch off: Switch off + // .... .0.. = Re-registration required: re-registration not required + // .... ..01 = Access type: 3GPP access (1) + // NAS key set identifier + // 0... .... = Type of security context flag (TSC): Native security context (for KSIAMF) + // .000 .... = NAS key set identifier: 0 + // 5GS mobile identity + // Length: 11 + // .... 0... = Odd/even indication: Even number of identity digits + // .... .010 = Type of identity: 5G-GUTI (2) + // Mobile Country Code (MCC): Unknown (1) + // Mobile Network Code (MNC): Unknown (01) + // AMF Region ID: 202 + // 1111 1110 00.. .... = AMF Set ID: 1016 + // ..00 0000 = AMF Pointer: 0 + // 5G-TMSI: 3 (0x00000003) + // + + uint8_t deregistration_req[] = {0x7e, 0x02, 0xb1, 0xb8, 0x76, 0x98, 0x02, 0x7e, 0x00, 0x45, 0x09, 0x00, + 0x0b, 0x02, 0x00, 0xf1, 0x10, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03}; + + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, deregistration_req); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + + nas_5gs_msg nas_msg; + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0xb1b87698); + TESTASSERT(nas_msg.hdr.sequence_number == 2); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::deregistration_request_ue_originating); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + deregistration_request_ue_originating_t& dereg_req_ue_o = nas_msg.deregistration_request_ue_originating(); + + TESTASSERT(dereg_req_ue_o.de_registration_type.switch_off == + de_registration_type_t::switch_off_type_::options::switch_off); + TESTASSERT(dereg_req_ue_o.de_registration_type.access_type == + de_registration_type_t::access_type_type_::options::access_3_gpp); + TESTASSERT(dereg_req_ue_o.ng_ksi.security_context_flag == + key_set_identifier_t::security_context_flag_type_::options::native_security_context); + TESTASSERT(dereg_req_ue_o.ng_ksi.nas_key_set_identifier == 0); + TESTASSERT(dereg_req_ue_o.mobile_identity_5gs.type() == mobile_identity_5gs_t::identity_types_::options::guti_5g); + TESTASSERT(dereg_req_ue_o.mobile_identity_5gs.length == 11); + mobile_identity_5gs_t::guti_5g_s guti_5g = dereg_req_ue_o.mobile_identity_5gs.guti_5g(); + + TESTASSERT(guti_5g.mcc[0] == 0); + TESTASSERT(guti_5g.mcc[1] == 0); + TESTASSERT(guti_5g.mcc[2] == 1); + TESTASSERT(guti_5g.mnc[0] == 0); + TESTASSERT(guti_5g.mnc[1] == 1); + TESTASSERT(guti_5g.mnc[2] == 0xf); + TESTASSERT(guti_5g.amf_region_id == 202); + TESTASSERT(guti_5g.amf_set_id == 1016); + TESTASSERT(guti_5g.amf_pointer == 0); + TESTASSERT(guti_5g.tmsi_5g == 0x00000003); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int pdu_session_establishment_request_unpacking_packing_test(srsran::nas_pcap* pcap) +{ + // NAS-PDU: 7e 02 dc f9 1d 1b 02 7e 00 67 01 00 06 2e 0a 00 c1 ff ff 12 0a 81 22 04 … + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0010 = Security header type: Integrity protected and ciphered (2) + // Message authentication code: 0xdcf91d1b + // Sequence number: 2 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: UL NAS transport (0x67) + // 0000 .... = Spare Half Octet: 0 + // Payload container type + // .... 0001 = Payload container type: N1 SM information (1) + // Payload container + // Length: 6 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G session management messages (46) + // PDU session identity: PDU session identity value 10 (10) + // Procedure transaction identity: 0 + // Message type: PDU session establishment request (0xc1) + // Integrity protection maximum data rate + // Integrity protection maximum data rate for uplink: Full data rate (255) + // Integrity protection maximum data rate for downlink: Full data rate (255) + // PDU session identity 2 - PDU session ID + // Element ID: 0x12 + // PDU session identity: PDU session identity value 10 (10) + // Request type + // 1000 .... = Element ID: 0x8- + // .... .001 = Request type: Initial request (1) + // S-NSSAI + // Element ID: 0x22 + // Length: 4 + // Slice/service type (SST): 1 + // Slice differentiator (SD): 66051 + // DNN + // Element ID: 0x25 + // Length: 9 + // DNN: internet + + uint8_t pdu_session_bytes[] = {0x7e, 0x02, 0xdc, 0xf9, 0x1d, 0x1b, 0x02, 0x7e, 0x00, 0x67, 0x01, 0x00, 0x06, + 0x2e, 0x0a, 0x00, 0xc1, 0xff, 0xff, 0x12, 0x0a, 0x81, 0x22, 0x04, 0x01, 0x01, + 0x02, 0x03, 0x25, 0x09, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, pdu_session_bytes); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + + nas_5gs_msg nas_msg; + + // Unpacking + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0xdcf91d1b); + TESTASSERT(nas_msg.hdr.sequence_number == 2); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::ul_nas_transport); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + ul_nas_transport_t& ul_nas = nas_msg.ul_nas_transport(); + TESTASSERT(ul_nas.payload_container_type.payload_container_type == + payload_container_type_t::Payload_container_type_type_::options::n1_sm_information); + TESTASSERT(ul_nas.payload_container.length == 6); + TESTASSERT(ul_nas.payload_container.payload_container_contents.size() == 6); + TESTASSERT(ul_nas.payload_container.payload_container_contents[0] == 0x2e); + TESTASSERT(ul_nas.payload_container.payload_container_contents[5] == 0xff); + + // Unpack inner nas + nas_5gs_msg inner_nas; + TESTASSERT(inner_nas.unpack_outer_hdr(ul_nas.payload_container.payload_container_contents) == SRSRAN_SUCCESS); + TESTASSERT(inner_nas.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gsm); + TESTASSERT(inner_nas.hdr.pdu_session_identity == 10); + TESTASSERT(inner_nas.hdr.procedure_transaction_identity == 0); + TESTASSERT(inner_nas.hdr.message_type == msg_types::options::pdu_session_establishment_request); + + TESTASSERT(inner_nas.unpack(ul_nas.payload_container.payload_container_contents) == SRSRAN_SUCCESS); + pdu_session_establishment_request_t pdu_sess_est_req = inner_nas.pdu_session_establishment_request(); + TESTASSERT(pdu_sess_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_uplink == + integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_uplink_type_::options::full_data_rate); + TESTASSERT(pdu_sess_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_downlink == + integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_downlink_type_::options::full_data_rate); + + // Packing inner nas buffer + srsran::unique_byte_buffer_t buf_cmp_inner = srsran::make_byte_buffer(); + inner_nas.pack(buf_cmp_inner); + + // Compare inner nas buffer + TESTASSERT(ul_nas.payload_container.payload_container_contents.size() == buf_cmp_inner.get()->N_bytes); + TESTASSERT(memcmp(ul_nas.payload_container.payload_container_contents.data(), + buf_cmp_inner.get()->msg, + buf_cmp_inner.get()->N_bytes) == 0); + + // Outer again + TESTASSERT(ul_nas.pdu_session_id_present == true); + TESTASSERT(ul_nas.pdu_session_id.pdu_session_identity_2_value == 10); + TESTASSERT(ul_nas.request_type_present == true); + TESTASSERT(ul_nas.request_type.request_type_value == + request_type_t::Request_type_value_type_::options::initial_request); + TESTASSERT(ul_nas.s_nssai_present == true); + TESTASSERT(ul_nas.s_nssai.length == 4); + TESTASSERT(ul_nas.s_nssai.sst == 1); + TESTASSERT(ul_nas.s_nssai.sd == 66051); + TESTASSERT(ul_nas.dnn_present == true); + TESTASSERT(ul_nas.dnn.length == 9); + TESTASSERT(ul_nas.dnn.dnn_value.size() == 9); + TESTASSERT(ul_nas.dnn.dnn_value[0] == 0x08); + TESTASSERT(ul_nas.dnn.dnn_value[1] == 0x69); + TESTASSERT(ul_nas.dnn.dnn_value[8] == 0x74); + + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int pdu_session_est_req_accecpt(srsran::nas_pcap* pcap) +{ + // pDUSessionNAS-PDU: 7e 02 1a ca a2 92 02 7e 00 68 01 00 1d 2e 0a 00 c2 11 00 08 01 06 31 31 … + // Non-Access-Stratum 5GS (NAS)PDU + // Security protected NAS 5GS message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0010 = Security header type: Integrity protected and ciphered (2) + // Message authentication code: 0x1acaa292 + // Sequence number: 2 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G mobility management messages (126) + // 0000 .... = Spare Half Octet: 0 + // .... 0000 = Security header type: Plain NAS message, not security protected (0) + // Message type: DL NAS transport (0x68) + // 0000 .... = Spare Half Octet: 0 + // Payload container type + // .... 0001 = Payload container type: N1 SM information (1) + // Payload container + // Length: 29 + // Plain NAS 5GS Message + // Extended protocol discriminator: 5G session management messages (46) + // PDU session identity: PDU session identity value 10 (10) + // Procedure transaction identity: 0 + // Message type: PDU session establishment accept (0xc2) + // .001 .... = Selected SSC mode: SSC mode 1 (1) + // PDU session type - Selected PDU session type + // .... .001 = PDU session type: IPv4 (1) + // QoS rules - Authorized QoS rules + // Length: 8 + // QoS rule 1 + // QoS rule identifier: 1 + // Length: 1585 + // 001. .... = Rule operation code: Create new QoS rule (1) + // ...1 .... = DQR: The QoS rule is the default QoS rule + // .... 0001 = Number of packet filters: 1 + // Packet filter 1 + // ..00 .... = Packet filter direction: Reserved (0) + // .... 0001 = Packet filter identifier: 1 + // Length: 1 + // Packet filter component 1 + // Packet filter component type: Unknown (0) + // Not dissected yet + // [Expert Info (Note/Protocol): Not dissected yet] + // [Not dissected yet] + // + // [Severity level: Note] + // [Group: Protocol] + // QoS rule precedence: 9 + // 0... .... = Spare: 0 + // .0.. .... = Spare: 0 + // ..00 0110 = Qos flow identifier: 6 + // Session-AMBR + // Length: 6 + // Unit for Session-AMBR for downlink: value is incremented in multiples of 1 Kbps (1) + // Session-AMBR for downlink: 59395 Kbps (59395) + // Unit for Session-AMBR for uplink: value is incremented in multiples of 1 Kbps (1) + // Session-AMBR for uplink: 59395 Kbps (59395) + // PDU address + // Element ID: 0x29 + // Length: 5 + // .... .001 = PDU session type: IPv4 (1) + // PDU address information: 60.60.0.1 + // PDU session identity 2 - PDU session ID + // Element ID: 0x12 + // PDU session identity: PDU session identity value 10 (10) + + uint8_t pdu_session_bytes[] = {0x7e, 0x02, 0x1a, 0xca, 0xa2, 0x92, 0x02, 0x7e, 0x00, 0x68, 0x01, + 0x00, 0x1d, 0x2e, 0x0a, 0x00, 0xc2, 0x11, 0x00, 0x08, 0x01, 0x06, + 0x31, 0x31, 0x01, 0x01, 0x00, 0x09, 0x06, 0x01, 0xe8, 0x03, 0x01, + 0xe8, 0x03, 0x29, 0x05, 0x01, 0x3c, 0x3c, 0x00, 0x01, 0x12, 0x0a}; + srsran::unique_byte_buffer_t buf; + copy_msg_to_buffer(buf, pdu_session_bytes); +#if HAVE_PCAP + pcap->write_nas(buf.get()->msg, buf.get()->N_bytes); +#endif + + nas_5gs_msg nas_msg; + + // Unpacking + TESTASSERT(nas_msg.unpack_outer_hdr(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.security_header_type == nas_5gs_hdr::integrity_protected_and_ciphered); + TESTASSERT(nas_msg.hdr.message_authentication_code == 0x1acaa292); + TESTASSERT(nas_msg.hdr.sequence_number == 2); + + TESTASSERT(nas_msg.unpack(buf) == SRSRAN_SUCCESS); + TESTASSERT(nas_msg.hdr.inner_extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gmm); + TESTASSERT(nas_msg.hdr.inner_security_header_type == nas_5gs_hdr::plain_5gs_nas_message); + TESTASSERT(nas_msg.hdr.message_type == msg_types::options::dl_nas_transport); + printf("%s\n", nas_msg.hdr.message_type.to_string()); + + dl_nas_transport_t& dl_nas = nas_msg.dl_nas_transport(); + TESTASSERT(dl_nas.payload_container_type.payload_container_type == + payload_container_type_t::Payload_container_type_type_::options::n1_sm_information); + TESTASSERT(dl_nas.payload_container.length == 29); + TESTASSERT(dl_nas.payload_container.payload_container_contents.size() == 29); + TESTASSERT(dl_nas.payload_container.payload_container_contents[0] == 0x2e); + TESTASSERT(dl_nas.payload_container.payload_container_contents[28] == 0x01); + + // Unpack inner nas + nas_5gs_msg inner_nas; + TESTASSERT(inner_nas.unpack_outer_hdr(dl_nas.payload_container.payload_container_contents) == SRSRAN_SUCCESS); + TESTASSERT(inner_nas.hdr.extended_protocol_discriminator == nas_5gs_hdr::extended_protocol_discriminator_5gsm); + TESTASSERT(inner_nas.hdr.pdu_session_identity == 10); + TESTASSERT(inner_nas.hdr.procedure_transaction_identity == 0); + TESTASSERT(inner_nas.hdr.message_type == msg_types::options::pdu_session_establishment_accept); + + TESTASSERT(inner_nas.unpack(dl_nas.payload_container.payload_container_contents) == SRSRAN_SUCCESS); + pdu_session_establishment_accept_t pdu_sess_est_acc = inner_nas.pdu_session_establishment_accept(); + TESTASSERT(pdu_sess_est_acc.selected_ssc_mode.ssc_mode_value == + ssc_mode_t::SSC_mode_value_type_::options::ssc_mode_1); + TESTASSERT(pdu_sess_est_acc.selected_pdu_session_type.pdu_session_type_value == + pdu_session_type_t::PDU_session_type_value_type_::options::ipv4); + + TESTASSERT(pdu_sess_est_acc.authorized__qo_s_rules.length == 8); + TESTASSERT(pdu_sess_est_acc.session_ambr.length == 6); + TESTASSERT(pdu_sess_est_acc.session_ambr.unit_session_ambr_for_downlink == + session_ambr_t::unit_session_AMBR_type_::options::inc_by_1_kbps); + TESTASSERT(pdu_sess_est_acc.session_ambr.session_ambr_for_downlink == 59395); + TESTASSERT(pdu_sess_est_acc.session_ambr.unit_session_ambr_for_uplink == + session_ambr_t::unit_session_AMBR_type_::options::inc_by_1_kbps); + TESTASSERT(pdu_sess_est_acc.session_ambr.session_ambr_for_uplink == 59395); + TESTASSERT(pdu_sess_est_acc.pdu_address_present == true); + TESTASSERT(pdu_sess_est_acc.pdu_address.si6_lla == false); + TESTASSERT(pdu_sess_est_acc.pdu_address.pdu_session_type_value == + pdu_address_t::PDU_session_type_value_type_::options::ipv4); + TESTASSERT(pdu_sess_est_acc.pdu_address.ipv4[0] == 0x3c); + TESTASSERT(pdu_sess_est_acc.pdu_address.ipv4[1] == 0x3c); + TESTASSERT(pdu_sess_est_acc.pdu_address.ipv4[2] == 0x00); + TESTASSERT(pdu_sess_est_acc.pdu_address.ipv4[3] == 0x01); + + // Packing inner nas buffer + srsran::unique_byte_buffer_t buf_cmp_inner = srsran::make_byte_buffer(); + inner_nas.pack(buf_cmp_inner); + + // Compare inner nas buffer + // TESTASSERT(dl_nas.payload_container.payload_container_contents.size() == buf_cmp_inner.get()->N_bytes); + // TESTASSERT(memcmp(dl_nas.payload_container.payload_container_contents.data(), + // buf_cmp_inner.get()->msg, + // buf_cmp_inner.get()->N_bytes) == 0); + + // outer nas again + TESTASSERT(dl_nas.pdu_session_id_present == true); + TESTASSERT(dl_nas.pdu_session_id.pdu_session_identity_2_value == 10); + // Packing + srsran::unique_byte_buffer_t buf_cmp = srsran::make_byte_buffer(); + nas_msg.pack(buf_cmp); + +#if HAVE_PCAP + pcap->write_nas(buf_cmp.get()->msg, buf_cmp.get()->N_bytes); +#endif + + // Compare buffer + TESTASSERT(buf.get()->N_bytes == buf_cmp.get()->N_bytes); + TESTASSERT(memcmp(buf.get()->msg, buf_cmp.get()->msg, buf.get()->N_bytes) == 0); + return SRSRAN_SUCCESS; +} + +int main() +{ + srslog::init(); + srsran::console("Testing 5G NAS packing and unpacking\n"); +#if HAVE_PCAP + srsran::nas_pcap pcap; + pcap.open("nas_5g_msg_test.pcap", 0, srsran::srsran_rat_t::nr); + TESTASSERT(registration_request_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(registration_request_unpacking_packing_test_2(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(deregistration_request_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(authentication_request_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(authentication_resp_request_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(security_command_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(security_complete_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(registration_accept_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(registration_complete_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(deregistration_request_unpacking_packing_test_2(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(pdu_session_establishment_request_unpacking_packing_test(&pcap) == SRSRAN_SUCCESS); + TESTASSERT(pdu_session_est_req_accecpt(&pcap) == SRSRAN_SUCCESS); + pcap.close(); +#else + TESTASSERT(registration_request_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(registration_request_unpacking_packing_test_2(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(deregistration_request_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(authentication_request_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(authentication_resp_request_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(security_command_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(security_complete_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(registration_accept_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(registration_complete_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(deregistration_request_unpacking_packing_test_2(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(pdu_session_establishment_request_unpacking_packing_test(nullptr) == SRSRAN_SUCCESS); + TESTASSERT(pdu_session_est_req_accecpt(nullptr) == SRSRAN_SUCCESS); +#endif + return SRSRAN_SUCCESS; +}