From c670383ae96ce8d265e553b89f6018807e705e0f Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 8 Sep 2021 12:02:07 +0200 Subject: [PATCH] Added NAS 5G functions incoming msg and reg proc --- lib/include/srsran/asn1/nas_5g_ies.h | 518 ++++++++--------- lib/include/srsran/asn1/nas_5g_msg.h | 2 +- .../srsran/interfaces/rrc_interface_types.h | 43 ++ .../srsran/interfaces/ue_nas_interfaces.h | 1 + .../srsran/interfaces/ue_rrc_interfaces.h | 6 + srsue/hdr/stack/upper/nas_5g.h | 42 +- srsue/hdr/stack/upper/nas_5g_procedures.h | 1 + srsue/hdr/stack/upper/nas_5gmm_state.h | 3 +- srsue/hdr/stack/upper/nas_base.h | 14 +- srsue/hdr/stack/upper/test/nas_test_common.h | 14 +- srsue/src/stack/upper/nas_5g.cc | 530 +++++++++++++++++- srsue/src/stack/upper/nas_5g_procedures.cc | 1 + 12 files changed, 900 insertions(+), 275 deletions(-) diff --git a/lib/include/srsran/asn1/nas_5g_ies.h b/lib/include/srsran/asn1/nas_5g_ies.h index 6efdfc1f2..95e40ae1d 100644 --- a/lib/include/srsran/asn1/nas_5g_ies.h +++ b/lib/include/srsran/asn1/nas_5g_ies.h @@ -329,26 +329,26 @@ private: class capability_5gmm_t { public: - 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; + bool sgc = false; + bool iphc_cp_c_io_t_5g = false; + bool n3_data = false; + bool cp_c_io_t_5g = false; + bool restrict_ec = false; + bool lpp = false; + bool ho_attach = false; + bool s1_mode = false; + bool racs = false; + bool nssaa = false; + bool lcs_5g = false; + bool v2_xcnpc5 = false; + bool v2_xcepc5 = false; + bool v2_x = false; + bool up_c_io_t_5g = false; + bool srvcc_5g = false; + bool ehc_cp_c_io_t_5g = false; + bool multiple_up = false; + bool wusa = false; + bool cag = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -360,39 +360,39 @@ public: class ue_security_capability_t { public: - 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; + bool ea0_5g_supported = false; + bool ea1_128_5g_supported = false; + bool ea2_128_5g_supported = false; + bool ea3_128_5g_supported = false; + bool ea4_5g_supported = false; + bool ea5_5g_supported = false; + bool ea6_5g_supported = false; + bool ea7_5g_supported = false; + bool ia0_5g_supported = false; + bool ia1_128_5g_supported = false; + bool ia2_128_5g_supported = false; + bool ia3_128_5g_supported = false; + bool ia4_5g_supported = false; + bool ia5_5g_supported = false; + bool ia6_5g_supported = false; + bool ia7_5g_supported = false; + bool eps_caps_present = false; + bool eea0_supported = false; + bool eea1_128_supported = false; + bool eea2_128_supported = false; + bool eea3_128_supported = false; + bool eea4_supported = false; + bool eea5_supported = false; + bool eea6_supported = false; + bool eea7_supported = false; + bool eia0_supported = false; + bool eia1_128_supported = false; + bool eia2_128_supported = false; + bool eia3_128_supported = false; + bool eia4_supported = false; + bool eia5_supported = false; + bool eia6_supported = false; + bool eia7_supported = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -463,67 +463,67 @@ public: class s1_ue_network_capability_t { public: - 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; + bool eea0_supported = false; + bool eea1_128_supported = false; + bool eea2_128_supported = false; + bool eea3_128_supported = false; + bool eea4_supported = false; + bool eea5_supported = false; + bool eea6_supported = false; + bool eea7_supported = false; + bool eia0_supported = false; + bool eia1_128_supported = false; + bool eia2_128_supported = false; + bool eia3_128_supported = false; + bool eia4_supported = false; + bool eia5_supported = false; + bool eia6_supported = false; + bool eia7_supported = false; + bool uea0_supported = false; + bool uea1_128_supported = false; + bool uea2_128_supported = false; + bool uea3_128_supported = false; + bool uea4_supported = false; + bool uea5_supported = false; + bool uea6_supported = false; + bool uea7_supported = false; + bool ucs2_support = false; + bool uia1_128_supported = false; + bool uia2_128_supported = false; + bool uia3_128_supported = false; + bool uia4_supported = false; + bool uia5_supported = false; + bool uia6_supported = false; + bool uia7_supported = false; + bool pro_se_dd_supported = false; + bool pro_se_supported = false; + bool h245_ash_supported = false; + bool acc_csfb_supported = false; + bool llp_supported = false; + bool lcs_supported = false; + bool srvcc_capability_supported = false; + bool nf_capability_supported = false; + bool e_pco_supported = false; + bool hc_cp_c_io_t_supported = false; + bool e_rw_o_pdn_supported = false; + bool s1_u_data_supported = false; + bool up_c_io_t_supported = false; + bool cp_c_io_t_supported = false; + bool pro_se_relay_supported = false; + bool pro_se_dc_supported = false; + bool max_15_eps_bearer_supported = false; + bool sgc_supported = false; + bool n1mode_supported = false; + bool dcnr_supported = false; + bool cp_backoff_supported = false; + bool restrict_ec_supported = false; + bool v2_x_pc5_supported = false; + bool multiple_drb_supported = false; + bool nr_pc5_supported = false; + bool up_mt_edt_supported = false; + bool cp_mt_edt_supported = false; + bool wus_supported = false; + bool racs_supported = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -535,22 +535,22 @@ public: class uplink_data_status_t { public: - 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; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -562,22 +562,22 @@ public: class pdu_session_status_t { public: - 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; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -589,8 +589,8 @@ public: class mico_indication_t { public: - bool sprti; - bool aai; + bool sprti = false; + bool aai = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -602,8 +602,8 @@ public: class ue_status_t { public: - bool n1_mode_reg; - bool s1_mode_reg; + bool n1_mode_reg = false; + bool s1_mode_reg = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -615,22 +615,22 @@ public: class allowed_pdu_session_status_t { public: - 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; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -767,8 +767,8 @@ public: class network_slicing_indication_t { public: - bool nssci; - bool dcni; + bool nssci = false; + bool dcni = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -871,22 +871,22 @@ public: class eps_bearer_context_status_t { public: - 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; + bool ebi_7 = false; + bool ebi_6 = false; + bool ebi_5 = false; + bool ebi_4 = false; + bool ebi_3 = false; + bool ebi_2 = false; + bool ebi_1 = false; + bool ebi_0 = false; + bool ebi_15 = false; + bool ebi_14 = false; + bool ebi_13 = false; + bool ebi_12 = false; + bool ebi_11 = false; + bool ebi_10 = false; + bool ebi_9 = false; + bool ebi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1010,7 +1010,7 @@ public: class additional_information_requested_t { public: - bool cipher_key; + bool cipher_key = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1032,7 +1032,7 @@ public: class n5gc_indication_t { public: - bool n5gcreg; + bool n5gcreg = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1181,22 +1181,22 @@ public: class pdu_session_reactivation_result_t { public: - 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; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1326,7 +1326,7 @@ public: class non_3_gpp_nw_provided_policies_t { public: - bool n3_en; + bool n3_en = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1632,7 +1632,7 @@ public: class sms_indication_t { public: - bool sms_availability_indication; + bool sms_availability_indication = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1785,8 +1785,9 @@ public: }; typedef nas_enumerated ciphering_algorithm_type; - ciphering_algorithm_type ciphering_algorithm; - integrity_protection_algorithm_type integrity_protection_algorithm; + ciphering_algorithm_type ciphering_algorithm = ciphering_algorithm_type_::options::ea0_5g; + integrity_protection_algorithm_type integrity_protection_algorithm = + integrity_protection_algorithm_type_::options::ia0_5g; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1808,7 +1809,7 @@ public: }; typedef nas_enumerated imeisv_request_type; - imeisv_request_type imeisv_request; + imeisv_request_type imeisv_request = imeisv_request_type_::options::imeisv_not_requested; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1852,8 +1853,9 @@ public: }; typedef nas_enumerated ciphering_algorithm_type; - ciphering_algorithm_type ciphering_algorithm; - integrity_protection_algorithm_type integrity_protection_algorithm; + ciphering_algorithm_type ciphering_algorithm = ciphering_algorithm_type_::options::eea0; + integrity_protection_algorithm_type integrity_protection_algorithm = + integrity_protection_algorithm_type_::options::eia0; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1865,8 +1867,8 @@ public: class additional_5g_security_information_t { public: - bool rinmr; - bool hdp; + bool rinmr = false; + bool hdp = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1878,44 +1880,44 @@ public: class s1_ue_security_capability_t { public: - 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; + bool eea0 = false; + bool eea1_128 = false; + bool eea2_128 = false; + bool eea3_128 = false; + bool eea4 = false; + bool eea5 = false; + bool eea6 = false; + bool eea7 = false; + bool eia0 = false; + bool eia1_128 = false; + bool eia2_128 = false; + bool eia3_128 = false; + bool eia4 = false; + bool eia5 = false; + bool eia6 = false; + bool eia7 = false; + bool uea0 = false; + bool uea1 = false; + bool uea2 = false; + bool uea3 = false; + bool uea4 = false; + bool uea5 = false; + bool uea6 = false; + bool uea7 = false; + bool uia1 = false; + bool uia2 = false; + bool uia3 = false; + bool uia4 = false; + bool uia5 = false; + bool uia6 = false; + bool uia7 = false; + bool gea1 = false; + bool gea2 = false; + bool gea3 = false; + bool gea4 = false; + bool gea5 = false; + bool gea6 = false; + bool gea7 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2157,7 +2159,7 @@ public: class always_on_pdu_session_requested_t { public: - bool apsi; + bool apsi = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2271,7 +2273,7 @@ public: }; typedef nas_enumerated PDU_session_type_value_type; - bool si6_lla; + bool si6_lla = false; PDU_session_type_value_type pdu_session_type_value = PDU_session_type_value_type_::options::ipv4; std::array ipv4; std::array ipv6; @@ -2437,7 +2439,7 @@ public: class always_on_pdu_session_indication_t { public: - bool apsr; + bool apsr = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2515,7 +2517,7 @@ public: class control_plane_only_indication_t { public: - bool cpoi; + bool cpoi = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2527,9 +2529,9 @@ public: class allowed_ssc_mode_t { public: - bool ssc3; - bool ssc2; - bool ssc1; + bool ssc3 = false; + bool ssc2 = false; + bool ssc1 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2564,8 +2566,8 @@ public: class re_attempt_indicator_t { public: - bool eplmnc; - bool ratc; + bool eplmnc = false; + bool ratc = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); diff --git a/lib/include/srsran/asn1/nas_5g_msg.h b/lib/include/srsran/asn1/nas_5g_msg.h index 53d6b37b1..a53f697bd 100644 --- a/lib/include/srsran/asn1/nas_5g_msg.h +++ b/lib/include/srsran/asn1/nas_5g_msg.h @@ -2471,7 +2471,7 @@ public: private: SRSASN_CODE unpack(asn1::cbit_ref& bref); SRSASN_CODE pack(asn1::bit_ref& bref); - srslog::detail::any msg_container; + srslog::detail::any msg_container = srslog::detail::any{registration_request_t()}; }; } // namespace nas_5g } // namespace srsran diff --git a/lib/include/srsran/interfaces/rrc_interface_types.h b/lib/include/srsran/interfaces/rrc_interface_types.h index 269e476ff..9a403691b 100644 --- a/lib/include/srsran/interfaces/rrc_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_interface_types.h @@ -185,6 +185,49 @@ inline std::string to_string(const scg_failure_cause_t& cause) "nulltype"}; return enum_to_text(options, (uint32_t)scg_failure_cause_t::nulltype, (uint32_t)cause); } + +enum class nr_establishment_cause_t { + emergency, + highPriorityAccess, + mt_Access, + mo_Signalling, + mo_Data, + mo_VoiceCall, + mo_VideoCall, + mo_SMS, + mps_PriorityAccess, + mcs_PriorityAccess, + spare6, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype +}; +inline std::string to_string(const nr_establishment_cause_t& cause) +{ + constexpr static const char* options[] = { + "emergency", + "highPriorityAccess", + "mt_Access", + "mo_Signalling", + "mo_Data", + "mo_VoiceCall", + "mo_VideoCall", + "mo_SMS", + "mps_PriorityAccess", + "mcs_PriorityAccess", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1", + }; + return enum_to_text(options, (uint32_t)nr_establishment_cause_t::nulltype, (uint32_t)cause); +} + /*************************** * PHY Config **************************/ diff --git a/lib/include/srsran/interfaces/ue_nas_interfaces.h b/lib/include/srsran/interfaces/ue_nas_interfaces.h index e9fe56f43..4bbe3dfba 100644 --- a/lib/include/srsran/interfaces/ue_nas_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nas_interfaces.h @@ -42,6 +42,7 @@ public: class nas_5g_interface_rrc_nr { public: + virtual int write_pdu(srsran::unique_byte_buffer_t pdu) = 0; }; class nas_5g_interface_procedures diff --git a/lib/include/srsran/interfaces/ue_rrc_interfaces.h b/lib/include/srsran/interfaces/ue_rrc_interfaces.h index ca1ded8a8..f3796fa35 100644 --- a/lib/include/srsran/interfaces/ue_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rrc_interfaces.h @@ -116,6 +116,12 @@ public: class rrc_nr_interface_nas_5g { public: + virtual ~rrc_nr_interface_nas_5g() = default; + virtual int write_sdu(srsran::unique_byte_buffer_t sdu) = 0; + virtual bool is_connected() = 0; + virtual int connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu) = 0; + virtual uint16_t get_mcc() = 0; + virtual uint16_t get_mnc() = 0; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 0695aaf17..2124f5aea 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -14,6 +14,8 @@ #define SRSUE_NAS_5G_H #include "nas_base.h" +#include "srsran/asn1/nas_5g_ies.h" +#include "srsran/asn1/nas_5g_msg.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" #include "srsran/common/nas_pcap.h" @@ -51,6 +53,8 @@ public: // Stack+RRC interface bool is_registered(); + int write_pdu(srsran::unique_byte_buffer_t pdu); + // timer callback void timer_expired(uint32_t timeout_id); @@ -68,13 +72,23 @@ private: bool running = false; + bool initial_sec_command = false; + srsran::nas_5g::mobile_identity_5gs_t::guti_5g_s guti_5g; + + srsran::nas_5g::nas_5gs_msg initial_registration_request_stored; + nas_args_t cfg = {}; - mm5g_state_t state = {}; + mm5g_state_t state; // Security bool ia5g_caps[8] = {}; bool ea5g_caps[8] = {}; + // TS 23.003 Sec. 6.2.2 IMEISV's last two octets are Software Version Number (SVN) + // which identifies the software version number of the mobile equipment + const uint8_t ue_svn_oct1 = 0x5; + const uint8_t ue_svn_oct2 = 0x3; + // timers srsran::task_sched_handle task_sched; srsran::timer_handler::unique_timer t3502; // started when registration failure and the attempt counter is equal to 5 @@ -99,7 +113,31 @@ private: srsran::proc_t registration_proc; - int send_registration_request(); + // Message sender + int send_registration_request(); + int send_authentication_response(const uint8_t res[16]); + int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t* auth_fail_param); + int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); + int send_registration_complete(); + + void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); + int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); + + // message handler + int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); + int handle_registration_reject(srsran::nas_5g::registration_reject_t& registration_reject); + int handle_authentication_request(srsran::nas_5g::authentication_request_t& authentication_request); + int handle_identity_request(srsran::nas_5g::identity_request_t& identity_request); + int handle_service_accept(srsran::nas_5g::service_accept_t& service_accept); + int handle_service_reject(srsran::nas_5g::service_reject_t& service_reject); + int handle_security_mode_command(srsran::nas_5g::security_mode_command_t& security_mode_command, + srsran::unique_byte_buffer_t pdu); + int handle_deregistration_accept_ue_terminated( + srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated); + int handle_deregistration_request_ue_terminated( + srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated); }; } // namespace srsue #endif \ No newline at end of file diff --git a/srsue/hdr/stack/upper/nas_5g_procedures.h b/srsue/hdr/stack/upper/nas_5g_procedures.h index 85ef15bcd..9d6b08e3a 100644 --- a/srsue/hdr/stack/upper/nas_5g_procedures.h +++ b/srsue/hdr/stack/upper/nas_5g_procedures.h @@ -30,6 +30,7 @@ public: explicit registration_procedure(nas_5g_interface_procedures* parent_nas_); srsran::proc_outcome_t init(); srsran::proc_outcome_t step(); + srsran::proc_outcome_t then(); static const char* name() { return "Registration Procedure"; } private: diff --git a/srsue/hdr/stack/upper/nas_5gmm_state.h b/srsue/hdr/stack/upper/nas_5gmm_state.h index b28280b61..3489c7336 100644 --- a/srsue/hdr/stack/upper/nas_5gmm_state.h +++ b/srsue/hdr/stack/upper/nas_5gmm_state.h @@ -57,6 +57,7 @@ public: update_needed, }; + mm5g_state_t(srslog::basic_logger& logger_) : logger(logger_) {} // FSM setters void set_null(); void set_deregistered(deregistered_substate_t substate); @@ -77,7 +78,7 @@ private: state_t state = state_t::null; deregistered_substate_t deregistered_substate = deregistered_substate_t::null; registered_substate_t registered_substate = registered_substate_t::null; - srslog::basic_logger& logger = srslog::fetch_basic_logger("NAS-5G"); + srslog::basic_logger& logger; }; const char* mm5g_state_text(mm5g_state_t::state_t type); diff --git a/srsue/hdr/stack/upper/nas_base.h b/srsue/hdr/stack/upper/nas_base.h index 8f9efbe11..5688482d8 100644 --- a/srsue/hdr/stack/upper/nas_base.h +++ b/srsue/hdr/stack/upper/nas_base.h @@ -49,9 +49,17 @@ protected: LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; }; - nas_sec_ctxt ctxt = {}; - uint8_t k_nas_enc[32] = {}; - uint8_t k_nas_int[32] = {}; + struct nas_5g_sec_ctxt { + uint8_t ksi; + uint8_t k_amf[32]; + uint32_t tx_count; + uint32_t rx_count; + }; + + nas_sec_ctxt ctxt = {}; + nas_5g_sec_ctxt ctxt_5g = {}; + uint8_t k_nas_enc[32] = {}; + uint8_t k_nas_int[32] = {}; int parse_security_algorithm_list(std::string algorithm_string, bool* algorithm_caps); diff --git a/srsue/hdr/stack/upper/test/nas_test_common.h b/srsue/hdr/stack/upper/test/nas_test_common.h index bc88a9e89..05be81df4 100644 --- a/srsue/hdr/stack/upper/test/nas_test_common.h +++ b/srsue/hdr/stack/upper/test/nas_test_common.h @@ -131,15 +131,23 @@ public: plmns[0].plmn_id.from_number(mcc, mnc); plmns[0].tac = 0xffff; } - void init(nas_5g* nas_5g_) { nas_5g_ptr = nas_5g_; } - void write_sdu(unique_byte_buffer_t sdu) + void init(srsue::nas_5g* nas_5g_) { nas_5g_ptr = nas_5g_; } + int write_sdu(unique_byte_buffer_t sdu) { last_sdu_len = sdu->N_bytes; // printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); + return SRSRAN_SUCCESS; } + virtual bool is_connected() { return true; } + virtual int connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu) + { + return SRSRAN_SUCCESS; + } + uint16_t get_mcc() { return 0x0000; } + uint16_t get_mnc() { return 0x0000; } private: - nas_5g* nas_5g_ptr; + srsue::nas_5g* nas_5g_ptr; uint32_t last_sdu_len; nas_interface_rrc::found_plmn_t plmns[nas_interface_rrc::MAX_FOUND_PLMNS]; }; diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index e4147f349..2d13272b6 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -48,7 +48,8 @@ nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sch t3511(task_sched_.get_unique_timer()), t3521(task_sched_.get_unique_timer()), reregistration_timer(task_sched_.get_unique_timer()), - registration_proc(this) + registration_proc(this), + state(logger_) { // Configure timers t3502.set(t3502_duration_ms, [this](uint32_t tid) { timer_expired(tid); }); @@ -150,25 +151,27 @@ int nas_5g::send_registration_request() logger.info("Generating registration request"); - nas_5gs_msg nas_msg; - nas_msg.hdr.extended_protocol_discriminator = + initial_registration_request_stored.hdr.extended_protocol_discriminator = nas_5gs_hdr::extended_protocol_discriminator_opts::extended_protocol_discriminator_5gmm; - registration_request_t& reg_req = nas_msg.set_registration_request(); + registration_request_t& reg_req = initial_registration_request_stored.set_registration_request(); reg_req.registration_type_5gs.follow_on_request_bit = - registration_type_5gs_t::follow_on_request_bit_type_::options::no_follow_on_request_pending; + registration_type_5gs_t::follow_on_request_bit_type_::options::follow_on_request_pending; reg_req.registration_type_5gs.registration_type = registration_type_5gs_t::registration_type_type_::options::initial_registration; mobile_identity_5gs_t::suci_s& suci = reg_req.mobile_identity_5gs.set_suci(); suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); - usim->get_home_mcc_bytes(suci.mnc.data(), suci.mnc.size()); + usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); suci.scheme_output.resize(5); usim->get_home_msin_bcd(suci.scheme_output.data(), 5); logger.info("Requesting IMSI attach (IMSI=%s)", usim->get_imsi_str().c_str()); - if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + reg_req.ue_security_capability_present = true; + fill_security_caps(reg_req.ue_security_capability); + + if (initial_registration_request_stored.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack registration request"); return SRSRAN_ERROR; } @@ -181,11 +184,358 @@ int nas_5g::send_registration_request() logger.debug("Starting T3410. Timeout in %d ms.", t3510.duration()); t3510.run(); + if (rrc_nr->is_connected() == true) { + rrc_nr->write_sdu(std::move(pdu)); + } else { + logger.debug("Initiating RRC NR Connection"); + if (rrc_nr->connection_request(nr_establishment_cause_t::mo_Signalling, std::move(pdu)) != SRSRAN_SUCCESS) { + logger.warning("Error starting RRC NR connection"); + return SRSRAN_ERROR; + } + } + state.set_registered_initiated(); return SRSRAN_SUCCESS; } +int nas_5g::send_authentication_response(const uint8_t res[16]) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Authentication Response"); + + nas_5gs_msg nas_msg; + authentication_response_t& auth_resp = nas_msg.set_authentication_response(); + auth_resp.authentication_response_parameter_present = true; + auth_resp.authentication_response_parameter.res.resize(16); + memcpy(auth_resp.authentication_response_parameter.res.data(), res, 16); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication response"); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + // if (apply_security_config(pdu, current_sec_hdr) != SRSASN_SUCCESS) { + // logger.error("Error applying NAS security."); + // return SRSRAN_ERROR; + // } + + logger.info("Sending Authentication Response"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_security_mode_reject(const cause_5gmm_t::cause_5gmm_type_::options cause) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + nas_5gs_msg nas_msg; + security_mode_reject_t& security_mode_reject = nas_msg.set_security_mode_reject(); + security_mode_reject.cause_5gmm.cause_5gmm = cause; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication response"); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Authentication Response"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} +void copy_msg_to_buffer(unique_byte_buffer_t& pdu, const_byte_span msg) +{ + pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + srslog::fetch_basic_logger("ALL").error("Couldn't allocate PDU in %s().", __FUNCTION__); + return; + } + memcpy(pdu->msg, msg.data(), msg.size()); + pdu->N_bytes = msg.size(); +} + +int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command) +{ + uint8_t current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT; + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Security Mode Complete"); + + nas_5gs_msg nas_msg; + security_mode_complete_t& security_mode_complete = nas_msg.set_security_mode_complete(); + + if (security_mode_command.imeisv_request_present) { + security_mode_complete.imeisv_present = true; + mobile_identity_5gs_t::imeisv_s& imeisv = security_mode_complete.imeisv.set_imeisv(); + usim->get_imei_vec(imeisv.imeisv.data(), 15); + imeisv.imeisv[14] = ue_svn_oct1; + imeisv.imeisv[15] = ue_svn_oct2; + } + + registration_request_t& modified_registration_request = initial_registration_request_stored.registration_request(); + modified_registration_request.capability_5gmm_present = true; + modified_registration_request.requested_nssai_present = true; + modified_registration_request.update_type_5gs_present = true; + + s_nssai_t s_nssai; + s_nssai.type = s_nssai_t::SST_type_::options::sst; + s_nssai.sst = 1; + modified_registration_request.requested_nssai.s_nssai_list = {s_nssai}; + + modified_registration_request.capability_5gmm.lpp = 0; + modified_registration_request.capability_5gmm.ho_attach = 0; + modified_registration_request.capability_5gmm.s1_mode = 0; + + modified_registration_request.update_type_5gs.ng_ran_rcu.value = + update_type_5gs_t::NG_RAN_RCU_type::options::ue_radio_capability_update_not_needed; + modified_registration_request.update_type_5gs.sms_requested.value = + update_type_5gs_t::SMS_requested_type::options::sms_over_nas_not_supported; + + security_mode_complete.nas_message_container_present = true; + initial_registration_request_stored.pack(security_mode_complete.nas_message_container.nas_message_container); + + nas_msg.hdr.security_header_type = + nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context; + nas_msg.hdr.sequence_number = ctxt.tx_count; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack security mode complete"); + return SRSRAN_ERROR; + } + + cipher_encrypt(pdu.get()); + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[SEQ_5G_OFFSET], + pdu->N_bytes - SEQ_5G_OFFSET, + &pdu->msg[MAC_5G_OFFSET]); + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Security Mode Complete"); + rrc_nr->write_sdu(std::move(pdu)); + ctxt.rx_count++; + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t* auth_fail_param) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + nas_5gs_msg nas_msg; + authentication_failure_t& auth_fail = nas_msg.set_authentication_failure(); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication failure."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Authentication Failure"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_registration_complete() +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Registration Complete"); + + nas_5gs_msg nas_msg; + registration_complete_t& reg_comp = nas_msg.set_registration_complete(); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack registration complete."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Registration Complete"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) +{ + logger.info(pdu->msg, pdu->N_bytes, "DL PDU (length %d)", pdu->N_bytes); + + nas_5gs_msg nas_msg; + + if (nas_msg.unpack_outer_hdr(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack outer NAS header"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.security_header_type) { + case nas_5gs_hdr::security_header_type_opts::plain_5gs_nas_message: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } else { + cipher_decrypt(pdu.get()); + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_with_new_5G_nas_context: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context: + return SRSRAN_ERROR; + default: + logger.error("Not handling NAS message with unkown security header"); + break; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + logger.info(pdu->msg, pdu->N_bytes, "Decrypted DL PDU (length %d)", pdu->N_bytes); + + // Parse the message header + if (nas_msg.unpack(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack complete NAS pdu"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.message_type) { + case msg_opts::options::registration_accept: + handle_registration_accept(nas_msg.registration_accept()); + break; + case msg_opts::options::registration_reject: + handle_registration_reject(nas_msg.registration_reject()); + break; + case msg_opts::options::authentication_request: + handle_authentication_request(nas_msg.authentication_request()); + break; + case msg_opts::options::identity_request: + handle_identity_request(nas_msg.identity_request()); + break; + case msg_opts::options::security_mode_command: + handle_security_mode_command(nas_msg.security_mode_command(), std::move(pdu)); + break; + case msg_opts::options::service_accept: + handle_service_accept(nas_msg.service_accept()); + break; + case msg_opts::options::service_reject: + handle_service_reject(nas_msg.service_reject()); + break; + case msg_opts::options::deregistration_accept_ue_terminated: + handle_deregistration_accept_ue_terminated(nas_msg.deregistration_accept_ue_terminated()); + break; + case msg_opts::options::deregistration_request_ue_terminated: + handle_deregistration_request_ue_terminated(nas_msg.deregistration_request_ue_terminated()); + break; + default: + logger.error( + "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); + break; + } + return SRSRAN_SUCCESS; +} + +void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps) +{ + if (ia5g_caps[0] == true) { + sec_caps.ia0_5g_supported = true; + } + if (ia5g_caps[1] == true) { + sec_caps.ia1_128_5g_supported = true; + } + if (ia5g_caps[2] == true) { + sec_caps.ia2_128_5g_supported = true; + } + if (ia5g_caps[3] == true) { + sec_caps.ia3_128_5g_supported = true; + } + if (ia5g_caps[4] == true) { + sec_caps.ia4_5g_supported = true; + } + if (ia5g_caps[5] == true) { + sec_caps.ia5_5g_supported = true; + } + if (ia5g_caps[6] == true) { + sec_caps.ia6_5g_supported = true; + } + if (ia5g_caps[7] == true) { + sec_caps.ia7_5g_supported = true; + } + + if (ea5g_caps[0] == true) { + sec_caps.ea0_5g_supported = true; + } + if (ea5g_caps[1] == true) { + sec_caps.ea1_128_5g_supported = true; + } + if (ea5g_caps[2] == true) { + sec_caps.ea2_128_5g_supported = true; + } + if (ea5g_caps[3] == true) { + sec_caps.ea3_128_5g_supported = true; + } + if (ea5g_caps[4] == true) { + sec_caps.ea4_5g_supported = true; + } + if (ea5g_caps[5] == true) { + sec_caps.ea5_5g_supported = true; + } + if (ea5g_caps[6] == true) { + sec_caps.ea6_5g_supported = true; + } + if (ea5g_caps[7] == true) { + sec_caps.ea7_5g_supported = true; + } +} /******************************************************************************* * UE Stack and RRC common Interface ******************************************************************************/ @@ -239,4 +589,170 @@ int nas_5g::start_service_request() return SRSRAN_SUCCESS; } +// Message handler + +int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) +{ + if (state.get_state() != mm5g_state_t::state_t::registered_initiated) { + logger.warning("Not compatibale with current state %s", state.get_full_state_text()); + return SRSRAN_ERROR; + } + + bool send_reg_complete = false; + logger.info("Handling Registration Accept"); + if (registration_accept.guti_5g_present) { + guti_5g = registration_accept.guti_5g.guti_5g(); + send_reg_complete = true; + } + + if (send_reg_complete == true) { + send_registration_complete(); + } + + // TODO: reset counters and everything what is needed by the specification + t3521.set(registration_accept.t3512_value.timer_value); + registration_proc.run(); + state.set_registered(mm5g_state_t::registered_substate_t::normal_service); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) +{ + logger.info("Handling Registration Reject"); + return SRSRAN_SUCCESS; +} +int nas_5g::handle_authentication_request(authentication_request_t& authentication_request) +{ + logger.info("Handling Registration Request"); + + // Generate authentication response using RAND, AUTN & KSI-ASME + uint16 mcc, mnc; + mcc = rrc_nr->get_mcc(); + mnc = rrc_nr->get_mnc(); + plmn_id_t plmn_id; + plmn_id.from_number(mcc, mnc); + + if (authentication_request.authentication_parameter_rand_present == false) { + logger.error("authentication_parameter_rand_present is not present"); + return SRSRAN_ERROR; + } + + if (authentication_request.authentication_parameter_autn_present == false) { + logger.error("authentication_parameter_autn_present is not present"); + return SRSRAN_ERROR; + } + + uint8_t res_star[16]; + + logger.info(authentication_request.authentication_parameter_rand.rand.data(), + authentication_request.authentication_parameter_rand.rand.size(), + "Authentication request RAND"); + + logger.info(authentication_request.authentication_parameter_autn.autn.data(), + authentication_request.authentication_parameter_rand.rand.size(), + "Authentication request AUTN"); + + logger.info("Serving network name %s", plmn_id.to_serving_network_name_string().c_str()); + auth_result_t auth_result = + usim->generate_authentication_response_5g(authentication_request.authentication_parameter_rand.rand.data(), + authentication_request.authentication_parameter_autn.autn.data(), + plmn_id.to_serving_network_name_string().c_str(), + authentication_request.abba.abba_contents.data(), + authentication_request.abba.abba_contents.size(), + res_star, + ctxt_5g.k_amf); + logger.info(ctxt_5g.k_amf, 32, "Generated k_amf:"); + if (auth_result == AUTH_OK) { + logger.info("Network authentication successful"); + send_authentication_response(res_star); + logger.info(res_star, 16, "Generated res_star (%d):", 16); + + } else if (auth_result == AUTH_SYNCH_FAILURE) { + logger.error("Network authentication synchronization failure."); + // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res); + } else { + logger.warning("Network authentication failure"); + srsran::console("Warning: Network authentication failure\n"); + // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE, nullptr); + } + + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_identity_request(identity_request_t& identity_request) +{ + logger.info("Handling Identity Request"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_service_accept(srsran::nas_5g::service_accept_t& service_accept) +{ + logger.info("Handling Service Accept"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_service_reject(srsran::nas_5g::service_reject_t& service_reject) +{ + logger.info("Handling Service Accept"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_security_mode_command(security_mode_command_t& security_mode_command, + srsran::unique_byte_buffer_t pdu) +{ + logger.info("Handling Security Mode Command"); + ctxt.cipher_algo = + (CIPHERING_ALGORITHM_ID_ENUM)security_mode_command.selected_nas_security_algorithms.ciphering_algorithm.value; + ctxt.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) + security_mode_command.selected_nas_security_algorithms.integrity_protection_algorithm.value; + + // Check capabilities + // TODO: Check replayed sec capabilities + if (!ea5g_caps[ctxt.cipher_algo] || !ia5g_caps[ctxt.integ_algo]) { + logger.warning("Sending Security Mode Reject due to security capabilities mismatch"); + send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::options::ue_security_capabilities_mismatch); + return SRSRAN_ERROR; + } + + initial_sec_command = false; // TODO + + if (initial_sec_command) { + ctxt.rx_count = 0; + ctxt.tx_count = 0; + initial_sec_command = false; + } + + // Generate NAS keys + logger.debug(ctxt_5g.k_amf, 32, "K AMF"); + logger.debug("cipher_algo %d, integ_algo %d", ctxt.cipher_algo, ctxt.integ_algo); + + usim->generate_nas_keys_5g(ctxt_5g.k_amf, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); + logger.info(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.info(k_nas_int, 32, "NAS integrity key - k_nas_int"); + + logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d", ctxt.integ_algo, ctxt.rx_count); + + if (not integrity_check(pdu.get())) { + logger.warning("Sending Security Mode Reject due to integrity check failure"); + send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::options::mac_failure); + return SRSRAN_ERROR; + } + + send_security_mode_complete(security_mode_command); + ctxt.rx_count++; + return SRSRAN_SUCCESS; +} +int nas_5g::handle_deregistration_accept_ue_terminated( + deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated) +{ + logger.info("Handling Deregistration Accept UE Terminated"); + return SRSRAN_SUCCESS; +} +int nas_5g::handle_deregistration_request_ue_terminated( + deregistration_request_ue_terminated_t& deregistration_request_ue_terminated) +{ + logger.info("Handling Deregistration Request UE Terminated"); + return SRSRAN_SUCCESS; +} + } // namespace srsue \ No newline at end of file diff --git a/srsue/src/stack/upper/nas_5g_procedures.cc b/srsue/src/stack/upper/nas_5g_procedures.cc index bf2b80e2d..577095cc4 100644 --- a/srsue/src/stack/upper/nas_5g_procedures.cc +++ b/srsue/src/stack/upper/nas_5g_procedures.cc @@ -35,4 +35,5 @@ srsran::proc_outcome_t nas_5g::registration_procedure::step() return srsran::proc_outcome_t::success; } + } // namespace srsue \ No newline at end of file