mirror of https://github.com/PentHertz/srsLTE.git
asn1: fix json generation for s1ap/ngap and improve ie protocol field interface
This commit is contained in:
parent
61e225d762
commit
ec1ed9d4a5
|
@ -1377,7 +1377,7 @@ inline auto to_json(json_writer& j, const T& obj) -> decltype(obj.to_json(j))
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void to_json(json_writer& j, const asn1::enumerated<T>& obj)
|
inline auto to_json(json_writer& j, const T& obj) -> decltype(j.write_str(obj.to_string()))
|
||||||
{
|
{
|
||||||
j.write_str(obj.to_string());
|
j.write_str(obj.to_string());
|
||||||
}
|
}
|
||||||
|
@ -1549,14 +1549,40 @@ struct crit_opts {
|
||||||
};
|
};
|
||||||
typedef enumerated<crit_opts> crit_e;
|
typedef enumerated<crit_opts> crit_e;
|
||||||
|
|
||||||
template <class ObjSet, class ValueType, ValueType (*Getter)(const uint32_t&)>
|
namespace detail {
|
||||||
struct base_protocol_ie_field {
|
|
||||||
using value_type = ValueType;
|
template <typename IEsSetParam>
|
||||||
|
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 <typename ExtensionSetParam>
|
||||||
|
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 <class IEItem>
|
||||||
|
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(); }
|
value_type* operator->() { return &value(); }
|
||||||
const value_type* operator->() const { return &value(); }
|
const value_type* operator->() const { return &value(); }
|
||||||
value_type& operator*() { return value(); }
|
value_type& operator*() { return value(); }
|
||||||
|
@ -1573,9 +1599,9 @@ struct base_protocol_ie_field {
|
||||||
{
|
{
|
||||||
uint32_t id_val;
|
uint32_t id_val;
|
||||||
HANDLE_CODE(unpack_integer(id_val, bref, (uint32_t)0u, (uint32_t)65535u, false, true));
|
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(crit().unpack(bref));
|
||||||
HANDLE_CODE(value_.unpack(bref));
|
HANDLE_CODE(value().unpack(bref));
|
||||||
return SRSASN_SUCCESS;
|
return SRSASN_SUCCESS;
|
||||||
}
|
}
|
||||||
void to_json(json_writer& j) const
|
void to_json(json_writer& j) const
|
||||||
|
@ -1583,51 +1609,89 @@ struct base_protocol_ie_field {
|
||||||
j.start_obj();
|
j.start_obj();
|
||||||
j.write_int("id", id());
|
j.write_int("id", id());
|
||||||
j.write_str("criticality", crit().to_string());
|
j.write_str("criticality", crit().to_string());
|
||||||
// j.write_str("value");
|
j.write_fieldname(this->item_name());
|
||||||
// to_json(j, value());
|
asn1::to_json(j, value());
|
||||||
j.end_obj();
|
j.end_obj();
|
||||||
}
|
}
|
||||||
bool load_info_obj(const uint32_t& id_)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
value_ = ObjSet::get_value(id_);
|
this->set_item(id_);
|
||||||
return value_.type().value != ObjSet::value_c::types_opts::nulltype;
|
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}}
|
// ProtocolIE-Field{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}}
|
||||||
template <class ies_set_paramT_>
|
template <class IEsSetParam>
|
||||||
struct protocol_ie_field_s
|
struct protocol_ie_field_s : public detail::base_ie_field<detail::ie_field_value_item<IEsSetParam> > {};
|
||||||
: public base_protocol_ie_field<ies_set_paramT_, typename ies_set_paramT_::value_c, &ies_set_paramT_::get_value> {};
|
|
||||||
|
|
||||||
// ProtocolIE-SingleContainer{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}}
|
// ProtocolIE-SingleContainer{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE{{IEsSetParam}}
|
||||||
template <class ies_set_paramT_>
|
template <class ies_set_paramT_>
|
||||||
struct protocol_ie_single_container_s : public protocol_ie_field_s<ies_set_paramT_> {};
|
struct protocol_ie_single_container_s : public protocol_ie_field_s<ies_set_paramT_> {};
|
||||||
|
|
||||||
// ProtocolExtensionField{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{NGAP-PROTOCOL-EXTENSION}}
|
// ProtocolExtensionField{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE{{LAYER-PROTOCOL-EXTENSION}}
|
||||||
template <class ext_set_paramT_>
|
template <class ExtensionSetParam>
|
||||||
struct protocol_ext_field_s
|
struct protocol_ext_field_s : public detail::base_ie_field<detail::ie_field_ext_item<ExtensionSetParam> > {};
|
||||||
: public base_protocol_ie_field<ext_set_paramT_, typename ext_set_paramT_::ext_c, &ext_set_paramT_::get_ext> {};
|
|
||||||
|
|
||||||
template <class Derived>
|
namespace detail {
|
||||||
struct base_protocol_ie_container_item_s {
|
|
||||||
base_protocol_ie_container_item_s(uint32_t id_, crit_e crit_) : id(id_), crit(crit_) {}
|
template <typename T>
|
||||||
|
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 <typename T>
|
||||||
|
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 <class IEItem>
|
||||||
|
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;
|
uint32_t id = 0;
|
||||||
crit_e crit;
|
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
|
SRSASN_CODE pack(bit_ref& bref) const
|
||||||
{
|
{
|
||||||
HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true));
|
HANDLE_CODE(pack_integer(bref, id, (uint32_t)0u, (uint32_t)65535u, false, true));
|
||||||
HANDLE_CODE(crit.pack(bref));
|
HANDLE_CODE(crit.pack(bref));
|
||||||
{
|
{
|
||||||
varlength_field_pack_guard varlen_scope(bref, true);
|
varlength_field_pack_guard varlen_scope(bref, true);
|
||||||
HANDLE_CODE((*derived())->pack(bref));
|
HANDLE_CODE(this->item().pack(bref));
|
||||||
}
|
}
|
||||||
return SRSASN_SUCCESS;
|
return SRSASN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1637,7 +1701,7 @@ struct base_protocol_ie_container_item_s {
|
||||||
HANDLE_CODE(crit.unpack(bref));
|
HANDLE_CODE(crit.unpack(bref));
|
||||||
{
|
{
|
||||||
varlength_field_unpack_guard varlen_scope(bref, true);
|
varlength_field_unpack_guard varlen_scope(bref, true);
|
||||||
HANDLE_CODE((*derived())->unpack(bref));
|
HANDLE_CODE(this->item().unpack(bref));
|
||||||
}
|
}
|
||||||
return SRSASN_SUCCESS;
|
return SRSASN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1646,47 +1710,31 @@ struct base_protocol_ie_container_item_s {
|
||||||
j.start_obj();
|
j.start_obj();
|
||||||
j.write_int("id", id);
|
j.write_int("id", id);
|
||||||
j.write_str("criticality", crit.to_string());
|
j.write_str("criticality", crit.to_string());
|
||||||
|
j.write_fieldname(this->item_name());
|
||||||
|
asn1::to_json(j, this->item());
|
||||||
j.end_obj();
|
j.end_obj();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
} // namespace detail
|
||||||
Derived* derived() { return static_cast<Derived*>(this); }
|
|
||||||
const Derived* derived() const { return static_cast<const Derived*>(this); }
|
template <typename T>
|
||||||
|
struct protocol_ie_container_item_s : public detail::base_ie_container_item<detail::ie_value_item<T> > {
|
||||||
|
using base_type = detail::base_ie_container_item<detail::ie_value_item<T> >;
|
||||||
|
using base_type::base_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct protocol_ie_container_item_s : public base_protocol_ie_container_item_s<protocol_ie_container_item_s<T> > {
|
struct protocol_ext_container_item_s : public detail::base_ie_container_item<detail::ie_ext_item<T> > {
|
||||||
using base_type = base_protocol_ie_container_item_s<protocol_ie_container_item_s<T> >;
|
using base_type = detail::base_ie_container_item<detail::ie_ext_item<T> >;
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
value_type value;
|
|
||||||
|
|
||||||
using base_type::base_type;
|
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 <typename T>
|
// ProtocolIE-Container{LAYER-PROTOCOL-IES : IEsSetParam} ::= SEQUENCE (SIZE (0..65535)) OF ProtocolIE-Field
|
||||||
struct protocol_ext_container_item_s : public base_protocol_ie_container_item_s<protocol_ie_container_item_s<T> > {
|
|
||||||
using base_type = base_protocol_ie_container_item_s<protocol_ie_container_item_s<T> >;
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
value_type ext;
|
|
||||||
|
|
||||||
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
|
|
||||||
template <class IEsSetParam>
|
template <class IEsSetParam>
|
||||||
using protocol_ie_container_l = dyn_seq_of<protocol_ie_field_s<IEsSetParam>, 0, 65535, true>;
|
using protocol_ie_container_l = dyn_seq_of<protocol_ie_field_s<IEsSetParam>, 0, 65535, true>;
|
||||||
|
|
||||||
// ProtocolExtensionContainer{NGAP-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF
|
// ProtocolExtensionContainer{LAYER-PROTOCOL-EXTENSION : ExtensionSetParam} ::= SEQUENCE (SIZE (1..65535)) OF
|
||||||
// ProtocolExtensionField
|
// ProtocolExtensionField
|
||||||
template <class ExtensionSetParam>
|
template <class ExtensionSetParam>
|
||||||
using protocol_ext_container_l = dyn_seq_of<protocol_ext_field_s<ExtensionSetParam>, 1, 65535, true>;
|
using protocol_ext_container_l = dyn_seq_of<protocol_ext_field_s<ExtensionSetParam>, 1, 65535, true>;
|
||||||
|
|
|
@ -20,33 +20,35 @@ using namespace asn1::ngap;
|
||||||
|
|
||||||
int test_amf_upd()
|
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));
|
cbit_ref bref(&ngap_msg[0], sizeof(ngap_msg));
|
||||||
// 0000000A00000100010003000011
|
// 0000000A00000100010003000011
|
||||||
|
// 0000000F00000100010008028073727372616E
|
||||||
|
|
||||||
ngap_pdu_c pdu;
|
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_EQ(ngap_pdu_c::types_opts::init_msg, pdu.type().value);
|
||||||
TESTASSERT(pdu.init_msg().proc_code == 0);
|
TESTASSERT_EQ(0, pdu.init_msg().proc_code);
|
||||||
TESTASSERT(pdu.init_msg().crit.value == crit_opts::reject);
|
TESTASSERT_EQ(crit_opts::reject, pdu.init_msg().crit.value);
|
||||||
ngap_elem_procs_o::init_msg_c& init_choice = pdu.init_msg().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();
|
amf_cfg_upd_s& amf_upd = init_choice.amf_cfg_upd();
|
||||||
TESTASSERT(not amf_upd.ext);
|
TESTASSERT(not amf_upd.ext);
|
||||||
auto& amf_name = amf_upd.protocol_ies.amf_name;
|
auto& amf_name = amf_upd.protocol_ies.amf_name;
|
||||||
TESTASSERT(amf_upd.protocol_ies.amf_name_present);
|
TESTASSERT(amf_upd.protocol_ies.amf_name_present);
|
||||||
TESTASSERT(amf_name.id == 1);
|
TESTASSERT_EQ(1, amf_name.id);
|
||||||
TESTASSERT(amf_name.crit == crit_opts::reject);
|
TESTASSERT_EQ(crit_opts::reject, amf_name.crit);
|
||||||
TESTASSERT(amf_name.value.size() == 1);
|
TESTASSERT_EQ("srsran", amf_name.value.to_string());
|
||||||
TESTASSERT(amf_name.value[0] == 17);
|
|
||||||
|
|
||||||
TESTASSERT(ceil(bref.distance_bytes()) == sizeof(ngap_msg));
|
TESTASSERT_EQ(sizeof(ngap_msg), ceil(bref.distance_bytes()));
|
||||||
TESTASSERT(test_pack_unpack_consistency(pdu) == SRSASN_SUCCESS);
|
TESTASSERT_EQ(SRSASN_SUCCESS, test_pack_unpack_consistency(pdu));
|
||||||
|
|
||||||
// json_writer js;
|
json_writer js;
|
||||||
// pdu.to_json(js);
|
pdu.to_json(js);
|
||||||
// printf("PDU json: %s\n", js.to_string().c_str());
|
printf("PDU json: %s\n", js.to_string().c_str());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -344,15 +346,15 @@ int main()
|
||||||
// Start the log backend.
|
// Start the log backend.
|
||||||
srslog::init();
|
srslog::init();
|
||||||
|
|
||||||
TESTASSERT(test_amf_upd() == 0);
|
test_amf_upd();
|
||||||
TESTASSERT(test_ngsetup_request() == 0);
|
test_ngsetup_request();
|
||||||
TESTASSERT(test_ngsetup_response() == 0);
|
test_ngsetup_response();
|
||||||
TESTASSERT(test_init_ue_msg() == 0);
|
test_init_ue_msg();
|
||||||
TESTASSERT(test_dl_nas_transport() == 0);
|
test_dl_nas_transport();
|
||||||
TESTASSERT(test_ul_ran_status_transfer() == 0);
|
test_ul_ran_status_transfer();
|
||||||
TESTASSERT(test_ue_context_release() == 0);
|
test_ue_context_release();
|
||||||
TESTASSERT(test_ue_context_release_complete() == 0);
|
test_ue_context_release_complete();
|
||||||
TESTASSERT(test_session_res_setup_request() == 0);
|
test_session_res_setup_request();
|
||||||
|
|
||||||
srslog::flush();
|
srslog::flush();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue