From 25bb36cdc386d9fa4a703f70e35e2d0076162c1d Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 17 Jan 2020 12:26:53 +0100 Subject: [PATCH] converted ho preparation to new s1ap asn1 lib. Extended s1ap test --- lib/include/srslte/asn1/s1ap_asn1.h | 34 +++--- lib/src/asn1/s1ap_asn1.cc | 157 ++++++++++++++------------- lib/test/asn1/s1ap_test.cc | 43 ++++++++ srsenb/hdr/stack/upper/s1ap.h | 1 - srsenb/src/stack/upper/s1ap.cc | 162 ++++++++-------------------- 5 files changed, 191 insertions(+), 206 deletions(-) diff --git a/lib/include/srslte/asn1/s1ap_asn1.h b/lib/include/srslte/asn1/s1ap_asn1.h index 5c775d6d7..f7511fa88 100644 --- a/lib/include/srslte/asn1/s1ap_asn1.h +++ b/lib/include/srslte/asn1/s1ap_asn1.h @@ -176,7 +176,7 @@ ItemType convert_enum_idx(ItemType* array, uint32_t nof_types, uint32_t enum_val #define ASN1_S1AP_MAXNOOF_RECOMMENDED_CELLS 16 #define ASN1_S1AP_MAXNOOF_RECOMMENDED_ENBS 16 #define ASN1_S1AP_ID_MME_UE_S1AP_ID 0 -#define ASN1_S1AP_ID_HO_TYPE 1 +#define ASN1_S1AP_ID_HANDOV_TYPE 1 #define ASN1_S1AP_ID_CAUSE 2 #define ASN1_S1AP_ID_SOURCE_ID 3 #define ASN1_S1AP_ID_TARGET_ID 4 @@ -7615,6 +7615,14 @@ struct ho_cancel_ack_s { void to_json(json_writer& j) const; }; +// HandoverType ::= ENUMERATED +struct handov_type_opts { + enum options { intralte, ltetoutran, ltetogeran, utrantolte, gerantolte, /*...*/ nulltype } value; + + std::string to_string() const; +}; +typedef enumerated handov_type_e; + // HandoverCommandIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES struct ho_cmd_ies_o { // Value ::= OPEN TYPE @@ -7623,7 +7631,7 @@ struct ho_cmd_ies_o { enum options { mme_ue_s1ap_id, enb_ue_s1ap_id, - ho_type, + handov_type, nas_security_paramsfrom_e_utran, e_rab_subjectto_data_forwarding_list, e_ra_bto_release_list_ho_cmd, @@ -7650,7 +7658,7 @@ struct ho_cmd_ies_o { // getters uint64_t& mme_ue_s1ap_id(); uint32_t& enb_ue_s1ap_id(); - ho_type_e& ho_type(); + handov_type_e& handov_type(); unbounded_octstring& nas_security_paramsfrom_e_utran(); e_rab_data_forwarding_item_ies_container& e_rab_subjectto_data_forwarding_list(); e_rab_list_l& e_ra_bto_release_list_ho_cmd(); @@ -7659,7 +7667,7 @@ struct ho_cmd_ies_o { crit_diagnostics_s& crit_diagnostics(); const uint64_t& mme_ue_s1ap_id() const; const uint32_t& enb_ue_s1ap_id() const; - const ho_type_e& ho_type() const; + const handov_type_e& handov_type() const; const unbounded_octstring& nas_security_paramsfrom_e_utran() const; const e_rab_data_forwarding_item_ies_container& e_rab_subjectto_data_forwarding_list() const; const e_rab_list_l& e_ra_bto_release_list_ho_cmd() const; @@ -7698,7 +7706,7 @@ struct ho_cmd_ies_container { bool crit_diagnostics_present = false; ie_field_s > mme_ue_s1ap_id; ie_field_s > enb_ue_s1ap_id; - ie_field_s ho_type; + ie_field_s handov_type; ie_field_s > nas_security_paramsfrom_e_utran; ie_field_s e_rab_subjectto_data_forwarding_list; ie_field_s, 1, 256, true> > e_ra_bto_release_list_ho_cmd; @@ -8952,7 +8960,7 @@ struct ho_request_ies_o { struct types_opts { enum options { mme_ue_s1ap_id, - ho_type, + handov_type, cause, ueaggregate_maximum_bitrate, e_rab_to_be_setup_list_ho_req, @@ -8998,7 +9006,7 @@ struct ho_request_ies_o { void to_json(json_writer& j) const; // getters uint64_t& mme_ue_s1ap_id(); - ho_type_e& ho_type(); + handov_type_e& handov_type(); cause_c& cause(); ue_aggregate_maximum_bitrate_s& ueaggregate_maximum_bitrate(); e_rab_to_be_setup_item_ho_req_ies_container& e_rab_to_be_setup_list_ho_req(); @@ -9026,7 +9034,7 @@ struct ho_request_ies_o { ce_mode_brestricted_e& ce_mode_brestricted(); pending_data_ind_e& pending_data_ind(); const uint64_t& mme_ue_s1ap_id() const; - const ho_type_e& ho_type() const; + const handov_type_e& handov_type() const; const cause_c& cause() const; const ue_aggregate_maximum_bitrate_s& ueaggregate_maximum_bitrate() const; const e_rab_to_be_setup_item_ho_req_ies_container& e_rab_to_be_setup_list_ho_req() const; @@ -9111,7 +9119,7 @@ struct ho_request_ies_container { bool ce_mode_brestricted_present = false; bool pending_data_ind_present = false; ie_field_s > mme_ue_s1ap_id; - ie_field_s ho_type; + ie_field_s handov_type; ie_field_s cause; ie_field_s ueaggregate_maximum_bitrate; ie_field_s e_rab_to_be_setup_list_ho_req; @@ -9382,7 +9390,7 @@ struct ho_required_ies_o { enum options { mme_ue_s1ap_id, enb_ue_s1ap_id, - ho_type, + handov_type, cause, target_id, direct_forwarding_path_availability, @@ -9414,7 +9422,7 @@ struct ho_required_ies_o { // getters uint64_t& mme_ue_s1ap_id(); uint32_t& enb_ue_s1ap_id(); - ho_type_e& ho_type(); + handov_type_e& handov_type(); cause_c& cause(); target_id_c& target_id(); direct_forwarding_path_availability_e& direct_forwarding_path_availability(); @@ -9428,7 +9436,7 @@ struct ho_required_ies_o { ps_service_not_available_e& ps_service_not_available(); const uint64_t& mme_ue_s1ap_id() const; const uint32_t& enb_ue_s1ap_id() const; - const ho_type_e& ho_type() const; + const handov_type_e& handov_type() const; const cause_c& cause() const; const target_id_c& target_id() const; const direct_forwarding_path_availability_e& direct_forwarding_path_availability() const; @@ -9471,7 +9479,7 @@ struct ho_required_ies_container { bool ps_service_not_available_present = false; ie_field_s > mme_ue_s1ap_id; ie_field_s > enb_ue_s1ap_id; - ie_field_s ho_type; + ie_field_s handov_type; ie_field_s cause; ie_field_s target_id; ie_field_s direct_forwarding_path_availability; diff --git a/lib/src/asn1/s1ap_asn1.cc b/lib/src/asn1/s1ap_asn1.cc index 3be80a357..801167629 100644 --- a/lib/src/asn1/s1ap_asn1.cc +++ b/lib/src/asn1/s1ap_asn1.cc @@ -21823,6 +21823,13 @@ void ho_cancel_ack_s::to_json(json_writer& j) const j.end_obj(); } +// HandoverType ::= ENUMERATED +std::string handov_type_opts::to_string() const +{ + static constexpr const char* options[] = {"intralte", "ltetoutran", "ltetogeran", "utrantolte", "gerantolte"}; + return convert_enum_idx(options, 5, value, "handov_type_e"); +} + // HandoverCommandIEs ::= OBJECT SET OF S1AP-PROTOCOL-IES uint32_t ho_cmd_ies_o::idx_to_id(uint32_t idx) { @@ -21876,7 +21883,7 @@ ho_cmd_ies_o::value_c ho_cmd_ies_o::get_value(const uint32_t& id) ret.set(value_c::types::enb_ue_s1ap_id); break; case 1: - ret.set(value_c::types::ho_type); + ret.set(value_c::types::handov_type); break; case 135: ret.set(value_c::types::nas_security_paramsfrom_e_utran); @@ -21939,10 +21946,10 @@ uint32_t& ho_cmd_ies_o::value_c::enb_ue_s1ap_id() assert_choice_type("INTEGER (0..16777215)", type_.to_string(), "Value"); return c.get(); } -ho_type_e& ho_cmd_ies_o::value_c::ho_type() +handov_type_e& ho_cmd_ies_o::value_c::handov_type() { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } unbounded_octstring& ho_cmd_ies_o::value_c::nas_security_paramsfrom_e_utran() { @@ -21984,10 +21991,10 @@ const uint32_t& ho_cmd_ies_o::value_c::enb_ue_s1ap_id() const assert_choice_type("INTEGER (0..16777215)", type_.to_string(), "Value"); return c.get(); } -const ho_type_e& ho_cmd_ies_o::value_c::ho_type() const +const handov_type_e& ho_cmd_ies_o::value_c::handov_type() const { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } const unbounded_octstring& ho_cmd_ies_o::value_c::nas_security_paramsfrom_e_utran() const { @@ -22053,7 +22060,7 @@ void ho_cmd_ies_o::value_c::set(types::options e) break; case types::enb_ue_s1ap_id: break; - case types::ho_type: + case types::handov_type: break; case types::nas_security_paramsfrom_e_utran: c.init >(); @@ -22089,8 +22096,8 @@ ho_cmd_ies_o::value_c::value_c(const ho_cmd_ies_o::value_c& other) case types::enb_ue_s1ap_id: c.init(other.c.get()); break; - case types::ho_type: - c.init(other.c.get()); + case types::handov_type: + c.init(other.c.get()); break; case types::nas_security_paramsfrom_e_utran: c.init(other.c.get >()); @@ -22129,8 +22136,8 @@ ho_cmd_ies_o::value_c& ho_cmd_ies_o::value_c::operator=(const ho_cmd_ies_o::valu case types::enb_ue_s1ap_id: c.set(other.c.get()); break; - case types::ho_type: - c.set(other.c.get()); + case types::handov_type: + c.set(other.c.get()); break; case types::nas_security_paramsfrom_e_utran: c.set(other.c.get >()); @@ -22168,8 +22175,8 @@ void ho_cmd_ies_o::value_c::to_json(json_writer& j) const case types::enb_ue_s1ap_id: j.write_int("INTEGER (0..16777215)", c.get()); break; - case types::ho_type: - j.write_str("HoType", c.get().to_string()); + case types::handov_type: + j.write_str("HandoverType", c.get().to_string()); break; case types::nas_security_paramsfrom_e_utran: j.write_str("OCTET STRING", c.get >().to_string()); @@ -22210,8 +22217,8 @@ SRSASN_CODE ho_cmd_ies_o::value_c::pack(bit_ref& bref) const case types::enb_ue_s1ap_id: HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)16777215u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().pack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().pack(bref)); break; case types::nas_security_paramsfrom_e_utran: HANDLE_CODE(c.get >().pack(bref)); @@ -22247,8 +22254,8 @@ SRSASN_CODE ho_cmd_ies_o::value_c::unpack(bit_ref& bref) case types::enb_ue_s1ap_id: HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)16777215u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().unpack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().unpack(bref)); break; case types::nas_security_paramsfrom_e_utran: HANDLE_CODE(c.get >().unpack(bref)); @@ -22279,7 +22286,7 @@ std::string ho_cmd_ies_o::value_c::types_opts::to_string() const { static constexpr const char* options[] = {"INTEGER (0..4294967295)", "INTEGER (0..16777215)", - "HoType", + "HandoverType", "OCTET STRING", "", "E-RABList", @@ -22294,7 +22301,7 @@ template struct protocol_ie_field_s; ho_cmd_ies_container::ho_cmd_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), - ho_type(1, crit_e::reject), + handov_type(1, crit_e::reject), nas_security_paramsfrom_e_utran(135, crit_e::reject), e_rab_subjectto_data_forwarding_list(12, crit_e::ignore), e_ra_bto_release_list_ho_cmd(13, crit_e::ignore), @@ -22315,7 +22322,7 @@ SRSASN_CODE ho_cmd_ies_container::pack(bit_ref& bref) const HANDLE_CODE(mme_ue_s1ap_id.pack(bref)); HANDLE_CODE(enb_ue_s1ap_id.pack(bref)); - HANDLE_CODE(ho_type.pack(bref)); + HANDLE_CODE(handov_type.pack(bref)); if (nas_security_paramsfrom_e_utran_present) { HANDLE_CODE(nas_security_paramsfrom_e_utran.pack(bref)); } @@ -22360,9 +22367,9 @@ SRSASN_CODE ho_cmd_ies_container::unpack(bit_ref& bref) break; case 1: nof_mandatory_ies--; - ho_type.id = c.id; - ho_type.crit = c.crit; - ho_type.value = c.value.ho_type(); + handov_type.id = c.id; + handov_type.crit = c.crit; + handov_type.value = c.value.handov_type(); break; case 135: nas_security_paramsfrom_e_utran_present = true; @@ -22420,7 +22427,7 @@ void ho_cmd_ies_container::to_json(json_writer& j) const j.write_fieldname(""); enb_ue_s1ap_id.to_json(j); j.write_fieldname(""); - ho_type.to_json(j); + handov_type.to_json(j); if (nas_security_paramsfrom_e_utran_present) { j.write_fieldname(""); nas_security_paramsfrom_e_utran.to_json(j); @@ -26016,7 +26023,7 @@ ho_request_ies_o::value_c ho_request_ies_o::get_value(const uint32_t& id) ret.set(value_c::types::mme_ue_s1ap_id); break; case 1: - ret.set(value_c::types::ho_type); + ret.set(value_c::types::handov_type); break; case 2: ret.set(value_c::types::cause); @@ -26172,10 +26179,10 @@ uint64_t& ho_request_ies_o::value_c::mme_ue_s1ap_id() assert_choice_type("INTEGER (0..4294967295)", type_.to_string(), "Value"); return c.get(); } -ho_type_e& ho_request_ies_o::value_c::ho_type() +handov_type_e& ho_request_ies_o::value_c::handov_type() { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } cause_c& ho_request_ies_o::value_c::cause() { @@ -26312,10 +26319,10 @@ const uint64_t& ho_request_ies_o::value_c::mme_ue_s1ap_id() const assert_choice_type("INTEGER (0..4294967295)", type_.to_string(), "Value"); return c.get(); } -const ho_type_e& ho_request_ies_o::value_c::ho_type() const +const handov_type_e& ho_request_ies_o::value_c::handov_type() const { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } const cause_c& ho_request_ies_o::value_c::cause() const { @@ -26515,7 +26522,7 @@ void ho_request_ies_o::value_c::set(types::options e) switch (type_) { case types::mme_ue_s1ap_id: break; - case types::ho_type: + case types::handov_type: break; case types::cause: c.init(); @@ -26600,8 +26607,8 @@ ho_request_ies_o::value_c::value_c(const ho_request_ies_o::value_c& other) case types::mme_ue_s1ap_id: c.init(other.c.get()); break; - case types::ho_type: - c.init(other.c.get()); + case types::handov_type: + c.init(other.c.get()); break; case types::cause: c.init(other.c.get()); @@ -26697,8 +26704,8 @@ ho_request_ies_o::value_c& ho_request_ies_o::value_c::operator=(const ho_request case types::mme_ue_s1ap_id: c.set(other.c.get()); break; - case types::ho_type: - c.set(other.c.get()); + case types::handov_type: + c.set(other.c.get()); break; case types::cause: c.set(other.c.get()); @@ -26793,8 +26800,8 @@ void ho_request_ies_o::value_c::to_json(json_writer& j) const case types::mme_ue_s1ap_id: j.write_int("INTEGER (0..4294967295)", c.get()); break; - case types::ho_type: - j.write_str("HoType", c.get().to_string()); + case types::handov_type: + j.write_str("HandoverType", c.get().to_string()); break; case types::cause: j.write_fieldname("Cause"); @@ -26903,8 +26910,8 @@ SRSASN_CODE ho_request_ies_o::value_c::pack(bit_ref& bref) const case types::mme_ue_s1ap_id: HANDLE_CODE(pack_integer(bref, c.get(), (uint64_t)0u, (uint64_t)4294967295u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().pack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().pack(bref)); break; case types::cause: HANDLE_CODE(c.get().pack(bref)); @@ -26997,8 +27004,8 @@ SRSASN_CODE ho_request_ies_o::value_c::unpack(bit_ref& bref) case types::mme_ue_s1ap_id: HANDLE_CODE(unpack_integer(c.get(), bref, (uint64_t)0u, (uint64_t)4294967295u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().unpack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().unpack(bref)); break; case types::cause: HANDLE_CODE(c.get().unpack(bref)); @@ -27088,7 +27095,7 @@ SRSASN_CODE ho_request_ies_o::value_c::unpack(bit_ref& bref) std::string ho_request_ies_o::value_c::types_opts::to_string() const { static constexpr const char* options[] = {"INTEGER (0..4294967295)", - "HoType", + "HandoverType", "Cause", "UEAggregateMaximumBitrate", "", @@ -27122,7 +27129,7 @@ template struct protocol_ie_field_s; ho_request_ies_container::ho_request_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), - ho_type(1, crit_e::reject), + handov_type(1, crit_e::reject), cause(2, crit_e::ignore), ueaggregate_maximum_bitrate(66, crit_e::reject), e_rab_to_be_setup_list_ho_req(53, crit_e::reject), @@ -27177,7 +27184,7 @@ SRSASN_CODE ho_request_ies_container::pack(bit_ref& bref) const pack_length(bref, nof_ies, 0u, 65535u, true); HANDLE_CODE(mme_ue_s1ap_id.pack(bref)); - HANDLE_CODE(ho_type.pack(bref)); + HANDLE_CODE(handov_type.pack(bref)); HANDLE_CODE(cause.pack(bref)); HANDLE_CODE(ueaggregate_maximum_bitrate.pack(bref)); HANDLE_CODE(e_rab_to_be_setup_list_ho_req.pack(bref)); @@ -27266,9 +27273,9 @@ SRSASN_CODE ho_request_ies_container::unpack(bit_ref& bref) break; case 1: nof_mandatory_ies--; - ho_type.id = c.id; - ho_type.crit = c.crit; - ho_type.value = c.value.ho_type(); + handov_type.id = c.id; + handov_type.crit = c.crit; + handov_type.value = c.value.handov_type(); break; case 2: nof_mandatory_ies--; @@ -27443,7 +27450,7 @@ void ho_request_ies_container::to_json(json_writer& j) const j.write_fieldname(""); mme_ue_s1ap_id.to_json(j); j.write_fieldname(""); - ho_type.to_json(j); + handov_type.to_json(j); j.write_fieldname(""); cause.to_json(j); j.write_fieldname(""); @@ -28441,7 +28448,7 @@ ho_required_ies_o::value_c ho_required_ies_o::get_value(const uint32_t& id) ret.set(value_c::types::enb_ue_s1ap_id); break; case 1: - ret.set(value_c::types::ho_type); + ret.set(value_c::types::handov_type); break; case 2: ret.set(value_c::types::cause); @@ -28529,10 +28536,10 @@ uint32_t& ho_required_ies_o::value_c::enb_ue_s1ap_id() assert_choice_type("INTEGER (0..16777215)", type_.to_string(), "Value"); return c.get(); } -ho_type_e& ho_required_ies_o::value_c::ho_type() +handov_type_e& ho_required_ies_o::value_c::handov_type() { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } cause_c& ho_required_ies_o::value_c::cause() { @@ -28599,10 +28606,10 @@ const uint32_t& ho_required_ies_o::value_c::enb_ue_s1ap_id() const assert_choice_type("INTEGER (0..16777215)", type_.to_string(), "Value"); return c.get(); } -const ho_type_e& ho_required_ies_o::value_c::ho_type() const +const handov_type_e& ho_required_ies_o::value_c::handov_type() const { - assert_choice_type("HoType", type_.to_string(), "Value"); - return c.get(); + assert_choice_type("HandoverType", type_.to_string(), "Value"); + return c.get(); } const cause_c& ho_required_ies_o::value_c::cause() const { @@ -28696,7 +28703,7 @@ void ho_required_ies_o::value_c::set(types::options e) break; case types::enb_ue_s1ap_id: break; - case types::ho_type: + case types::handov_type: break; case types::cause: c.init(); @@ -28743,8 +28750,8 @@ ho_required_ies_o::value_c::value_c(const ho_required_ies_o::value_c& other) case types::enb_ue_s1ap_id: c.init(other.c.get()); break; - case types::ho_type: - c.init(other.c.get()); + case types::handov_type: + c.init(other.c.get()); break; case types::cause: c.init(other.c.get()); @@ -28798,8 +28805,8 @@ ho_required_ies_o::value_c& ho_required_ies_o::value_c::operator=(const ho_requi case types::enb_ue_s1ap_id: c.set(other.c.get()); break; - case types::ho_type: - c.set(other.c.get()); + case types::handov_type: + c.set(other.c.get()); break; case types::cause: c.set(other.c.get()); @@ -28852,8 +28859,8 @@ void ho_required_ies_o::value_c::to_json(json_writer& j) const case types::enb_ue_s1ap_id: j.write_int("INTEGER (0..16777215)", c.get()); break; - case types::ho_type: - j.write_str("HoType", c.get().to_string()); + case types::handov_type: + j.write_str("HandoverType", c.get().to_string()); break; case types::cause: j.write_fieldname("Cause"); @@ -28905,8 +28912,8 @@ SRSASN_CODE ho_required_ies_o::value_c::pack(bit_ref& bref) const case types::enb_ue_s1ap_id: HANDLE_CODE(pack_integer(bref, c.get(), (uint32_t)0u, (uint32_t)16777215u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().pack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().pack(bref)); break; case types::cause: HANDLE_CODE(c.get().pack(bref)); @@ -28957,8 +28964,8 @@ SRSASN_CODE ho_required_ies_o::value_c::unpack(bit_ref& bref) case types::enb_ue_s1ap_id: HANDLE_CODE(unpack_integer(c.get(), bref, (uint32_t)0u, (uint32_t)16777215u, false, true)); break; - case types::ho_type: - HANDLE_CODE(c.get().unpack(bref)); + case types::handov_type: + HANDLE_CODE(c.get().unpack(bref)); break; case types::cause: HANDLE_CODE(c.get().unpack(bref)); @@ -29004,7 +29011,7 @@ std::string ho_required_ies_o::value_c::types_opts::to_string() const { static constexpr const char* options[] = {"INTEGER (0..4294967295)", "INTEGER (0..16777215)", - "HoType", + "HandoverType", "Cause", "TargetID", "Direct-Forwarding-Path-Availability", @@ -29024,7 +29031,7 @@ template struct protocol_ie_field_s; ho_required_ies_container::ho_required_ies_container() : mme_ue_s1ap_id(0, crit_e::reject), enb_ue_s1ap_id(8, crit_e::reject), - ho_type(1, crit_e::reject), + handov_type(1, crit_e::reject), cause(2, crit_e::ignore), target_id(4, crit_e::reject), direct_forwarding_path_availability(79, crit_e::ignore), @@ -29053,7 +29060,7 @@ SRSASN_CODE ho_required_ies_container::pack(bit_ref& bref) const HANDLE_CODE(mme_ue_s1ap_id.pack(bref)); HANDLE_CODE(enb_ue_s1ap_id.pack(bref)); - HANDLE_CODE(ho_type.pack(bref)); + HANDLE_CODE(handov_type.pack(bref)); HANDLE_CODE(cause.pack(bref)); HANDLE_CODE(target_id.pack(bref)); if (direct_forwarding_path_availability_present) { @@ -29109,9 +29116,9 @@ SRSASN_CODE ho_required_ies_container::unpack(bit_ref& bref) break; case 1: nof_mandatory_ies--; - ho_type.id = c.id; - ho_type.crit = c.crit; - ho_type.value = c.value.ho_type(); + handov_type.id = c.id; + handov_type.crit = c.crit; + handov_type.value = c.value.handov_type(); break; case 2: nof_mandatory_ies--; @@ -29199,7 +29206,7 @@ void ho_required_ies_container::to_json(json_writer& j) const j.write_fieldname(""); enb_ue_s1ap_id.to_json(j); j.write_fieldname(""); - ho_type.to_json(j); + handov_type.to_json(j); j.write_fieldname(""); cause.to_json(j); j.write_fieldname(""); diff --git a/lib/test/asn1/s1ap_test.cc b/lib/test/asn1/s1ap_test.cc index c55d7451b..8f891c3e6 100644 --- a/lib/test/asn1/s1ap_test.cc +++ b/lib/test/asn1/s1ap_test.cc @@ -91,6 +91,48 @@ int test_initial_ctxt_setup_response() return SRSLTE_SUCCESS; } +int test_eci_pack() +{ + uint8_t buffer[128]; + + uint32_t target_cellid = 0x19C02; + fixed_bitstring<28, false, true> cell_id; + cell_id.from_number(target_cellid); + TESTASSERT(cell_id.to_number() == target_cellid); + asn1::bit_ref bref(buffer, sizeof(buffer)); + cell_id.pack(bref); + TESTASSERT(buffer[0] == 0); + TESTASSERT(buffer[1] == 0x19); + TESTASSERT(buffer[2] == 0xC0); + TESTASSERT(buffer[3] == 0x20); + + uint32_t eci = 0x19b01; + cell_id.from_number(eci); + TESTASSERT(cell_id.to_number() == eci); + TESTASSERT(cell_id.to_string() == "0000000000011001101100000001"); + + bref = asn1::bit_ref(buffer, sizeof(buffer)); + cell_id.pack(bref); + TESTASSERT(buffer[0] == 0); + TESTASSERT(buffer[1] == 0x19); + TESTASSERT(buffer[2] == 0xB0); + TESTASSERT(buffer[3] == 0x10); + + uint32_t macroenbid = 0x19C; + fixed_bitstring<20, false, true> macro_id; + macro_id.from_number(macroenbid); + TESTASSERT(macro_id.to_number() == macroenbid); + bref = asn1::bit_ref(buffer, sizeof(buffer)); + macro_id.pack(bref); + TESTASSERT(buffer[0] == 0); + TESTASSERT(buffer[1] == 0x19); + TESTASSERT(buffer[2] == 0xC0); + + test_logger.info_hex(buffer, bref.distance_bytes(), "Packed cell id:\n"); + + return SRSLTE_SUCCESS; +} + int main() { test_logger.set_level(LOG_LEVEL_DEBUG); @@ -98,5 +140,6 @@ int main() TESTASSERT(unpack_test_served_gummeis_with_multiple_plmns() == SRSLTE_SUCCESS); TESTASSERT(test_initial_ctxt_setup_response() == SRSLTE_SUCCESS); + TESTASSERT(test_eci_pack() == SRSLTE_SUCCESS); printf("Success\n"); } diff --git a/srsenb/hdr/stack/upper/s1ap.h b/srsenb/hdr/stack/upper/s1ap.h index 2e22dc304..64901a101 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -114,7 +114,6 @@ private: void build_tai_cgi(); bool connect_mme(); bool setup_s1(); - bool sctp_send_s1ap_pdu(LIBLTE_S1AP_S1AP_PDU_STRUCT* tx_pdu, uint32_t rnti, const char* procedure_name); bool sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnti, const char* procedure_name); bool handle_s1ap_rx_pdu(srslte::byte_buffer_t* pdu); diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index a0fff24f6..435722fa6 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -434,8 +434,6 @@ bool s1ap::setup_s1() plmn = htonl(plmn); tmp32 = htonl(args.enb_id); - uint8_t enb_id_bits[4 * 8]; - liblte_unpack((uint8_t*)&tmp32, 4, enb_id_bits); s1ap_pdu_c pdu; pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_S1_SETUP); @@ -444,10 +442,7 @@ bool s1ap::setup_s1() container.global_enb_id.value.plm_nid[1] = ((uint8_t*)&plmn)[2]; container.global_enb_id.value.plm_nid[2] = ((uint8_t*)&plmn)[3]; - container.global_enb_id.value.enb_id.set_macro_enb_id(); - memcpy(container.global_enb_id.value.enb_id.macro_enb_id().data(), - &enb_id_bits[32 - LIBLTE_S1AP_MACROENB_ID_BIT_STRING_LEN], - LIBLTE_S1AP_MACROENB_ID_BIT_STRING_LEN); + container.global_enb_id.value.enb_id.set_macro_enb_id().from_number(args.enb_id); container.enbname_present = true; container.enbname.value.from_string(args.enb_name); @@ -1167,44 +1162,6 @@ bool s1ap::sctp_send_s1ap_pdu(const asn1::s1ap::s1ap_pdu_c& tx_pdu, uint32_t rnt return true; } -bool s1ap::sctp_send_s1ap_pdu(LIBLTE_S1AP_S1AP_PDU_STRUCT* tx_pdu, uint32_t rnti, const char* procedure_name) -{ - srslte::unique_byte_buffer_t buf = srslte::allocate_unique_buffer(*pool, false); - if (buf == nullptr) { - s1ap_log->error("Fatal Error: Couldn't allocate buffer for %s.\n", procedure_name); - return false; - } - - liblte_s1ap_pack_s1ap_pdu(tx_pdu, (LIBLTE_BYTE_MSG_STRUCT*)buf.get()); - if (rnti > 0) { - s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s for rnti=0x%x", procedure_name, rnti); - } else { - s1ap_log->info_hex(buf->msg, buf->N_bytes, "Sending %s to MME", procedure_name); - } - uint16_t streamid = rnti == 0 ? NONUE_STREAM_ID : get_user_ctxt(rnti)->stream_id; - - ssize_t n_sent = sctp_sendmsg(s1ap_socket.fd(), - buf->msg, - buf->N_bytes, - (struct sockaddr*)&mme_addr, - sizeof(struct sockaddr_in), - htonl(PPID), - 0, - streamid, - 0, - 0); - if (n_sent == -1) { - if (rnti > 0) { - s1ap_log->error("Failed to send %s for rnti=0x%x\n", procedure_name, rnti); - } else { - s1ap_log->error("Failed to send %s\n", procedure_name); - } - return false; - } - - return true; -} - bool s1ap::find_mme_ue_id(uint32_t mme_ue_id, uint16_t* rnti, uint32_t* enb_ue_id) { for (auto& it : users) { @@ -1280,102 +1237,73 @@ bool s1ap::ue::send_ho_required(uint32_t target_eci, srslte::unique_byte_buffer_t rrc_container) { /*** Setup S1AP PDU as HandoverRequired ***/ - LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu; - bzero(&tx_pdu, sizeof(tx_pdu)); - tx_pdu.choice_type = LIBLTE_S1AP_S1AP_PDU_CHOICE_INITIATINGMESSAGE; - tx_pdu.choice.initiatingMessage.choice_type = LIBLTE_S1AP_INITIATINGMESSAGE_CHOICE_HANDOVERREQUIRED; - tx_pdu.choice.initiatingMessage.criticality = LIBLTE_S1AP_CRITICALITY_IGNORE; - tx_pdu.choice.initiatingMessage.procedureCode = LIBLTE_S1AP_PROC_ID_HANDOVERPREPARATION; - LIBLTE_S1AP_MESSAGE_HANDOVERREQUIRED_STRUCT& horeq = tx_pdu.choice.initiatingMessage.choice.HandoverRequired; + s1ap_pdu_c tx_pdu; + tx_pdu.set_init_msg().load_info_obj(ASN1_S1AP_ID_HO_PREP); + ho_required_ies_container& container = tx_pdu.init_msg().value.ho_required().protocol_ies; /*** fill HO Required message ***/ - horeq.eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ctxt.eNB_UE_S1AP_ID; - horeq.MME_UE_S1AP_ID.MME_UE_S1AP_ID = ctxt.MME_UE_S1AP_ID; - horeq.Direct_Forwarding_Path_Availability_present = false; // NOTE: X2 for fwd path not supported - horeq.HandoverType.e = LIBLTE_S1AP_HANDOVERTYPE_INTRALTE; // NOTE: only intra-LTE HO supported - horeq.Cause.choice_type = LIBLTE_S1AP_CAUSE_CHOICE_RADIONETWORK; - horeq.Cause.choice.radioNetwork.e = LIBLTE_S1AP_CAUSERADIONETWORK_UNSPECIFIED; + container.enb_ue_s1ap_id.value = ctxt.eNB_UE_S1AP_ID; + container.mme_ue_s1ap_id.value = ctxt.MME_UE_S1AP_ID; + container.direct_forwarding_path_availability_present = false; // NOTE: X2 for fwd path not supported + container.handov_type.value.value = handov_type_opts::intralte; // NOTE: only intra-LTE HO supported + container.cause.value.set_radio_network().value = cause_radio_network_opts::unspecified; // LIBLTE_S1AP_CAUSERADIONETWORK_S1_INTRA_SYSTEM_HANDOVER_TRIGGERED; /*** set the target eNB ***/ - horeq.TargetID.choice_type = LIBLTE_S1AP_TARGETID_CHOICE_TARGETENB_ID; - LIBLTE_S1AP_TARGETENB_ID_STRUCT* targetenb = &horeq.TargetID.choice.targeteNB_ID; - horeq.CSG_Id_present = false; // NOTE: CSG/hybrid target cell not supported - horeq.CellAccessMode_present = false; // only for hybrid cells + container.csg_id_present = false; // NOTE: CSG/hybrid target cell not supported + container.cell_access_mode_present = false; // only for hybrid cells // no GERAN/UTRAN/PS - horeq.SRVCCHOIndication_present = false; - horeq.MSClassmark2_present = false; - horeq.MSClassmark3_present = false; - horeq.PS_ServiceNotAvailable_present = false; - // set PLMN of target and TAI - if (horeq.TargetID.choice_type != LIBLTE_S1AP_TARGETID_CHOICE_TARGETENB_ID) { - s1ap_log->error("Non-intraLTE HO not supported.\n"); - return false; - } + auto& targetenb = container.target_id.value.set_targete_nb_id(); + // set PLMN and TAI of target // NOTE: Only HO without TAU supported. uint16_t tmp16; tmp16 = htons(s1ap_ptr->args.tac); - memcpy(targetenb->selected_TAI.tAC.buffer, &tmp16, sizeof(uint16_t)); - target_plmn.to_s1ap_plmn_bytes(targetenb->selected_TAI.pLMNidentity.buffer); + memcpy(targetenb.sel_tai.tac.data(), &tmp16, sizeof(uint16_t)); + target_plmn.to_s1ap_plmn_bytes(targetenb.sel_tai.plm_nid.data()); // NOTE: Only HO to different Macro eNB is supported. - targetenb->global_ENB_ID.eNB_ID.choice_type = LIBLTE_S1AP_ENB_ID_CHOICE_MACROENB_ID; - target_plmn.to_s1ap_plmn_bytes(targetenb->global_ENB_ID.pLMNidentity.buffer); - uint32_t tmp32 = htonl(target_eci >> 8u); - uint8_t enb_id_bits[sizeof(uint32_t) * 8]; - liblte_unpack((uint8_t*)&tmp32, sizeof(uint32_t), enb_id_bits); - memcpy(targetenb->global_ENB_ID.eNB_ID.choice.macroENB_ID.buffer, - &enb_id_bits[32 - LIBLTE_S1AP_MACROENB_ID_BIT_STRING_LEN], - LIBLTE_S1AP_MACROENB_ID_BIT_STRING_LEN); + auto& macroenb = targetenb.global_enb_id.enb_id.set_macro_enb_id(); + target_plmn.to_s1ap_plmn_bytes(targetenb.global_enb_id.plm_nid.data()); + macroenb.from_number(target_eci >> 8u); /*** fill the transparent container ***/ - horeq.Source_ToTarget_TransparentContainer_Secondary_present = false; - LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT transparent_cntr; - bzero(&transparent_cntr, sizeof(LIBLTE_S1AP_SOURCEENB_TOTARGETENB_TRANSPARENTCONTAINER_STRUCT)); - transparent_cntr.e_RABInformationList_present = false; // TODO: CHECK - transparent_cntr.subscriberProfileIDforRFP_present = false; // TODO: CHECK + container.source_to_target_transparent_container_secondary_present = false; + sourcee_nb_to_targete_nb_transparent_container_s transparent_cntr; + transparent_cntr.e_rab_info_list_present = false; // TODO: CHECK + transparent_cntr.subscriber_profile_idfor_rfp_present = false; // TODO: CHECK // - set target cell ID - target_plmn.to_s1ap_plmn_bytes(transparent_cntr.targetCell_ID.pLMNidentity.buffer); - tmp32 = htonl(target_eci); - uint8_t eci_bits[32]; - liblte_unpack((uint8_t*)&tmp32, sizeof(uint32_t), eci_bits); - memcpy(transparent_cntr.targetCell_ID.cell_ID.buffer, - &eci_bits[32 - LIBLTE_S1AP_CELLIDENTITY_BIT_STRING_LEN], - LIBLTE_S1AP_CELLIDENTITY_BIT_STRING_LEN); // [ENBID|CELLID|0] + target_plmn.to_s1ap_plmn_bytes(transparent_cntr.target_cell_id.plm_nid.data()); + transparent_cntr.target_cell_id.cell_id.from_number(target_eci); // [ENBID|CELLID|0] // info specific to source cell and history of UE // - set as last visited cell the source eNB PLMN & Cell ID - transparent_cntr.uE_HistoryInformation.len = 1; - transparent_cntr.uE_HistoryInformation.buffer[0].choice_type = LIBLTE_S1AP_LASTVISITEDCELL_ITEM_CHOICE_E_UTRAN_CELL; - LIBLTE_S1AP_LASTVISITEDEUTRANCELLINFORMATION_STRUCT* lastvisited = - &transparent_cntr.uE_HistoryInformation.buffer[0].choice.e_UTRAN_Cell; - lastvisited->cellType.cell_Size.e = LIBLTE_S1AP_CELL_SIZE_MEDIUM; - target_plmn.to_s1ap_plmn_bytes(lastvisited->global_Cell_ID.pLMNidentity.buffer); - memcpy(lastvisited->global_Cell_ID.cell_ID.buffer, - s1ap_ptr->eutran_cgi.cell_ID.buffer, - LIBLTE_S1AP_CELLIDENTITY_BIT_STRING_LEN); + transparent_cntr.ue_history_info.resize(1); + auto& eutra = transparent_cntr.ue_history_info[0].set_e_utran_cell(); + eutra.cell_type.cell_size.value = cell_size_opts::medium; + target_plmn.to_s1ap_plmn_bytes(eutra.global_cell_id.plm_nid.data()); + for (uint32_t i = 0; i < LIBLTE_S1AP_CELLIDENTITY_BIT_STRING_LEN; ++i) { + eutra.global_cell_id.cell_id.set(i, s1ap_ptr->eutran_cgi.cell_ID.buffer[i]); + } // - set time spent in current source cell struct timeval ts[3]; memcpy(&ts[1], &ctxt.init_timestamp, sizeof(struct timeval)); gettimeofday(&ts[2], nullptr); get_time_interval(ts); - lastvisited->time_UE_StayedInCell.Time_UE_StayedInCell = (uint16_t)(ts[0].tv_usec / 1.0e6 + ts[0].tv_sec); - lastvisited->time_UE_StayedInCell.Time_UE_StayedInCell = - std::min(lastvisited->time_UE_StayedInCell.Time_UE_StayedInCell, (uint16_t)4095); + eutra.time_ue_stayed_in_cell = (uint16_t)(ts[0].tv_usec / 1.0e6 + ts[0].tv_sec); + eutra.time_ue_stayed_in_cell = std::min(eutra.time_ue_stayed_in_cell, (uint16_t)4095); // - fill RRC container - memcpy(transparent_cntr.rRC_Container.buffer, rrc_container->msg, rrc_container->N_bytes); - transparent_cntr.rRC_Container.n_octets = rrc_container->N_bytes; + transparent_cntr.rrc_container.resize(rrc_container->N_bytes); + memcpy(transparent_cntr.rrc_container.data(), rrc_container->msg, rrc_container->N_bytes); /*** pack Transparent Container into HORequired message ***/ - LIBLTE_BYTE_MSG_STRUCT bytemsg; - bytemsg.N_bytes = 0; - LIBLTE_BIT_MSG_STRUCT bitmsg; - uint8_t* msg_ptr = bitmsg.msg; - liblte_s1ap_pack_sourceenb_totargetenb_transparentcontainer(&transparent_cntr, &msg_ptr); - bitmsg.N_bits = msg_ptr - bitmsg.msg; - liblte_pack(&bitmsg, &bytemsg); - memcpy(horeq.Source_ToTarget_TransparentContainer.buffer, bytemsg.msg, bytemsg.N_bytes); - horeq.Source_ToTarget_TransparentContainer.n_octets = bytemsg.N_bytes; - - return s1ap_ptr->sctp_send_s1ap_pdu(&tx_pdu, ctxt.rnti, "HORequired"); + uint8_t buffer[4096]; + asn1::bit_ref bref(buffer, sizeof(buffer)); + if (transparent_cntr.pack(bref) != asn1::SRSASN_SUCCESS) { + s1ap_log->error("Failed to pack transparent container of HO Required message\n"); + return false; + } + container.source_to_target_transparent_container.value.resize(bref.distance_bytes()); + memcpy(container.source_to_target_transparent_container.value.data(), buffer, bref.distance_bytes()); + + return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "HORequired"); } bool s1ap::ue::send_enb_status_transfer_proc(std::vector& bearer_status_list)