Por asn1 code in lib directory to srslog (#2253)

* Match hex dump indentation with srslog.

* Port asn1 utils to use srslog. Converted logging functions from taking varargs to variadic template functions.

* Remove trailing new lines in log lines from asn1 utils.

* First round of upgrades to srslog to asn1 tests.

* Second round of porting asn1 tests to srslog.
This commit is contained in:
faluco 2021-02-01 11:58:28 +01:00 committed by GitHub
parent fa1f9594cb
commit 806268f6cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 233 additions and 180 deletions

View File

@ -13,14 +13,14 @@
#ifndef SRSASN_COMMON_UTILS_H
#define SRSASN_COMMON_UTILS_H
#include "srslte/srslog/bundled/fmt/format.h"
#include "srslte/srslog/srslog.h"
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <limits>
#include <map>
#include <stdint.h>
#include <string>
#include <vector>
@ -53,10 +53,29 @@ struct static_max<arg1, arg2, others...> {
logging
************************/
void log_error(const char* format, ...);
void log_warning(const char* format, ...);
void log_info(const char* format, ...);
void log_debug(const char* format, ...);
template <typename... Args>
void log_error(const char* format, Args&&... args)
{
srslog::fetch_basic_logger("ASN1").error(format, std::forward<Args>(args)...);
}
template <typename... Args>
void log_warning(const char* format, Args&&... args)
{
srslog::fetch_basic_logger("ASN1").warning(format, std::forward<Args>(args)...);
}
template <typename... Args>
void log_info(const char* format, Args&&... args)
{
srslog::fetch_basic_logger("ASN1").info(format, std::forward<Args>(args)...);
}
template <typename... Args>
void log_debug(const char* format, Args&&... args)
{
srslog::fetch_basic_logger("ASN1").debug(format, std::forward<Args>(args)...);
}
void warn_assert(bool cond, const char* filename, int lineno);
void log_invalid_access_choice_id(uint32_t val, uint32_t choice_id);
@ -217,7 +236,7 @@ public:
iterator erase(iterator it)
{
if (it < begin() or it >= end()) {
log_warning("Trying to access out-of-bounds iterator.\n");
log_warning("Trying to access out-of-bounds iterator.");
return end();
}
@ -272,7 +291,7 @@ public:
void push_back(const T& elem)
{
if (current_size >= MAX_N) {
log_error("Maximum size %d achieved for bounded_array.\n", MAX_N);
log_error("Maximum size %d achieved for bounded_array.", MAX_N);
return;
}
data_[current_size++] = elem;
@ -636,7 +655,7 @@ public:
fixed_octstring<N, aligned>& from_string(const std::string& hexstr)
{
if (hexstr.size() != 2 * N) {
log_error("The provided hex string size is not valid (%zd!=2*%zd).\n", hexstr.size(), (size_t)N);
log_error("The provided hex string size is not valid (%zd!=2*%zd).", hexstr.size(), (size_t)N);
} else {
string_to_octstring(&octets_[0], hexstr);
}
@ -707,7 +726,7 @@ public:
bounded_octstring<LB, UB, aligned>& from_string(const std::string& hexstr)
{
if (hexstr.size() > 2 * UB) {
log_error("The provided hex string size is not valid (%zd>2*%zd).\n", hexstr.size(), (size_t)UB);
log_error("The provided hex string size is not valid (%zd>2*%zd).", hexstr.size(), (size_t)UB);
} else {
resize(hexstr.size() / 2);
string_to_octstring(&octets_[0], hexstr);
@ -868,7 +887,8 @@ public:
this_type& from_string(const std::string& s)
{
if (s.size() < lb or s.size() > ub) {
log_error("The provided string size=%zd is not withing the bounds [%d, %d]\n", s.size(), lb, ub);
log_error(
"The provided string size=%zd is not withing the bounds [%d, %d]", s.size(), uint32_t(lb), uint32_t(ub));
} else {
resize(s.size());
for (uint32_t i = 0; i < s.size(); ++i) {
@ -884,7 +904,7 @@ public:
{
auto nof_bits_ = std::max((uint32_t)ceilf(log2(std::max(val, (uint64_t)1u))), LB);
if (nof_bits_ > UB) {
log_error("The provided bitstring value %ld does not fit the bounds [%d, %d]\n", val, lb, ub);
log_error("The provided bitstring value %ld does not fit the bounds [%d, %d]", val, uint32_t(lb), uint32_t(ub));
return *this;
}
resize(nof_bits_);
@ -1357,17 +1377,17 @@ int test_pack_unpack_consistency(const Msg& msg)
// unpack and last pack done for the same number of bits
if (bref3.distance() != bref2.distance()) {
log_error("[%s][%d] .\n", __FILE__, __LINE__);
log_error("[%s][%d] .", __FILE__, __LINE__);
return -1;
}
// ensure packed messages are the same
if (bref3.distance() != bref.distance()) {
log_error("[%s][%d] .\n", __FILE__, __LINE__);
log_error("[%s][%d] .", __FILE__, __LINE__);
return -1;
}
if (memcmp(buf, buf2, bref.distance_bytes()) != 0) {
log_error("[%s][%d] .\n", __FILE__, __LINE__);
log_error("[%s][%d] .", __FILE__, __LINE__);
return -1;
}
return SRSASN_SUCCESS;

View File

@ -11,11 +11,6 @@
*/
#include "srslte/asn1/asn1_utils.h"
#include "srslte/common/logmap.h"
#include "srslte/srslog/bundled/fmt/core.h"
#include <cmath>
#include <stdarg.h> /* va_list, va_start, va_arg, va_end */
#include <stdio.h>
namespace asn1 {
@ -23,70 +18,16 @@ namespace asn1 {
logging
************************/
void vlog_print(srslte::LOG_LEVEL_ENUM log_level, const char* format, va_list args)
{
char* args_msg = nullptr;
if (vasprintf(&args_msg, format, args) > 0) {
switch (log_level) {
case srslte::LOG_LEVEL_ERROR:
srslte::logmap::get("ASN1")->error("%s", args_msg);
break;
case srslte::LOG_LEVEL_WARNING:
srslte::logmap::get("ASN1")->warning("%s", args_msg);
break;
case srslte::LOG_LEVEL_INFO:
srslte::logmap::get("ASN1")->info("%s", args_msg);
break;
case srslte::LOG_LEVEL_DEBUG:
srslte::logmap::get("ASN1")->debug("%s", args_msg);
default:
break;
}
}
if (args_msg) {
free(args_msg);
}
}
void log_error(const char* format, ...)
{
va_list args;
va_start(args, format);
vlog_print(srslte::LOG_LEVEL_ERROR, format, args);
va_end(args);
}
void log_warning(const char* format, ...)
{
va_list args;
va_start(args, format);
vlog_print(srslte::LOG_LEVEL_WARNING, format, args);
va_end(args);
}
void log_info(const char* format, ...)
{
va_list args;
va_start(args, format);
vlog_print(srslte::LOG_LEVEL_INFO, format, args);
va_end(args);
}
void log_debug(const char* format, ...)
{
va_list args;
va_start(args, format);
vlog_print(srslte::LOG_LEVEL_DEBUG, format, args);
va_end(args);
}
void warn_assert(bool cond, const char* filename, int lineno)
{
if (cond) {
log_warning("Assertion in [%s][%d] failed.\n", filename, lineno);
log_warning("Assertion in [%s][%d] failed.", filename, lineno);
}
}
void invalid_enum_number(int value, const char* name)
{
log_error("The provided enum value=%d of type %s cannot be translated into a number\n", value, name);
log_error("The provided enum value=%d of type %s cannot be translated into a number", value, name);
}
void assert_choice_type(uint32_t val, uint32_t choice_id)
@ -99,7 +40,7 @@ void assert_choice_type(uint32_t val, uint32_t choice_id)
void assert_choice_type(const std::string& access_type, const std::string& current_type, const std::string& choice_type)
{
if (access_type != current_type) {
log_error("Invalid field access for choice type \"%s\" (\"%s\"!=\"%s\")\n",
log_error("Invalid field access for choice type \"%s\" (\"%s\"!=\"%s\")",
choice_type.c_str(),
access_type.c_str(),
current_type.c_str());
@ -114,13 +55,13 @@ void log_error_code(SRSASN_CODE code, const char* filename, int line)
{
switch (code) {
case SRSASN_ERROR_ENCODE_FAIL:
log_error("[%s][%d] Encoding failure.\n", filename, line);
log_error("[%s][%d] Encoding failure.", filename, line);
break;
case SRSASN_ERROR_DECODE_FAIL:
log_error("[%s][%d] Decoding failure.\n", filename, line);
log_error("[%s][%d] Decoding failure.", filename, line);
break;
default:
log_warning("[%s][%d] SRSASN_CODE=%d not recognized.\n", filename, line, (int)code);
log_warning("[%s][%d] SRSASN_CODE=%d not recognized.", filename, line, (int)code);
}
}
@ -128,9 +69,9 @@ const char* convert_enum_idx(const char* array[], uint32_t nof_types, uint32_t e
{
if (enum_val >= nof_types) {
if (enum_val == nof_types) {
log_error("The enum of type %s was not initialized.\n", enum_type);
log_error("The enum of type %s was not initialized.", enum_type);
} else {
log_error("The enum value=%d of type %s is not valid.\n", enum_val, enum_type);
log_error("The enum value=%d of type %s is not valid.", enum_val, enum_type);
}
return "";
}
@ -142,9 +83,9 @@ ItemType map_enum_number(ItemType* array, uint32_t nof_types, uint32_t enum_val,
{
if (enum_val >= nof_types) {
if (enum_val == nof_types) {
log_error("The enum of type %s is not initialized.\n", enum_type);
log_error("The enum of type %s is not initialized.", enum_type);
} else {
log_error("The enum value=%d of type %s cannot be converted to a number.\n", enum_val, enum_type);
log_error("The enum value=%d of type %s cannot be converted to a number.", enum_val, enum_type);
}
return 0;
}
@ -202,13 +143,13 @@ int bit_ref_impl<Ptr>::distance_bytes() const
SRSASN_CODE bit_ref::pack(uint64_t val, uint32_t n_bits)
{
if (n_bits >= 64) {
log_error("This method only supports packing up to 64 bits\n");
log_error("This method only supports packing up to 64 bits");
return SRSASN_ERROR_ENCODE_FAIL;
}
uint64_t mask;
while (n_bits > 0) {
if (ptr >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_ENCODE_FAIL;
}
mask = ((1ul << n_bits) - 1ul);
@ -234,13 +175,13 @@ template <typename T, typename Ptr>
SRSASN_CODE unpack_bits(T& val, Ptr& ptr, uint8_t& offset, const uint8_t* max_ptr, uint32_t n_bits)
{
if (n_bits > sizeof(T) * 8) {
log_error("This method only supports unpacking up to %d bits\n", (int)sizeof(T) * 8);
log_error("This method only supports unpacking up to %d bits", (int)sizeof(T) * 8);
return SRSASN_ERROR_DECODE_FAIL;
}
val = 0;
while (n_bits > 0) {
if (ptr >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_DECODE_FAIL;
}
if ((uint32_t)(8 - offset) > n_bits) {
@ -302,7 +243,7 @@ SRSASN_CODE bit_ref_impl<Ptr>::unpack_bytes(uint8_t* buf, uint32_t n_bytes)
return SRSASN_SUCCESS;
}
if (ptr + n_bytes >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_DECODE_FAIL;
}
if (offset == 0) {
@ -323,7 +264,7 @@ SRSASN_CODE bit_ref_impl<Ptr>::align_bytes()
if (offset == 0)
return SRSASN_SUCCESS;
if (ptr >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_DECODE_FAIL;
}
offset = 0;
@ -339,7 +280,7 @@ SRSASN_CODE bit_ref_impl<Ptr>::advance_bits(uint32_t n_bits)
uint32_t bytes_offset = floorf((offset + n_bits) / 8.0f);
if (ptr + bytes_required >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_DECODE_FAIL;
}
ptr += bytes_offset;
@ -365,7 +306,7 @@ SRSASN_CODE bit_ref::pack_bytes(const uint8_t* buf, uint32_t n_bytes)
return SRSASN_SUCCESS;
}
if (ptr + n_bytes >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_ENCODE_FAIL;
}
if (offset == 0) {
@ -385,7 +326,7 @@ SRSASN_CODE bit_ref::align_bytes_zero()
if (offset == 0)
return SRSASN_SUCCESS;
if (ptr >= max_ptr) {
log_error("Buffer size limit was achieved\n");
log_error("Buffer size limit was achieved");
return SRSASN_ERROR_ENCODE_FAIL;
}
auto mask = static_cast<uint8_t>(256u - (1u << (8u - offset)));
@ -403,7 +344,7 @@ SRSASN_CODE pack_unsupported_ext_flag(bit_ref& bref, bool ext)
{
HANDLE_CODE(bref.pack(ext, 1));
if (ext) {
log_error("ASN extensions not currently supported\n");
log_error("ASN extensions not currently supported");
return SRSASN_ERROR_ENCODE_FAIL;
}
return SRSASN_SUCCESS;
@ -413,7 +354,7 @@ SRSASN_CODE unpack_unsupported_ext_flag(bool& ext, bit_ref& bref)
{
SRSASN_CODE ret = bref.unpack(ext, 1);
if (ext) {
log_error("ASN extensions not currently supported\n");
log_error("ASN extensions not currently supported");
return SRSASN_ERROR_DECODE_FAIL;
}
return ret;
@ -447,7 +388,7 @@ SRSASN_CODE pack_enum(bit_ref& bref, uint32_t e, uint32_t nof_types, uint32_t no
{
if (e >= nof_types) {
log_error(
"The provided enum is not within the range of possible values (%u>=%u)\n", (unsigned)e, (unsigned)nof_types);
"The provided enum is not within the range of possible values (%u>=%u)", (unsigned)e, (unsigned)nof_types);
return SRSASN_ERROR_ENCODE_FAIL;
}
SRSASN_CODE ret;
@ -482,7 +423,7 @@ ValOrError unpack_enum(uint32_t nof_types, uint32_t nof_exts, bool has_ext, cbit
ret.code = bref.unpack(ret.val, nof_bits);
}
if (ret.val >= nof_types) {
log_error("The provided enum is not within the range of possible values (%u>=%u)\n",
log_error("The provided enum is not within the range of possible values (%u>=%u)",
(unsigned)ret.val,
(unsigned)nof_types);
ret.code = SRSASN_ERROR_DECODE_FAIL;
@ -508,7 +449,7 @@ template <class IntType>
SRSASN_CODE pack_constrained_whole_number(bit_ref& bref, IntType n, IntType lb, IntType ub, bool aligned)
{
if (ub < lb or n < lb or n > ub) {
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub);
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub);
return SRSASN_ERROR_ENCODE_FAIL;
}
uint64_t ra = (uint64_t)(ub - lb) + 1; // NOTE: Can overflow if IntType is kept
@ -574,7 +515,7 @@ template <class IntType>
SRSASN_CODE unpack_constrained_whole_number(IntType& n, cbit_ref& bref, IntType lb, IntType ub, bool aligned)
{
if (ub < lb) {
log_error("The condition lb <= ub (%ld <= %ld) was not met\n", (long)lb, (long)ub);
log_error("The condition lb <= ub (%ld <= %ld) was not met", (long)lb, (long)ub);
return SRSASN_ERROR_DECODE_FAIL;
}
uint64_t ra = (uint64_t)(ub - lb) + 1; // NOTE: Can overflow if IntType is kept.
@ -588,7 +529,7 @@ SRSASN_CODE unpack_constrained_whole_number(IntType& n, cbit_ref& bref, IntType
HANDLE_CODE(bref.unpack(n, n_bits));
n += lb;
if (n > ub) {
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub);
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub);
return SRSASN_ERROR_DECODE_FAIL;
}
} else {
@ -644,7 +585,7 @@ SRSASN_CODE pack_norm_small_non_neg_whole_number(bit_ref& bref, UintType n)
HANDLE_CODE(bref.pack(n, 7)); // [1 bit: 0 | 6 bit: n]
} else {
HANDLE_CODE(bref.pack(1, 1));
log_error("Long small integers not supported\n");
log_error("Long small integers not supported");
return SRSASN_ERROR_ENCODE_FAIL;
}
return SRSASN_SUCCESS;
@ -658,7 +599,7 @@ SRSASN_CODE unpack_norm_small_non_neg_whole_number(UintType& n, cbit_ref& bref)
if (not ext) {
ret = bref.unpack(n, 6);
} else {
log_error("Long small integers not supported\n");
log_error("Long small integers not supported");
return SRSASN_ERROR_DECODE_FAIL;
}
return ret;
@ -785,7 +726,7 @@ SRSASN_CODE pack_length(bit_ref& bref, uint32_t val, bool aligned)
HANDLE_CODE(bref.pack(0b10, 2));
HANDLE_CODE(bref.pack(val, 14));
} else {
log_error("Not handling sizes longer than 16383 octets\n");
log_error("Not handling sizes longer than 16383 octets");
return SRSASN_ERROR_ENCODE_FAIL;
}
} else {
@ -824,7 +765,7 @@ SRSASN_CODE unpack_length(uint32_t& val, cbit_ref& bref, bool aligned)
if (not ext) {
ret = bref.unpack(val, 14);
} else {
log_error("Not handling octet strings longer than 16383 octets\n");
log_error("Not handling octet strings longer than 16383 octets");
val = 0;
return SRSASN_ERROR_DECODE_FAIL;
}
@ -864,7 +805,7 @@ SRSASN_CODE pack_integer(bit_ref& bref, IntType n, IntType lb, IntType ub, bool
if (has_ext) {
HANDLE_CODE(bref.pack(not within_bounds, 1));
} else if (not within_bounds) {
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met\n", (long)lb, (long)n, (long)ub);
log_error("The condition lb <= n <= ub (%ld <= %ld <= %ld) was not met", (long)lb, (long)n, (long)ub);
return SRSASN_ERROR_ENCODE_FAIL;
}
bool lower_bounded = lb != std::numeric_limits<IntType>::min() or std::is_unsigned<IntType>::value;
@ -1012,7 +953,7 @@ template struct integer_packer<uint64_t>;
uint64_t octstring_to_number(const uint8_t* ptr, uint32_t nbytes)
{
if (nbytes > 8) {
log_error("octstring of size=%d does not fit in an uint64_t\n", nbytes);
log_error("octstring of size=%d does not fit in an uint64_t", nbytes);
return 0;
}
uint64_t val = 0;
@ -1025,7 +966,7 @@ uint64_t octstring_to_number(const uint8_t* ptr, uint32_t nbytes)
void number_to_octstring(uint8_t* ptr, uint64_t number, uint32_t nbytes)
{
if (nbytes > 8) {
log_error("octstring of size=%d does not fit in an uint64_t\n", nbytes);
log_error("octstring of size=%d does not fit in an uint64_t", nbytes);
return;
}
for (uint32_t i = 0; i < nbytes; ++i) {
@ -1054,7 +995,7 @@ std::string octstring_to_string(const uint8_t* ptr, uint32_t N)
void string_to_octstring(uint8_t* ptr, const std::string& str)
{
if (str.size() % 2 != 0) {
log_warning("The provided hex string size=%zd is not a multiple of 2\n.", str.size());
log_warning("The provided hex string size=%zd is not a multiple of 2.", str.size());
}
char cstr[] = "\0\0\0";
for (uint32_t i = 0; i < str.size(); i += 2) {
@ -1123,12 +1064,12 @@ SRSASN_CODE pack_length_prefix(bit_ref& bref,
bool is_aligned = false)
{
if (has_ext and ub == std::numeric_limits<uint32_t>::max()) {
log_error("has extension marker but it is an unbounded prefix size\n");
log_error("has extension marker but it is an unbounded prefix size");
return SRSASN_ERROR_ENCODE_FAIL;
}
bool within_bounds = len >= lb and len <= ub;
if (not within_bounds and not has_ext) {
log_error("bitstring length=%d is not within bounds [%d, %d]\n", len, lb, ub);
log_error("bitstring length=%d is not within bounds [%d, %d]", len, lb, ub);
return SRSASN_ERROR_ENCODE_FAIL;
}
@ -1159,7 +1100,7 @@ SRSASN_CODE pack_length_prefix(bit_ref& bref,
SRSASN_CODE pack_bitfield(bit_ref& bref, const uint8_t* buf, uint32_t nbits, uint32_t lb, uint32_t ub, bool is_aligned)
{
if (nbits == 0) {
log_error("Invalid bitstring size=%d\n", nbits);
log_error("Invalid bitstring size=%d", nbits);
return SRSASN_ERROR_ENCODE_FAIL;
}
if (is_aligned and (lb != ub or ub > 16)) {
@ -1222,7 +1163,7 @@ SRSASN_CODE unpack_length_prefix(uint32_t& len, cbit_ref& bref, uint32_t lb, uin
SRSASN_CODE unpack_bitfield(uint8_t* buf, cbit_ref& bref, uint32_t n, uint32_t lb, uint32_t ub, bool is_aligned)
{
if (n > ASN_64K) {
log_error("bitstrings longer than 64K not supported\n");
log_error("bitstrings longer than 64K not supported");
return SRSASN_ERROR_DECODE_FAIL;
}
if (n == 0) {
@ -1245,7 +1186,7 @@ SRSASN_CODE unpack_bitfield(uint8_t* buf, cbit_ref& bref, uint32_t n, uint32_t l
void from_number(uint8_t* ptr, uint64_t number, uint32_t nbits)
{
if (nbits > 64u) {
log_error("bitstring of size=%d does not fit in an uint64_t\n", nbits);
log_error("bitstring of size=%d does not fit in an uint64_t", nbits);
return;
}
uint32_t nof_bytes = ceil_frac(nbits, 8u);
@ -1270,7 +1211,7 @@ std::string to_string(const uint8_t* ptr, uint32_t nbits)
uint64_t to_number(const uint8_t* ptr, uint32_t nbits)
{
if (nbits > 64u) {
log_error("bitstring of size=%d does not fit in an uint64_t\n", nbits);
log_error("bitstring of size=%d does not fit in an uint64_t", nbits);
return 0;
}
uint64_t val = 0;
@ -1288,11 +1229,11 @@ uint64_t to_number(const uint8_t* ptr, uint32_t nbits)
*********************/
void log_invalid_access_choice_id(uint32_t val, uint32_t choice_id)
{
log_error("The access choide id is invalid (%zd!=%zd)\n", (size_t)val, (size_t)choice_id);
log_error("The access choide id is invalid (%zd!=%zd)", (size_t)val, (size_t)choice_id);
}
void log_invalid_choice_id(uint32_t val, const char* choice_type)
{
log_error("Invalid choice id=%zd for choice type %s\n", (size_t)val, choice_type);
log_error("Invalid choice id=%zd for choice type %s", (size_t)val, choice_type);
}
/*********************
@ -1329,7 +1270,7 @@ pack(bit_ref& bref, const std::string& s, size_t lb, size_t ub, size_t alb, size
if (not within_limits) {
// TODO: print error
// NOTE: This should be valid for exts
log_error("The PrintableString size=%zd is not within the limits [%zd, %zd]\n", s.size(), alb, aub);
log_error("The PrintableString size=%zd is not within the limits [%zd, %zd]", s.size(), alb, aub);
return SRSASN_ERROR_ENCODE_FAIL;
}
size_t b = asn_string_utils::get_nof_bits_per_char(lb, ub, aligned);
@ -1366,7 +1307,7 @@ SRSASN_CODE unpack(std::string& s, cbit_ref& bref, size_t lb, size_t ub, size_t
bool is_ext;
HANDLE_CODE(bref.unpack(is_ext, 1));
if (is_ext) {
log_error("Extension of PrintableString not supported\n");
log_error("Extension of PrintableString not supported");
return SRSASN_ERROR_DECODE_FAIL;
}
}
@ -1489,7 +1430,7 @@ varlength_field_pack_guard::~varlength_field_pack_guard()
// check how many bytes were written in total
uint32_t nof_bytes = bref_tracker->distance(bref0) / (uint32_t)8;
if (nof_bytes > sizeof(buffer)) {
log_error("The packed variable sized field is too long for the reserved buffer (%zd > %zd)\n",
log_error("The packed variable sized field is too long for the reserved buffer (%zd > %zd)",
(size_t)nof_bytes,
sizeof(buffer));
}

View File

@ -282,7 +282,7 @@ std::string log_filter::hex_string(const uint8_t* hex, int size)
size = (size > hex_limit) ? hex_limit : size;
}
while (c < size) {
ss << " " << std::setw(4) << static_cast<unsigned>(c) << ": ";
ss << " " << std::setw(4) << static_cast<unsigned>(c) << ": ";
int tmp = (size - c < 16) ? size - c : 16;
for (int i = 0; i < tmp; i++) {
ss << std::setw(2) << static_cast<unsigned>(hex[c++]) << " ";

View File

@ -644,6 +644,13 @@ int test_big_integers()
int main()
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_arrays() == 0);
TESTASSERT(test_bit_ref() == 0);
TESTASSERT(test_oct_string() == 0);
@ -653,5 +660,8 @@ int main()
TESTASSERT(test_enum() == 0);
TESTASSERT(test_big_integers() == 0);
// TESTASSERT(test_json_writer()==0);
srslog::flush();
printf("Success\n");
}

View File

@ -338,6 +338,12 @@ int test_session_res_setup_request()
int main()
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_amf_upd() == 0);
TESTASSERT(test_ngsetup_request() == 0);
@ -349,6 +355,8 @@ int main()
TESTASSERT(test_ue_context_release_complete() == 0);
TESTASSERT(test_session_res_setup_request() == 0);
srslog::flush();
printf("Success\n");
return 0;
}

View File

@ -113,6 +113,13 @@ int main(int argc, char** argv)
return -1;
}
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
asn1::cbit_ref bref(rrc_msg, fsize);
// TODO do other rrc messages and type

View File

@ -119,8 +119,8 @@ int test_eutra_nr_capabilities()
TESTASSERT(test_pack_unpack_consistency(mrdc_cap) == SRSASN_SUCCESS);
srslte::logmap::get("RRC")->info_hex(
buffer, bref.distance_bytes(), "Packed cap struct (%d bytes):\n", bref.distance_bytes());
srslog::fetch_basic_logger("RRC").info(
buffer, bref.distance_bytes(), "Packed cap struct (%d bytes):", bref.distance_bytes());
return SRSLTE_SUCCESS;
}
@ -177,7 +177,7 @@ int test_ue_rrc_reconfiguration()
TESTASSERT(rrc_recfg.rrc_transaction_id == 0);
json_writer jw;
rrc_recfg.to_json(jw);
srslte::logmap::get("RRC")->info_long("RRC Reconfig: \n %s \n", jw.to_string().c_str());
srslog::fetch_basic_logger("RRC").info("RRC Reconfig: \n %s", jw.to_string().c_str());
TESTASSERT(rrc_recfg.crit_exts.type() == asn1::rrc_nr::rrc_recfg_s::crit_exts_c_::types::rrc_recfg);
TESTASSERT(rrc_recfg.crit_exts.rrc_recfg().secondary_cell_group_present == true);
@ -188,7 +188,7 @@ int test_ue_rrc_reconfiguration()
TESTASSERT(cell_group_cfg.unpack(bref0) == SRSASN_SUCCESS);
json_writer jw1;
cell_group_cfg.to_json(jw1);
srslte::logmap::get("RRC")->info_long("RRC Secondary Cell Group: \n %s \n", jw1.to_string().c_str());
srslog::fetch_basic_logger("RRC").info("RRC Secondary Cell Group: \n %s", jw1.to_string().c_str());
TESTASSERT(cell_group_cfg.cell_group_id == 1);
TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list_present == true);
TESTASSERT(cell_group_cfg.rlc_bearer_to_add_mod_list.size() == 1);
@ -207,7 +207,7 @@ int test_radio_bearer_config()
TESTASSERT(radio_bearer_cfg.unpack(bref) == SRSASN_SUCCESS);
json_writer jw;
radio_bearer_cfg.to_json(jw);
srslte::logmap::get("RRC")->info_long("RRC Bearer CFG Message: \n %s \n", jw.to_string().c_str());
srslog::fetch_basic_logger("RRC").info("RRC Bearer CFG Message: \n %s", jw.to_string().c_str());
TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list_present == true);
TESTASSERT(radio_bearer_cfg.drb_to_add_mod_list.size() == 1);
TESTASSERT(radio_bearer_cfg.security_cfg_present == true);
@ -219,12 +219,23 @@ int test_radio_bearer_config()
int main()
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
auto& rrc_logger = srslog::fetch_basic_logger("RRC", false);
rrc_logger.set_level(srslog::basic_levels::debug);
rrc_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_eutra_nr_capabilities() == 0);
TESTASSERT(test_ue_mrdc_capabilities() == 0);
TESTASSERT(test_ue_rrc_reconfiguration() == 0);
TESTASSERT(test_radio_bearer_config() == 0);
srslog::flush();
printf("Success\n");
return 0;
}

View File

@ -33,7 +33,7 @@ int test_rlc_config()
rlc_cfg_asn1.um_bi_dir().ul_um_rlc.sn_field_len = asn1::rrc_nr::sn_field_len_um_e::size12;
asn1::json_writer jw;
rlc_cfg_asn1.to_json(jw);
logmap::get("RRC")->info_long("RLC NR Config: \n %s \n", jw.to_string().c_str());
srslog::fetch_basic_logger("RRC").info("RLC NR Config: \n %s", jw.to_string().c_str());
rlc_config_t rlc_cfg = make_rlc_config_t(rlc_cfg_asn1);
TESTASSERT(rlc_cfg.rat == srslte_rat_t::nr);
@ -45,9 +45,20 @@ int test_rlc_config()
int main()
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
auto& rrc_logger = srslog::fetch_basic_logger("RRC", false);
rrc_logger.set_level(srslog::basic_levels::debug);
rrc_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_rlc_config() == 0);
srslog::flush();
printf("Success\n");
return 0;
}

View File

@ -26,16 +26,6 @@ int test_generic()
// make suce a choice is always started in null mode
TESTASSERT(choice_type1.type() == pusch_enhance_cfg_r14_c::types::nulltype);
// test logger handler
{
srslte::scoped_log<srslte::nullsink_log> null_log("ASN1");
null_log->set_level(srslte::LOG_LEVEL_INFO);
asn1::log_info("This is a console test to see if the RRC logger is working fine\n");
TESTASSERT(null_log->last_log_msg == "This is a console test to see if the RRC logger is working fine\n");
TESTASSERT(null_log->last_log_level == srslte::LOG_LEVEL_INFO);
// go back to original logger
}
// Test deep copy of choice types
sib_type14_r11_s::eab_param_r11_c_ choice2;
choice2.set_eab_per_plmn_list_r11();
@ -704,6 +694,12 @@ int test_rrc_conn_reconf_r15_3()
int main()
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_DEBUG);
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_generic() == 0);
TESTASSERT(test_json_printer() == 0);
@ -720,6 +716,9 @@ int main()
TESTASSERT(test_rrc_conn_reconf_r15_2() == 0);
TESTASSERT(test_rrc_conn_reconf_v2() == 0);
TESTASSERT(test_rrc_conn_reconf_r15_3() == 0);
srslog::flush();
printf("Success\n");
return 0;
}

View File

@ -116,7 +116,7 @@ bool is_same_type(U& u)
return std::is_same<T, U>::value;
}
int test_proc_id_consistency()
int test_proc_id_consistency(srslte::log_sink_spy& spy)
{
s1ap_pdu_c pdu;
@ -141,11 +141,9 @@ int test_proc_id_consistency()
TESTASSERT(unsuc.value.type().value == s1ap_elem_procs_o::unsuccessful_outcome_c::types_opts::ho_fail);
TESTASSERT(is_same_type<ho_fail_s>(unsuc.value.ho_fail()));
// e-RABSetup (No Unsuccessful Outcome)
{
srslte::scoped_log<srslte::nullsink_log> sink("ASN1");
TESTASSERT(not unsuc.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP));
TESTASSERT(sink->error_counter == 1);
}
spy.reset_counters();
TESTASSERT(not unsuc.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP));
TESTASSERT(spy.get_error_counter() == 1);
// initialContextSetup
TESTASSERT(unsuc.load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP));
TESTASSERT(unsuc.proc_code == ASN1_S1AP_ID_INIT_CONTEXT_SETUP);
@ -216,7 +214,7 @@ int test_enb_status_transfer()
asn1::bit_ref bref{buffer, sizeof(buffer)};
TESTASSERT(pdu.pack(bref) == SRSASN_SUCCESS);
srslte::logmap::get("ASN1")->info_hex(
srslog::fetch_basic_logger("ASN1").info(
buffer, bref.distance_bytes(), "eNB Status Transfer (%d bytes)", (int)bref.distance_bytes());
asn1::cbit_ref bref2{buffer, sizeof(buffer)};
@ -291,8 +289,8 @@ int test_initial_ctxt_setup_response()
asn1::bit_ref bref(buffer, sizeof(buffer));
TESTASSERT(tx_pdu.pack(bref) == SRSLTE_SUCCESS);
srslte::logmap::get("TEST")->info_hex(
buffer, bref.distance_bytes(), "message (nof bytes = %d):\n", bref.distance_bytes());
srslog::fetch_basic_logger("TEST").info(
buffer, bref.distance_bytes(), "message (nof bytes = %d):", bref.distance_bytes());
return SRSLTE_SUCCESS;
}
@ -334,7 +332,7 @@ int test_eci_pack()
TESTASSERT(buffer[1] == 0x19);
TESTASSERT(buffer[2] == 0xC0);
srslte::logmap::get("TEST")->info_hex(buffer, bref.distance_bytes(), "Packed cell id:\n");
srslog::fetch_basic_logger("TEST").info(buffer, bref.distance_bytes(), "Packed cell id:");
return SRSLTE_SUCCESS;
}
@ -361,10 +359,32 @@ int main()
srslte::logmap::set_default_hex_limit(4096);
TESTASSERT(srslte::logmap::get("ASN1")->get_level() == srslte::LOG_LEVEL_DEBUG);
// Setup the log spy to intercept error and warning log entries.
if (!srslog::install_custom_sink(
srslte::log_sink_spy::name(),
std::unique_ptr<srslte::log_sink_spy>(new srslte::log_sink_spy(srslog::get_default_log_formatter())))) {
return SRSLTE_ERROR;
}
auto* spy = static_cast<srslte::log_sink_spy*>(srslog::find_sink(srslte::log_sink_spy::name()));
if (!spy) {
return SRSLTE_ERROR;
}
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", *spy, false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
auto& test_logger = srslog::fetch_basic_logger("TEST", false);
test_logger.set_level(srslog::basic_levels::debug);
test_logger.set_hex_dump_max_size(-1);
// Start the log backend.
srslog::init();
TESTASSERT(test_s1setup_request() == 0);
TESTASSERT(test_init_ctxt_setup_req() == 0);
TESTASSERT(test_ue_ctxt_release_req() == 0);
TESTASSERT(test_proc_id_consistency() == 0);
TESTASSERT(test_proc_id_consistency(*spy) == 0);
TESTASSERT(test_ho_request() == 0);
TESTASSERT(test_enb_status_transfer() == 0);
TESTASSERT(unpack_test_served_gummeis_with_multiple_plmns() == 0);
@ -373,6 +393,8 @@ int main()
TESTASSERT(test_eci_pack() == 0);
TESTASSERT(test_paging() == 0);
srslog::flush();
printf("Success\n");
return 0;
}

View File

@ -12,6 +12,7 @@
#include "srslte/asn1/liblte_mme.h"
#include "srslte/common/log_filter.h"
#include "srslte/srslog/srslog.h"
#include <iostream>
#include <memory>
#include <srslte/common/buffer_pool.h>
@ -28,9 +29,9 @@
int nas_dedicated_eps_bearer_context_setup_request_test()
{
srslte::log_filter log1("NAS");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
auto& nas_logger = srslog::fetch_basic_logger("NAS", false);
nas_logger.set_level(srslog::basic_levels::debug);
nas_logger.set_hex_dump_max_size(128);
srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance();
srslte::unique_byte_buffer_t tst_msg, out_msg;
@ -47,7 +48,7 @@ int nas_dedicated_eps_bearer_context_setup_request_test()
// Unpack Activate Dedicated EPS bearer context setup request
tst_msg->N_bytes = nas_message_len;
memcpy(tst_msg->msg, nas_message, nas_message_len);
log1.info_hex(tst_msg->msg, tst_msg->N_bytes, "NAS Activate Dedicated EPS Bearer Context Request original message\n");
nas_logger.info(tst_msg->msg, tst_msg->N_bytes, "NAS Activate Dedicated EPS Bearer Context Request original message");
// Test message type and protocol discriminator
uint8_t pd, msg_type;
@ -101,12 +102,21 @@ int nas_dedicated_eps_bearer_context_setup_request_test()
TESTASSERT(ded_bearer_req.packet_flow_id == 77); // Test flow id
// NAS Activate Dedicated EPS Bearer Context Setup Request Pack Test (TODO)
srslog::flush();
printf("Test NAS Activate Dedicated EPS Bearer Context Request successfull\n");
return 0;
}
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
int result = nas_dedicated_eps_bearer_context_setup_request_test();
return result;
}

View File

@ -28,10 +28,6 @@ using namespace asn1::rrc;
int rrc_conn_setup_test1()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
uint8_t rrc_msg[] = {0x60, 0x12, 0x98, 0x0b, 0xfd, 0xd2, 0x04, 0xfa, 0x18, 0x3e, 0xd5, 0xe6, 0xc2,
0x59, 0x90, 0xc1, 0xa6, 0x00, 0x01, 0x31, 0x40, 0x42, 0x50, 0x80, 0x00, 0xf8};
uint32_t rrc_msg_len = sizeof(rrc_msg);
@ -81,9 +77,9 @@ int rrc_conn_setup_test1()
// Only packing implemented
int rrc_reestablishment_reject_test()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
auto& rrc_logger = srslog::fetch_basic_logger("RRC", false);
rrc_logger.set_level(srslog::basic_levels::debug);
rrc_logger.set_hex_dump_max_size(128);
dl_ccch_msg_s dl_ccch_msg;
dl_ccch_msg.msg.set(dl_ccch_msg_type_c::types::c1);
@ -102,14 +98,21 @@ int rrc_reestablishment_reject_test()
}
int actual_len = bref.distance_bytes(rrc_msg);
log1.info_hex(rrc_msg, actual_len, "DL-CCCH message (%d/%zd B)\n", actual_len, sizeof(rrc_msg));
rrc_logger.info(rrc_msg, actual_len, "DL-CCCH message (%d/%zd B)", actual_len, sizeof(rrc_msg));
return 0;
}
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
TESTASSERT(rrc_conn_setup_test1() == 0);
TESTASSERT(rrc_reestablishment_reject_test() == 0);
return 0;
}

View File

@ -28,10 +28,6 @@ using namespace asn1::rrc;
int rrc_conn_reconfig_ho_test1()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
uint8_t rrc_msg[] = {0x20, 0x1b, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x01, 0xa9, 0x08, 0x80, 0x00, 0x00, 0x29, 0x00,
0x97, 0x80, 0x00, 0x00, 0x00, 0x01, 0x04, 0x22, 0x14, 0x00, 0xf8, 0x02, 0x0a, 0xc0, 0x60,
0x00, 0xa0, 0x0c, 0x80, 0x42, 0x02, 0x9f, 0x43, 0x07, 0xda, 0xbc, 0xf8, 0x4b, 0x32, 0x18,
@ -64,6 +60,13 @@ int rrc_conn_reconfig_ho_test1()
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
TESTASSERT(rrc_conn_reconfig_ho_test1() == 0);
return 0;
}

View File

@ -29,10 +29,6 @@ using namespace asn1::rrc;
int meas_obj_test()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(1024);
uint8_t known_reference[] = {0x0d, 0x8f, 0xdf, 0xff, 0xff, 0xff, 0xe2, 0x2f, 0xfc, 0x38,
0x5e, 0x61, 0xec, 0xa8, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,
0x20, 0x05, 0xe6, 0x1e, 0xca, 0x80, 0x00, 0x00, 0x40, 0x42};
@ -121,6 +117,13 @@ int meas_obj_test()
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
TESTASSERT(meas_obj_test() == 0);
return 0;
}

View File

@ -31,10 +31,6 @@ using namespace asn1::rrc;
int meas_obj_test()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
uint8_t rrc_msg[] = {
0x08, 0x10, 0x49, 0x3C, 0x0D, 0x97, 0x89, 0x83, 0xC0, 0x84, 0x20, 0x82, 0x08, 0x21, 0x00, 0x01, 0xBC, 0x48};
uint32_t rrc_msg_len = sizeof(rrc_msg);
@ -91,6 +87,13 @@ int meas_obj_test()
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
TESTASSERT(meas_obj_test() == 0);
return 0;
}

View File

@ -30,9 +30,9 @@ using namespace asn1::rrc;
int rrc_ue_cap_info_test(srslte::mac_pcap* pcap)
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
auto& rrc_logger = srslog::fetch_basic_logger("RRC", false);
rrc_logger.set_level(srslog::basic_levels::debug);
rrc_logger.set_hex_dump_max_size(128);
rrc_args_t args = {};
args.feature_group = 0xe6041c00;
@ -80,7 +80,7 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap)
info->ue_cap_rat_container_list[0].ue_cap_rat_container.resize(cap_len);
memcpy(info->ue_cap_rat_container_list[0].ue_cap_rat_container.data(), buf, cap_len);
log1.debug_hex(buf, cap_len, "UE-Cap (%d/%zd B)\n", cap_len, sizeof(buf));
rrc_logger.debug(buf, cap_len, "UE-Cap (%d/%zd B)", cap_len, sizeof(buf));
// pack the message
uint8_t byte_buf[32];
@ -90,7 +90,7 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap)
bref3.align_bytes_zero();
uint32_t len = (uint32_t)bref3.distance_bytes(byte_buf);
log1.debug_hex(byte_buf, len, "UL-DCCH (%d/%zd B)\n", len, sizeof(byte_buf));
rrc_logger.debug(byte_buf, len, "UL-DCCH (%d/%zd B)", len, sizeof(byte_buf));
if (pcap != NULL) {
pcap->write_ul_rrc_pdu(byte_buf, len);
@ -101,10 +101,6 @@ int rrc_ue_cap_info_test(srslte::mac_pcap* pcap)
int pack_fail_test()
{
srslte::log_filter log1("RRC");
log1.set_level(srslte::LOG_LEVEL_DEBUG);
log1.set_hex_limit(128);
rrc_args_t args = {};
args.feature_group = 0xe6041c00;
args.nof_supported_bands = 1;
@ -154,6 +150,12 @@ int pack_fail_test()
int main(int argc, char** argv)
{
auto& asn1_logger = srslog::fetch_basic_logger("ASN1", false);
asn1_logger.set_level(srslog::basic_levels::debug);
asn1_logger.set_hex_dump_max_size(-1);
srslog::init();
#if PCAP
srslte::mac_pcap pcap;
pcap.open("ul_dcch.pcap");