diff --git a/lib/include/srslte/asn1/asn1_utils.h b/lib/include/srslte/asn1/asn1_utils.h index 878af7d82..67c5ae166 100644 --- a/lib/include/srslte/asn1/asn1_utils.h +++ b/lib/include/srslte/asn1/asn1_utils.h @@ -146,7 +146,7 @@ public: bit_ref() = default; 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 align_bytes_zero(); }; diff --git a/lib/src/asn1/asn1_utils.cc b/lib/src/asn1/asn1_utils.cc index 1422fb372..b08ade621 100644 --- a/lib/src/asn1/asn1_utils.cc +++ b/lib/src/asn1/asn1_utils.cc @@ -197,19 +197,19 @@ int bit_ref_impl::distance_bytes() const 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) { - log_error("This method only supports packing up to 32 bits\n"); + if (n_bits >= 64) { + log_error("This method only supports packing up to 64 bits\n"); return SRSASN_ERROR_ENCODE_FAIL; } - uint32_t mask; + uint64_t mask; while (n_bits > 0) { if (ptr >= max_ptr) { log_error("Buffer size limit was achieved\n"); return SRSASN_ERROR_ENCODE_FAIL; } - mask = ((1u << n_bits) - 1u); + mask = ((1ul << n_bits) - 1ul); val = val & mask; uint8_t keepmask = ((uint8_t)-1) - (uint8_t)((1u << (8u - offset)) - 1u); 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)); ret = bref.align_bytes_zero(); } else { - // TODO: Check if this is correct 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); - uint32_t n_octets = (uint32_t)((n_bits + 7) / 8); + n_bits = (uint32_t)floorf(log2f(std::max(toencode, (IntType)1)) + 1); + uint32_t n_octets = ceil_frac(n_bits, 8u); HANDLE_CODE(bref.pack(n_octets - 1, n_bits_len)); HANDLE_CODE(bref.align_bytes_zero()); - HANDLE_CODE(bref.pack(0, (n_octets * 8) - n_bits)); - ret = bref.pack(toencode, n_bits); + ret = bref.pack(toencode, n_octets * 8u); } 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.align_bytes()); } else { - // TODO: Check if this is correct uint32_t n_bits_len = (uint32_t)ceilf(log2f(ceil_frac(n_bits, 8u))); uint32_t n_octets; HANDLE_CODE(bref.unpack(n_octets, n_bits_len)); @@ -974,10 +971,7 @@ template SRSASN_CODE unpack_unconstrained_integer(int64_t& n, cbit_ref& // standalone packer template integer_packer::integer_packer(IntType lb_, IntType ub_, bool has_ext_, bool aligned_) : - lb(lb_), - ub(ub_), - has_ext(has_ext_), - aligned(aligned_) + lb(lb_), ub(ub_), has_ext(has_ext_), aligned(aligned_) {} template diff --git a/lib/test/asn1/asn1_utils_test.cc b/lib/test/asn1/asn1_utils_test.cc index 8b319b4a4..4453e2dfc 100644 --- a/lib/test/asn1/asn1_utils_test.cc +++ b/lib/test/asn1/asn1_utils_test.cc @@ -622,6 +622,25 @@ int test_json_writer() return 0; } +int test_big_integers() +{ + integer 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 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() { srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG); @@ -632,6 +651,7 @@ int main() TESTASSERT(test_seq_of() == 0); TESTASSERT(test_copy_ptr() == 0); TESTASSERT(test_enum() == 0); + TESTASSERT(test_big_integers() == 0); // TESTASSERT(test_json_writer()==0); printf("Success\n"); }