X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=sim%2Fe2-interface.git;a=blobdiff_plain;f=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FASN1%2Fasn%2Felements.hpp;fp=e2sim%2Fe2apv1sim%2Fricsim%2Fsrc%2FASN1%2Fasn%2Felements.hpp;h=9cbcd4209d57fcce9000c58e5cf021da383d0004;hp=0000000000000000000000000000000000000000;hb=3ebf932d23dcbec9ed19f4a51f9d00a0a54f5124;hpb=6896318f2b4ff01b4a88b16019c3dc93b0b693f5 diff --git a/e2sim/e2apv1sim/ricsim/src/ASN1/asn/elements.hpp b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/elements.hpp new file mode 100755 index 0000000..9cbcd42 --- /dev/null +++ b/e2sim/e2apv1sim/ricsim/src/ASN1/asn/elements.hpp @@ -0,0 +1,565 @@ +#pragma once + +/****************************************************************************** +* +* Copyright (c) 2019 AT&T Intellectual Property. +* Copyright (c) 2018-2019 Nokia. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +******************************************************************************/ + +// Standard Includes: ANSI C/C++, MSA, and Third-Party Libraries +#include +#include + +// Local Includes: Application specific classes, functions, and libraries +#include "asn/constraints.hpp" +#include "asn/identifier.hpp" + +namespace asn { + +enum class element_type : uint8_t +{ + T_BOOLEAN + ,T_INTEGER + ,T_ENUMERATED + ,T_REAL + ,T_BITSTRING + ,T_OCTETSTRING + ,T_NULL + ,T_SEQUENCE + ,T_SEQUENCE_OF + ,T_SET + ,T_SET_OF + ,T_CHOICE + ,T_OBJECTIDENTIFIER + ,T_OBJFIELD_FTV + ,T_OBJFIELD_TF +}; + +/*************************************************************************************** +* BASE +***************************************************************************************/ + +struct base +{ + static constexpr bool optional = false; + static constexpr bool extension = false; + + static constexpr char const* name() {return "";} + + void setpresent(bool p) {is_set = p;} + void clear() {is_set = false;} + + bool is_valid() const {return is_set;} + +protected: + base() {} + void set() {is_set = true;} +protected: + bool is_set {false}; + + base& operator=(const base&) = delete; + base (const base&) = delete; +}; + +/*************************************************************************************** +* IE_NULL +***************************************************************************************/ + +struct nulltype : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::NULL_TYPE), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_NULL; + static constexpr const char* name() {return "NULL";} + + void clear() {} +}; + +/*************************************************************************************** +* T_BOOLEAN +***************************************************************************************/ + +struct boolean : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::BOOLEAN), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_BOOLEAN; + static constexpr const char* name() {return "BOOLEAN";} + + using value_type = bool; + + void set(value_type vl) { m_value = vl; base::set();} + value_type get() const { return m_value; } + void clear() { m_value = false; base::clear();} + +private: + value_type m_value {false}; +}; + +/*************************************************************************************** +* T_INTEGER +***************************************************************************************/ +template < class Constraint = constraints > +struct integer : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::INTEGER), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_INTEGER; + static constexpr const char* name() {return "INTEGER";} + + using constraint_t = Constraint; + using value_type = int64_t; + + bool equal(value_type v) const {return m_value == v;} + + void set(value_type v) { m_value = v; base::set();} + value_type get() const { return m_value; } + + void clear() { m_value = 0; base::clear();} + +private: + value_type m_value; +}; + +/*************************************************************************************** +* T_ENUMERATED +***************************************************************************************/ +template +struct enumerated : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::ENUMERATED), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_ENUMERATED; + static constexpr const char* name() {return "ENUMERATED";} + + using constraint_t = seq_range; + using value_type = typename constraint_t::value_type; + + bool equal(value_type v) const {return m_value == v;} + void set(value_type vl) { m_value = vl; base::set();} + value_type get() const { return m_value; } + void clear() { m_value = constraint_t::default_value; base::clear();} + +private: + value_type m_value; +}; + +/*************************************************************************************** +* T_OCTETSTRING +***************************************************************************************/ +template< class Constraint = constraints > +struct ostring : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::OCTET_STRING), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_OCTETSTRING; + static constexpr const char* name() {return "OCTET STING";} + using constraint_t = Constraint; + + struct value_type + { + value_type() {} + value_type(size_t size, const char* data) : m_size(size), m_data(reinterpret_cast(data)) {} + + size_t size() const { return m_size; } + const uint8_t* data() const { return m_data; } + + using const_iterator = uint8_t const*; + const_iterator begin() const { return data(); } + const_iterator end() const { return begin() + size(); } + + void assign(void const* p, size_t sz) { m_data = static_cast(p); m_size = sz; } + + private: + const uint8_t* m_data{ 0 }; + size_t m_size{ 0 }; + }; + + value_type const& get() const { return m_value; } + + //Use std::string, std::vector or IE_OSTR::value_type + template value_type const& set(T const& tval) + { + set(tval.size(), tval.data()); + base::set(); + return m_value; + } + + void set(size_t size, void const* data) + { + m_value.assign(data, size); + base::set(); + } + + template + ostring& emplace(AT& allocator, size_t size, uint8_t const * data_in) + { + if(size) + { + base::clear(); + uint8_t* data_out = allocator.alloc_bytes(size); + if (data_out) + { + memcpy(data_out, data_in, size); + set(size, data_out); + } + } + else + base::set(); + return *this; + } + + template + ostring& emplace(AT& allocator, T const& tval) + { + return emplace(allocator, tval.size(), reinterpret_cast(tval.data())); + } + + void clear() { m_value = value_type{}; base::clear();} + +private: + value_type m_value; +}; + +/*************************************************************************************** +* T_BITSTRING +***************************************************************************************/ +template > +struct bstring : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::BIT_STRING), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_BITSTRING; + static constexpr const char* name() {return "BIT STING";} + using constraint_t = Constraint; + + struct value_type + { + value_type() {} + value_type(size_t size, const char* data, size_t bitqty) : m_size(size), m_data(reinterpret_cast(data)), m_bitqty(bitqty){} + + size_t size() const { return m_size; } + const uint8_t* data() const { return m_data; } + size_t bitqty() const { return m_bitqty; } + + void assign(void const* p, size_t sz, size_t bits) { m_data = static_cast(p); m_size = sz; m_bitqty = bits; } + + private: + const uint8_t* m_data{ nullptr }; + size_t m_size{ 0 }; + size_t m_bitqty{ 0 }; + }; + + value_type const& get_buffer() const { return m_value; } + + size_t get_bitqty() const { return m_value.bitqty(); } + + //Use std::string, std::vector or IE_BSTR::value_type + template value_type const& set_buffer(T& tval, size_t bitqty) + { + m_value.assign(tval.data(), tval.size(), bitqty); + base::set(); + return m_value; + } + + void set_buffer(size_t bitqty, const uint8_t* data) + { + m_value.assign(data, (bitqty +7) >> 3, bitqty); + base::set(); + } + + template + bstring& emplace_buffer(AT& allocator, size_t bitqty, uint8_t const * data_in) + { + size_t size = (bitqty +7) >> 3; + uint8_t* data_out = allocator.alloc_bytes(size); + if (!data_out) { + throw std::bad_alloc(); + } + memcpy(data_out, data_in, size); + set_buffer(bitqty, data_out); + return *this; + } + + void clear() { m_value = value_type{}; base::clear();} + + uint64_t get_number() const + { + uint64_t retval{0}; + size_t i = 0; + for(; i < m_value.size() - 1; ++i) + { + retval <<= 8; + retval |= m_value.data()[i]; + } + + uint8_t shift = m_value.bitqty() % 8; + if (shift) + { + retval <<= shift; + } + else + { + retval <<= 8; + } + + retval |= m_value.data()[i]; + + return retval; + } + + template + void set_number(AT& allocator, size_t bitqty, uint64_t data) + { + size_t size = (bitqty +7) >> 3; + uint8_t* data_out = allocator.alloc_bytes(size); + if (!data_out) { + throw std::bad_alloc(); + } + + const uint8_t shift = bitqty % 8; + if (shift) + { + data_out[size-1] = data & (0xFF >> (8 - shift)); + data >>= shift; + } + else + { + data_out[size-1] = data & (0xFF); + data >>= 8; + } + + for (size_t i = 1; i <= size - 1; i++) + { + data_out[size-1-i] = data & (0xFF); + data >>= 8; + } + + m_value.assign(data_out, size, bitqty); + base::set(); + } + +private: + value_type m_value; +}; + +/*************************************************************************************** +* T_CHOICE +***************************************************************************************/ +template +struct choice : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::CHOICE), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_CHOICE; + static constexpr const char* name() {return "CHOICE";} + + using constraint_t = seq_range; + using index_type = size_t; + using value_type = size_t; + + static constexpr index_type fst_index = 1; + static constexpr index_type ext_index = fst_index + TotalNumEntries; + + static index_type normalize(index_type idx) {return idx - fst_index;} + static index_type denormalize(index_type idx) {return idx + fst_index;} +}; + +/*************************************************************************************** +* T_SEQUENCE +***************************************************************************************/ +template +struct sequence : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::SEQUENCE), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_SEQUENCE; + static constexpr const char* name() {return "SEQUENCE";} + + static constexpr bound_t num_total_entries = TotalNumEntries; + static constexpr bound_t num_opt_entries = NumOptEntries; + static constexpr bound_t num_ext_entries = NumExtEntries; + + using constraint_t = seq_range; + +}; + +/*************************************************************************************** +* T_SEQUENCE_OF +***************************************************************************************/ +template > +struct sequenceof : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::SEQUENCE_OF), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_SEQUENCE_OF; + static constexpr const char* name() {return "SEQUENCE OF";} + + struct value_type : T, boost::intrusive::list_base_hook< boost::intrusive::link_mode > + { + value_type(){} + private: + value_type& operator=(const value_type&) = delete; + value_type (const value_type&) = delete; + }; + + using values_t = boost::intrusive::list>; + using constraint_t = Constraint; + using element_t = T; + + void clear() { m_list.clear(); base::clear();} + size_t size() const { return m_list.size(); } + template + void sort(Predicate const& p) { m_list.sort(p); } + + template + void set(V& v) {for(auto & e : v) {m_list.push_back(e);} base::set();} + + void push_back(value_type& v) { m_list.push_back(v); base::set();} + + template //Note: Allocator must return word alligned buffer! + T& emplace_back(AT& allocator) + { + uint8_t* data = allocator.alloc_bytes(sizeof(value_type)); + if(!data) + throw std::bad_alloc(); + value_type* v = new (data) value_type; + push_back(*v); + return *v; + }; + + using iterator = typename values_t::iterator; + iterator begin() { return m_list.begin(); } + iterator end() { return m_list.end(); } + + using const_iterator = typename values_t::const_iterator; + const_iterator begin() const { return m_list.begin(); } + const_iterator end() const { return m_list.end(); } + + sequenceof(){} + +private: + values_t m_list; +}; + +/*************************************************************************************** +* T_OBJFIELD_FTV +***************************************************************************************/ +template +struct fixedtypefield : T +{ + static constexpr element_type ie_type = element_type::T_OBJFIELD_FTV; + + T& ref_nested() {return *this;} + T const & ref_nested() const {return *this;} +}; + +/*************************************************************************************** +* T_OBJFIELD_TF +***************************************************************************************/ +template +struct typefield : base +{ + static constexpr element_type ie_type = element_type::T_OBJFIELD_TF; + static constexpr const char* name() {return "type-field";} + + typefield& ref_nested() {return *this;} + typefield const& ref_nested() const {return *this;} + + bool is_unknown() const {return false;} +}; + +/*************************************************************************************** +* T_OBJECTIDENTIFIER +***************************************************************************************/ +struct oid : ostring<> +{ + using asn_identifier_t = identifier(tag_rvalue_t::OBJECT_IDENTIFIER), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_OBJECTIDENTIFIER; + static constexpr const char* name() {return "OBJECT IDENTIFIER";} +}; + +/*************************************************************************************** +* T_PRINTABLESTRING +***************************************************************************************/ +template > +struct printable_string : ostring +{ + using asn_identifier_t = identifier(tag_rvalue_t::PrintableString), tag_type_t::IMPLICIT>; + static constexpr const char* name() {return "PrintableString";} +}; + +/*************************************************************************************** +* T_IA5_STRING +***************************************************************************************/ +template > +struct ia5_string : ostring +{ + using asn_identifier_t = identifier(tag_rvalue_t::IA5String), tag_type_t::IMPLICIT>; + static constexpr const char* name() {return "IA5String";} +}; + +/*************************************************************************************** +* T_GRAPHIC_STRING +***************************************************************************************/ +template > +struct graphic_string : ostring +{ + using asn_identifier_t = identifier(tag_rvalue_t::GraphicString), tag_type_t::IMPLICIT>; + static constexpr const char* name() {return "IA5String";} +}; + +/*************************************************************************************** +* T_UTF8_STRING +***************************************************************************************/ +template > +struct utf8_string : ostring +{ + using asn_identifier_t = identifier(tag_rvalue_t::UTF8String), tag_type_t::IMPLICIT>; + static constexpr const char* name() {return "UTF8String";} +}; + +/*************************************************************************************** +* T_SET +***************************************************************************************/ +template +struct set : base +{ + using asn_identifier_t = identifier(tag_rvalue_t::SET), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_SET; + static constexpr const char* name() {return "SET";} + + static constexpr bound_t num_total_entries = TotalNumEntries; + static constexpr bound_t num_opt_entries = NumOptEntries; + static constexpr bound_t num_ext_entries = NumExtEntries; + + using constraint_t = seq_range; +}; + +/*************************************************************************************** +* T_SET_OF +***************************************************************************************/ +template > +struct setof : sequenceof +{ + using asn_identifier_t = identifier(tag_rvalue_t::SET_OF), tag_type_t::IMPLICIT>; + + static constexpr element_type ie_type = element_type::T_SET_OF; + static constexpr const char* name() {return "SET OF";} +}; +} //namespace asn