diff --git a/lib/include/srsran/asn1/asn1_utils.h b/lib/include/srsran/asn1/asn1_utils.h index f95f6a03f..d51393e9b 100644 --- a/lib/include/srsran/asn1/asn1_utils.h +++ b/lib/include/srsran/asn1/asn1_utils.h @@ -1377,7 +1377,7 @@ inline auto to_json(json_writer& j, const T& obj) -> decltype(obj.to_json(j)) } template -inline void to_json(json_writer& j, const asn1::enumerated& obj) +inline auto to_json(json_writer& j, const T& obj) -> decltype(j.write_str(obj.to_string())) { j.write_str(obj.to_string()); } @@ -1549,14 +1549,40 @@ struct crit_opts { }; typedef enumerated crit_e; -template -struct base_protocol_ie_field { - using value_type = ValueType; +namespace detail { + +template +struct ie_field_value_item { + using obj_set_type = IEsSetParam; + using value_type = typename IEsSetParam::value_c; + const char* item_name() const { return "value"; } + void set_item(uint32_t id) { item = IEsSetParam::get_value(id); } + +protected: + value_type item; +}; + +template +struct ie_field_ext_item { + using obj_set_type = ExtensionSetParam; + using value_type = typename ExtensionSetParam::ext_c; + const char* item_name() const { return "extension"; } + void set_item(uint32_t id) { item = ExtensionSetParam::get_ext(id); } + +protected: + value_type item; +}; + +template +struct base_ie_field : public IEItem { + using obj_set_type = typename IEItem::obj_set_type; + using value_type = typename IEItem::value_type; + + uint32_t id() const { return obj_set_type::idx_to_id(value().type().value); } + crit_e crit() const { return obj_set_type::get_crit(id()); } + value_type& value() { return this->item; } + const value_type& value() const { return this->item; } - uint32_t id() const { return ObjSet::idx_to_id(value().type().value); } - crit_e crit() const { return ObjSet::get_crit(id()); } - value_type& value() { return value_; } - const value_type& value() const { return value_; } value_type* operator->() { return &value(); } const value_type* operator->() const { return &value(); } value_type& operator*() { return value(); } @@ -1573,9 +1599,9 @@ struct base_protocol_ie_field { { uint32_t id_val; HANDLE_CODE(unpack_integer(id_val, bref, (uint32_t)0u, (uint32_t)65535u, false, true)); - value_ = (*Getter)(id_val); + this->set_item(id_val); HANDLE_CODE(crit().unpack(bref)); - HANDLE_CODE(value_.unpack(bref)); + HANDLE_CODE(value().unpack(bref)); return SRSASN_SUCCESS; } void to_json(json_writer& j) const @@ -1583,51 +1609,89 @@ struct base_protocol_ie_field { j.start_obj(); j.write_int("id", id()); j.write_str("criticality", crit().to_string()); - // j.write_str("value"); - // to_json(j, value()); + j.write_fieldname(this->item_name()); + asn1::to_json(j, value()); j.end_obj(); } bool load_info_obj(const uint32_t& id_) { - if (not ObjSet::is_id_valid(id_)) { + if (not obj_set_type::is_id_valid(id_)) { return false; } - value_ = ObjSet::get_value(id_); - return value_.type().value != ObjSet::value_c::types_opts::nulltype; + this->set_item(id_); + return value().type().value != obj_set_type::value_c::types_opts::nulltype; } - -private: - value_type value_; }; +} // namespace detail + // ProtocolIE-Field{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}} -template -struct protocol_ie_field_s - : public base_protocol_ie_field {}; +template +struct protocol_ie_field_s : public detail::base_ie_field > {}; // ProtocolIE-SingleContainer{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}} template struct protocol_ie_single_container_s : public protocol_ie_field_s {}; -// ProtocolExtensionField{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-EXTENSION}} -template -struct protocol_ext_field_s - : public base_protocol_ie_field {}; +// ProtocolExtensionField{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{LAYER-PROTOCOL-EXTENSION}} +template +struct protocol_ext_field_s : public detail::base_ie_field > {}; + +namespace detail { + +template +struct ie_value_item { + using value_type = T; + value_type value; + + value_type* operator->() { return &value; } + const value_type* operator->() const { return &value; } + value_type& operator*() { return value; } + const value_type& operator*() const { return value; } + const char* item_name() const { return "value"; } + +protected: + value_type& item() { return value; } + const value_type& item() const { return value; } +}; + +template +struct ie_ext_item { + using value_type = T; + value_type ext; + + value_type* operator->() { return &ext; } + const value_type* operator->() const { return &ext; } + value_type& operator*() { return ext; } + const value_type& operator*() const { return ext; } + const char* item_name() const { return "extension"; } + +protected: + value_type& item() { return ext; } + const value_type& item() const { return ext; } +}; -template -struct base_protocol_ie_container_item_s { - base_protocol_ie_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) {} +template +struct base_ie_container_item : public IEItem { + using value_type = typename IEItem::value_type; + + base_ie_container_item(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) {} uint32_t id = 0; crit_e crit; + value_type* operator->() { return &this->item(); } + const value_type* operator->() const { return &this->item(); } + value_type& operator*() { return this->item(); } + const value_type& operator*() const { return this->item(); } + SRSASN_CODE pack(bit_ref& bref) const { HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true)); HANDLE_CODE(crit.pack(bref)); { varlength_field_pack_guard varlen_scope(bref, true); - HANDLE_CODE((*derived())->pack(bref)); + HANDLE_CODE(this->item().pack(bref)); } return SRSASN_SUCCESS; } @@ -1637,7 +1701,7 @@ struct base_protocol_ie_container_item_s { HANDLE_CODE(crit.unpack(bref)); { varlength_field_unpack_guard varlen_scope(bref, true); - HANDLE_CODE((*derived())->unpack(bref)); + HANDLE_CODE(this->item().unpack(bref)); } return SRSASN_SUCCESS; } @@ -1646,47 +1710,31 @@ struct base_protocol_ie_container_item_s { j.start_obj(); j.write_int("id", id); j.write_str("criticality", crit.to_string()); + j.write_fieldname(this->item_name()); + asn1::to_json(j, this->item()); j.end_obj(); } - -private: - Derived* derived() { return static_cast(this); } - const Derived* derived() const { return static_cast(this); } }; -template -struct protocol_ie_container_item_s : public base_protocol_ie_container_item_s > { - using base_type = base_protocol_ie_container_item_s >; - using value_type = T; - - value_type value; +} // namespace detail +template +struct protocol_ie_container_item_s : public detail::base_ie_container_item > { + using base_type = detail::base_ie_container_item >; using base_type::base_type; - value_type* operator->() { return &value; } - const value_type* operator->() const { return &value; } - value_type& operator*() { return value; } - const value_type& operator*() const { return value; } }; template -struct protocol_ext_container_item_s : public base_protocol_ie_container_item_s > { - using base_type = base_protocol_ie_container_item_s >; - using value_type = T; - - value_type ext; - +struct protocol_ext_container_item_s : public detail::base_ie_container_item > { + using base_type = detail::base_ie_container_item >; using base_type::base_type; - value_type* operator->() { return &ext; } - const value_type* operator->() const { return &ext; } - value_type& operator*() { return ext; } - const value_type& operator*() const { return ext; } }; -// ProtocolIE-Container{NGAP-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field +// ProtocolIE-Container{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field template using protocol_ie_container_l = dyn_seq_of, 0, 65535, true>; -// ProtocolExtensionContainer{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF +// ProtocolExtensionContainer{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF // ProtocolExtensionField template using protocol_ext_container_l = dyn_seq_of, 1, 65535, true>; diff --git a/lib/test/asn1/ngap_test.cc b/lib/test/asn1/ngap_test.cc index 8114d8012..242bb32fa 100644 --- a/lib/test/asn1/ngap_test.cc +++ b/lib/test/asn1/ngap_test.cc @@ -20,33 +20,35 @@ using namespace asn1::ngap; int test_amf_upd() { - uint8_t ngap_msg[] = {0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x11}; + // uint8_t ngap_msg[] = {0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x11}; + uint8_t ngap_msg[] = { + 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x02, 0x80, 0x73, 0x72, 0x73, 0x72, 0x61, 0x6e}; cbit_ref bref(&ngap_msg[0], sizeof(ngap_msg)); // 0000000A00000100010003000011 + // 0000000F00000100010008028073727372616E ngap_pdu_c pdu; - TESTASSERT(pdu.unpack(bref) == SRSASN_SUCCESS); + TESTASSERT_EQ(SRSASN_SUCCESS, pdu.unpack(bref)); - TESTASSERT(pdu.type().value == ngap_pdu_c::types_opts::init_msg); - TESTASSERT(pdu.init_msg().proc_code == 0); - TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject); + TESTASSERT_EQ(ngap_pdu_c::types_opts::init_msg, pdu.type().value); + TESTASSERT_EQ(0, pdu.init_msg().proc_code); + TESTASSERT_EQ(crit_opts::reject, pdu.init_msg().crit.value); ngap_elem_procs_o::init_msg_c& init_choice = pdu.init_msg().value; - TESTASSERT(init_choice.type().value == ngap_elem_procs_o::init_msg_c::types_opts::amf_cfg_upd); + TESTASSERT_EQ(ngap_elem_procs_o::init_msg_c::types_opts::amf_cfg_upd, init_choice.type().value); amf_cfg_upd_s& amf_upd = init_choice.amf_cfg_upd(); TESTASSERT(not amf_upd.ext); auto& amf_name = amf_upd.protocol_ies.amf_name; TESTASSERT(amf_upd.protocol_ies.amf_name_present); - TESTASSERT(amf_name.id == 1); - TESTASSERT(amf_name.crit == crit_opts::reject); - TESTASSERT(amf_name.value.size() == 1); - TESTASSERT(amf_name.value[0] == 17); + TESTASSERT_EQ(1, amf_name.id); + TESTASSERT_EQ(crit_opts::reject, amf_name.crit); + TESTASSERT_EQ("srsran", amf_name.value.to_string()); - TESTASSERT(ceil(bref.distance_bytes()) == sizeof(ngap_msg)); - TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS); + TESTASSERT_EQ(sizeof(ngap_msg), ceil(bref.distance_bytes())); + TESTASSERT_EQ(SRSASN_SUCCESS, test_pack_unpack_consistency(pdu)); - // json_writer js; - // pdu.to_json(js); - // printf("PDU json: %s\n", js.to_string().c_str()); + json_writer js; + pdu.to_json(js); + printf("PDU json: %s\n", js.to_string().c_str()); return 0; } @@ -344,15 +346,15 @@ int main() // Start the log backend. srslog::init(); - TESTASSERT(test_amf_upd() == 0); - TESTASSERT(test_ngsetup_request() == 0); - TESTASSERT(test_ngsetup_response() == 0); - TESTASSERT(test_init_ue_msg() == 0); - TESTASSERT(test_dl_nas_transport() == 0); - TESTASSERT(test_ul_ran_status_transfer() == 0); - TESTASSERT(test_ue_context_release() == 0); - TESTASSERT(test_ue_context_release_complete() == 0); - TESTASSERT(test_session_res_setup_request() == 0); + test_amf_upd(); + test_ngsetup_request(); + test_ngsetup_response(); + test_init_ue_msg(); + test_dl_nas_transport(); + test_ul_ran_status_transfer(); + test_ue_context_release(); + test_ue_context_release_complete(); + test_session_res_setup_request(); srslog::flush();