1#include <vanetza/asn1/support/asn_application.h>
2#include <vanetza/asn1/support/constraints.h>
3#include <vanetza/asn1/support/uper_decoder.h>
4#include <vanetza/asn1/support/uper_encoder.h>
5#include "asn1c_wrapper.hpp"
6#include <vanetza/common/byte_buffer.hpp>
7#include <boost/format.hpp>
20static int write_buffer(
const void* in, std::size_t size,
void* out_void)
22 assert(out_void !=
nullptr);
23 auto out =
static_cast<ByteBuffer*
>(out_void);
24 std::copy_n(
static_cast<const uint8_t*
>(in), size, std::back_inserter(*out));
28static int write_null(
const void*, std::size_t,
void*)
33void* allocate(std::size_t length)
35 void* ptr = calloc(1, length);
37 throw std::runtime_error(
"Bad ASN.1 memory allocation");
42void free(asn_TYPE_descriptor_t& td,
void* t)
45 ASN_STRUCT_FREE(td, t);
49void* copy(asn_TYPE_descriptor_t& td,
const void* original)
55 ec = oer_encode(&td,
const_cast<void*
>(original), write_buffer, &buffer);
56 if (ec.encoded == -1) {
57 throw std::runtime_error(
"OER encoding failed");
61 dc = oer_decode(0, &td, ©, buffer.data(), buffer.size());
62 if (dc.code != RC_OK) {
64 throw std::runtime_error(
"OER decoding failed");
70bool validate(asn_TYPE_descriptor_t& td,
const void* t)
72 return asn_check_constraints(&td, t,
nullptr,
nullptr) == 0;
75bool validate(asn_TYPE_descriptor_t& td,
const void* t, std::string& error)
78 std::size_t errlen =
sizeof(errbuf);
79 bool ok = asn_check_constraints(&td, t, errbuf, &errlen) == 0;
86int compare(asn_TYPE_descriptor_t& td,
const void* a,
const void* b)
88 return td.op->compare_struct(&td, a, b);
91int print(FILE* stream, asn_TYPE_descriptor_t& td,
const void* t)
93 return asn_fprint(stream, &td, t);
96std::size_t size_per(asn_TYPE_descriptor_t& td,
const void* t)
99 ec = uper_encode(&td,
nullptr,
const_cast<void*
>(t), write_null,
nullptr);
100 if (ec.encoded < 0) {
101 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
102 const auto error_msg = boost::format(
103 "Can't determine size for unaligned PER encoding of type %1% because of %2% sub-type")
104 % td.name % failed_type;
105 throw std::runtime_error(error_msg.str());
109 return (ec.encoded + 7) / 8;
112ByteBuffer encode_per(asn_TYPE_descriptor_t& td,
const void* t)
115 asn_enc_rval_t ec = uper_encode(&td,
nullptr,
const_cast<void*
>(t), write_buffer, &buffer);
116 if (ec.encoded == -1) {
117 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
118 const auto error_msg = boost::format(
119 "Unaligned PER encoding of type %1% failed because of %2% sub-type")
120 % td.name % failed_type;
121 throw std::runtime_error(error_msg.str());
126bool decode_per(asn_TYPE_descriptor_t& td,
void** t,
const ByteBuffer& buffer)
128 return decode_per(td, t, buffer.data(), buffer.size());
131bool decode_per(asn_TYPE_descriptor_t& td,
void** t,
const void* buffer, std::size_t size)
133 asn_codec_ctx_t ctx {};
134 asn_dec_rval_t ec = uper_decode_complete(&ctx, &td, t, buffer, size);
135 return ec.code == RC_OK;
138std::size_t size_oer(asn_TYPE_descriptor_t& td,
const void* t)
141 ec = oer_encode(&td,
const_cast<void*
>(t), write_null,
nullptr);
142 if (ec.encoded < 0) {
143 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
144 const auto error_msg = boost::format(
145 "Can't determine size for OER encoding of type %1% because of %2% sub-type")
146 % td.name % failed_type;
147 throw std::runtime_error(error_msg.str());
154ByteBuffer encode_oer(asn_TYPE_descriptor_t& td,
const void* t)
157 asn_enc_rval_t ec = oer_encode(&td,
const_cast<void*
>(t), write_buffer, &buffer);
158 if (ec.encoded == -1) {
159 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
160 const auto error_msg = boost::format(
161 "OER encoding of type %1% failed because of %2% sub-type")
162 % td.name % failed_type;
163 throw std::runtime_error(error_msg.str());
168bool decode_oer(asn_TYPE_descriptor_t& td,
void** t,
const ByteBuffer& buffer)
170 return decode_oer(td, t, buffer.data(), buffer.size());
173bool decode_oer(asn_TYPE_descriptor_t& td,
void** t,
const void* buffer, std::size_t size)
175 asn_codec_ctx_t ctx {};
176 asn_dec_rval_t ec = oer_decode(&ctx, &td, t, buffer, size);
177 return ec.code == RC_OK;
180std::size_t size_xer(asn_TYPE_descriptor_t& td,
const void* t)
183 ec = xer_encode(&td,
const_cast<void*
>(t), XER_F_BASIC, write_null,
nullptr);
184 if (ec.encoded < 0) {
185 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
186 const auto error_msg = boost::format(
187 "Can't determine size for XER encoding of type %1% because of %2% sub-type")
188 % td.name % failed_type;
189 throw std::runtime_error(error_msg.str());
196ByteBuffer encode_xer(asn_TYPE_descriptor_t& td,
const void* t)
199 asn_enc_rval_t ec = xer_encode(&td,
const_cast<void*
>(t), XER_F_BASIC, write_buffer, &buffer);
200 if (ec.encoded == -1) {
201 const char* failed_type = ec.failed_type ? ec.failed_type->name :
"unknown";
202 const auto error_msg = boost::format(
203 "XER encoding of type %1% failed because of %2% sub-type")
204 % td.name % failed_type;
205 throw std::runtime_error(error_msg.str());
210bool decode_xer(asn_TYPE_descriptor_t& td,
void** t,
const ByteBuffer& buffer)
212 return decode_xer(td, t, buffer.data(), buffer.size());
215bool decode_xer(asn_TYPE_descriptor_t& td,
void** t,
const void* buffer, std::size_t size)
217 asn_codec_ctx_t ctx {};
218 asn_dec_rval_t ec = xer_decode(&ctx, &td, t, buffer, size);
219 return ec.code == RC_OK;