fix asn1 integer packing for integer values whose length is equal or above 32 bits

master
Francisco 4 years ago committed by Andre Puschmann
parent b4861bc59a
commit b41fc96d6d

@ -146,7 +146,7 @@ public:
bit_ref() = default; bit_ref() = default;
bit_ref(uint8_t* start_ptr_, uint32_t max_size_) : bit_ref_impl(start_ptr_, max_size_) {} bit_ref(uint8_t* start_ptr_, uint32_t max_size_) : bit_ref_impl(start_ptr_, max_size_) {}
SRSASN_CODE pack(uint32_t val, uint32_t n_bits); SRSASN_CODE pack(uint64_t val, uint32_t n_bits);
SRSASN_CODE pack_bytes(const uint8_t* buf, uint32_t n_bytes); SRSASN_CODE pack_bytes(const uint8_t* buf, uint32_t n_bytes);
SRSASN_CODE align_bytes_zero(); SRSASN_CODE align_bytes_zero();
}; };

@ -197,19 +197,19 @@ int bit_ref_impl<Ptr>::distance_bytes() const
return ((int)(ptr - start_ptr)) + ((offset) ? 1 : 0); return ((int)(ptr - start_ptr)) + ((offset) ? 1 : 0);
} }
SRSASN_CODE bit_ref::pack(uint32_t val, uint32_t n_bits) SRSASN_CODE bit_ref::pack(uint64_t val, uint32_t n_bits)
{ {
if (n_bits >= 32) { if (n_bits >= 64) {
log_error("This method only supports packing up to 32 bits\n"); log_error("This method only supports packing up to 64 bits\n");
return SRSASN_ERROR_ENCODE_FAIL; return SRSASN_ERROR_ENCODE_FAIL;
} }
uint32_t mask; uint64_t mask;
while (n_bits > 0) { while (n_bits > 0) {
if (ptr >= max_ptr) { if (ptr >= max_ptr) {
log_error("Buffer size limit was achieved\n"); log_error("Buffer size limit was achieved\n");
return SRSASN_ERROR_ENCODE_FAIL; return SRSASN_ERROR_ENCODE_FAIL;
} }
mask = ((1u << n_bits) - 1u); mask = ((1ul << n_bits) - 1ul);
val = val & mask; val = val & mask;
uint8_t keepmask = ((uint8_t)-1) - (uint8_t)((1u << (8u - offset)) - 1u); uint8_t keepmask = ((uint8_t)-1) - (uint8_t)((1u << (8u - offset)) - 1u);
if ((uint32_t)(8 - offset) > n_bits) { if ((uint32_t)(8 - offset) > n_bits) {
@ -531,14 +531,12 @@ SRSASN_CODE pack_constrained_whole_number(bit_ref& bref, IntType n, IntType lb,
HANDLE_CODE(bref.pack(toencode, n_bits)); HANDLE_CODE(bref.pack(toencode, n_bits));
ret = bref.align_bytes_zero(); ret = bref.align_bytes_zero();
} else { } else {
// TODO: Check if this is correct
uint32_t n_bits_len = (uint32_t)ceilf(log2f(ceil_frac(n_bits, 8u))); uint32_t n_bits_len = (uint32_t)ceilf(log2f(ceil_frac(n_bits, 8u)));
n_bits = (uint32_t)floorf(log2f(SRSLTE_MAX(toencode, 1)) + 1); n_bits = (uint32_t)floorf(log2f(std::max(toencode, (IntType)1)) + 1);
uint32_t n_octets = (uint32_t)((n_bits + 7) / 8); uint32_t n_octets = ceil_frac(n_bits, 8u);
HANDLE_CODE(bref.pack(n_octets - 1, n_bits_len)); HANDLE_CODE(bref.pack(n_octets - 1, n_bits_len));
HANDLE_CODE(bref.align_bytes_zero()); HANDLE_CODE(bref.align_bytes_zero());
HANDLE_CODE(bref.pack(0, (n_octets * 8) - n_bits)); ret = bref.pack(toencode, n_octets * 8u);
ret = bref.pack(toencode, n_bits);
} }
return ret; return ret;
} }
@ -601,7 +599,6 @@ SRSASN_CODE unpack_constrained_whole_number(IntType& n, cbit_ref& bref, IntType
HANDLE_CODE(bref.unpack(n, n_octets * 8)); HANDLE_CODE(bref.unpack(n, n_octets * 8));
HANDLE_CODE(bref.align_bytes()); HANDLE_CODE(bref.align_bytes());
} else { } else {
// TODO: Check if this is correct
uint32_t n_bits_len = (uint32_t)ceilf(log2f(ceil_frac(n_bits, 8u))); uint32_t n_bits_len = (uint32_t)ceilf(log2f(ceil_frac(n_bits, 8u)));
uint32_t n_octets; uint32_t n_octets;
HANDLE_CODE(bref.unpack(n_octets, n_bits_len)); HANDLE_CODE(bref.unpack(n_octets, n_bits_len));
@ -974,10 +971,7 @@ template SRSASN_CODE unpack_unconstrained_integer<int64_t>(int64_t& n, cbit_ref&
// standalone packer // standalone packer
template <class IntType> template <class IntType>
integer_packer<IntType>::integer_packer(IntType lb_, IntType ub_, bool has_ext_, bool aligned_) : integer_packer<IntType>::integer_packer(IntType lb_, IntType ub_, bool has_ext_, bool aligned_) :
lb(lb_), lb(lb_), ub(ub_), has_ext(has_ext_), aligned(aligned_)
ub(ub_),
has_ext(has_ext_),
aligned(aligned_)
{} {}
template <class IntType> template <class IntType>

@ -622,6 +622,25 @@ int test_json_writer()
return 0; return 0;
} }
int test_big_integers()
{
integer<uint64_t, 0, 4294967295, false, true> big_integer = 3172073535;
uint8_t mem_chunk[128];
bit_ref bref(&mem_chunk[0], sizeof(mem_chunk));
TESTASSERT(big_integer.pack(bref) == 0);
uint8_t bytes[] = {0xC0, 0xBD, 0x12, 0x00, 0x3F};
TESTASSERT(memcmp(bytes, mem_chunk, sizeof(bytes)) == 0);
integer<uint64_t, 0, 4294967295, false, true> big_integer2;
cbit_ref cbref(mem_chunk, sizeof(mem_chunk));
TESTASSERT(big_integer2.unpack(cbref) == 0);
TESTASSERT(big_integer == big_integer2);
return 0;
}
int main() int main()
{ {
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
@ -632,6 +651,7 @@ int main()
TESTASSERT(test_seq_of() == 0); TESTASSERT(test_seq_of() == 0);
TESTASSERT(test_copy_ptr() == 0); TESTASSERT(test_copy_ptr() == 0);
TESTASSERT(test_enum() == 0); TESTASSERT(test_enum() == 0);
TESTASSERT(test_big_integers() == 0);
// TESTASSERT(test_json_writer()==0); // TESTASSERT(test_json_writer()==0);
printf("Success\n"); printf("Success\n");
} }

Loading…
Cancel
Save