This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/baseband-devel@lists.osmocom.org/.
Max Max.Suraev at fairwaves.ru--- .gitignore | 1 + include/osmocom/core/utils.h | 5 ++++ src/utils.c | 68 ++++++++++++++++++++++++++++++++---------- tests/Makefile.am | 7 +++-- tests/hex/hex_test.c | 57 +++++++++++++++++++++++++++++++++++ tests/hex/hex_test.ok | 18 +++++++++++ tests/testsuite.at | 6 ++++ 7 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 tests/hex/hex_test.c create mode 100644 tests/hex/hex_test.ok diff --git a/.gitignore b/.gitignore index ac19b23..67d9196 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ tests/sms/sms_test tests/timer/timer_test tests/msgfile/msgfile_test tests/ussd/ussd_test +tests/hex/hex_test tests/smscb/smscb_test tests/bits/bitrev_test tests/a5/a5_test diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index 03861d7..5250094 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -30,6 +30,11 @@ char osmo_bcd2char(uint8_t bcd); /* only works for numbers in ascci */ uint8_t osmo_char2bcd(char c); +enum hex_len_policy { /* define how to deal with odd length during hex string parsing */ + HEX_ODD_NONE, HEX_ODD_LEFT, HEX_ODD_RIGHT +}; + +int osmo_hexparse_ext(const char *str, uint8_t *b, int max_len, enum hex_len_policy pol); int osmo_hexparse(const char *str, uint8_t *b, int max_len); char *osmo_ubit_dump(const uint8_t *bits, unsigned int len); diff --git a/src/utils.c b/src/utils.c index c36979c..a93d72c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -73,36 +73,74 @@ uint8_t osmo_char2bcd(char c) return c - 0x30; } -/*! \brief Parse a string ocntaining hexadecimal digits +/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x * \param[in] str string containing ASCII encoded hexadecimal digits * \param[out] b output buffer * \param[in] max_len maximum space in output buffer */ int osmo_hexparse(const char *str, uint8_t *b, int max_len) +{ + return osmo_hexparse_ext(str, b, max_len, HEX_ODD_NONE); +} +static inline int _osmo_hexval(char c) { - int i, l, v; + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return 10 + (c - 'a'); + if (c >= 'A' && c <= 'F') + return 10 + (c - 'A'); + return -1; +} - l = strlen(str); - if ((l&1) || ((l>>1) > max_len)) +/*! \brief Parse a string ocntaining hexadecimal digits, optionally prefixed with 0x + * \param[in] str string containing ASCII encoded hexadecimal digits + * \param[out] b output buffer + * \param[in] max_len maximum space in output buffer + * \param[in] pol defines how to treat odd length case + */ +int osmo_hexparse_ext(const char *str, uint8_t *b, int max_len, enum hex_len_policy pol) +{ + int v; + size_t i, left_adj = 0, right_adj = 0, l = strlen(str); + const char *src; + + if (l > 2) { /* remove 0x prefix if any */ + if (!strncmp(str, "0x", 2)) { + l -= 2; + str += 2; + } + } + + if (l & 1) { + switch (pol) { + case HEX_ODD_LEFT: + left_adj = 1; + break; + case HEX_ODD_NONE: + return -1; + case HEX_ODD_RIGHT: + right_adj = 1; + break; + default: + return -1; + } + } +/* left_adj and right_adj are mutually exclusive so left_adj + right_adj is either 1 or 0 */ + if ((l>>1) + left_adj + right_adj > max_len) return -1; memset(b, 0x00, max_len); - for (i=0; i<l; i++) { - char c = str[i]; - if (c >= '0' && c <= '9') - v = c - '0'; - else if (c >= 'a' && c <= 'f') - v = 10 + (c - 'a'); - else if (c >= 'A' && c <= 'F') - v = 10 + (c - 'A'); - else + for (i = 0; i < l; i++) { + v = _osmo_hexval(str[i]); + if (-1 == v) return -1; - b[i>>1] |= v << (i&1 ? 0 : 4); + b[(i + left_adj) >> 1] |= v << ((i + left_adj) & 1 ? 0 : 4); } - return i>>1; + return (l + left_adj + right_adj)/2; } static char hexd_buff[4096]; diff --git a/tests/Makefile.am b/tests/Makefile.am index b60f675..fbefab1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -4,7 +4,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \ smscb/smscb_test bits/bitrev_test a5/a5_test \ conv/conv_test auth/milenage_test lapd/lapd_test \ gsm0808/gsm0808_test gsm0408/gsm0408_test \ - gb/bssgp_fc_test logging/logging_test + gb/bssgp_fc_test hex/hex_test logging/logging_test if ENABLE_MSGFILE check_PROGRAMS += msgfile/msgfile_test endif @@ -21,6 +21,9 @@ bits_bitrev_test_LDADD = $(top_builddir)/src/libosmocore.la conv_conv_test_SOURCES = conv/conv_test.c conv_conv_test_LDADD = $(top_builddir)/src/libosmocore.la +hex_hex_test_SOURCES = hex/hex_test.c +hex_hex_test_LDADD = $(top_builddir)/src/libosmocore.la + gsm0808_gsm0808_test_SOURCES = gsm0808/gsm0808_test.c gsm0808_gsm0808_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la @@ -77,7 +80,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \ gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \ msgfile/msgfile_test.ok msgfile/msgconfig.cfg \ - logging/logging_test.ok logging/logging_test.err + logging/logging_test.ok hex/hex_test.ok logging/logging_test.err DISTCLEANFILES = atconfig diff --git a/tests/hex/hex_test.c b/tests/hex/hex_test.c new file mode 100644 index 0000000..5c060c4 --- /dev/null +++ b/tests/hex/hex_test.c @@ -0,0 +1,57 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include <osmocom/core/utils.h> + +/* ------------------------------------------------------------------------ */ +/* Test vectors */ +/* ------------------------------------------------------------------------ */ + +char * long_rand_x = "0xa63c3b465eb79b3e06ae66eb816eace"; +char * long_rand = "39ea2e536e6a2c0d3e59110df20e4bf"; +char * small_even_x = "0xDEAD"; +char * small_even = "FACE"; +char * small_odd_x = "0xFFACE"; +char * small_odd = "bee"; + +/* ------------------------------------------------------------------------ */ +/* Main */ +/* ------------------------------------------------------------------------ */ + +inline void _single_test(char * vec, size_t len, uint8_t * test, enum hex_len_policy pol) +{ + int r = osmo_hexparse_ext(vec, test, len, pol); + printf(" parsed %s (%u): %d", vec, len, r); + if (-1 != r) printf(", dumped: %s, check %x,%d,%d\n", osmo_hexdump_nospc(test, len), test[len - 1], test[len], test[len + 1]); + else printf("\n"); +} + +inline void _run_tests(char * vec, size_t len) +{ + uint8_t test[len + 4]; + int r; + + for (r = 0; r < len + 4; r++) test[r] = r; + + printf("NONE"); + _single_test(vec, len, test, HEX_ODD_NONE); + + printf("LEFT"); + _single_test(vec, len, test, HEX_ODD_LEFT); + + printf("RIGHT"); + _single_test(vec, len, test, HEX_ODD_RIGHT); +} + +int main(int argc, char **argv) +{ + _run_tests(long_rand_x, 16); + _run_tests(long_rand, 16); + _run_tests(small_even_x, 2); + _run_tests(small_even, 2); + _run_tests(small_odd_x, 3); + _run_tests(small_odd, 2); + + return 0; +} diff --git a/tests/hex/hex_test.ok b/tests/hex/hex_test.ok new file mode 100644 index 0000000..44e89d2 --- /dev/null +++ b/tests/hex/hex_test.ok @@ -0,0 +1,18 @@ +NONE parsed 0xa63c3b465eb79b3e06ae66eb816eace (16): -1 +LEFT parsed 0xa63c3b465eb79b3e06ae66eb816eace (16): 16, dumped: 0a63c3b465eb79b3e06ae66eb816eace, check ce,16,17 +RIGHT parsed 0xa63c3b465eb79b3e06ae66eb816eace (16): 16, dumped: a63c3b465eb79b3e06ae66eb816eace0, check e0,16,17 +NONE parsed 39ea2e536e6a2c0d3e59110df20e4bf (16): -1 +LEFT parsed 39ea2e536e6a2c0d3e59110df20e4bf (16): 16, dumped: 039ea2e536e6a2c0d3e59110df20e4bf, check bf,16,17 +RIGHT parsed 39ea2e536e6a2c0d3e59110df20e4bf (16): 16, dumped: 39ea2e536e6a2c0d3e59110df20e4bf0, check f0,16,17 +NONE parsed 0xDEAD (2): 2, dumped: dead, check ad,2,3 +LEFT parsed 0xDEAD (2): 2, dumped: dead, check ad,2,3 +RIGHT parsed 0xDEAD (2): 2, dumped: dead, check ad,2,3 +NONE parsed FACE (2): 2, dumped: face, check ce,2,3 +LEFT parsed FACE (2): 2, dumped: face, check ce,2,3 +RIGHT parsed FACE (2): 2, dumped: face, check ce,2,3 +NONE parsed 0xFFACE (3): -1 +LEFT parsed 0xFFACE (3): 3, dumped: 0fface, check ce,3,4 +RIGHT parsed 0xFFACE (3): 3, dumped: fface0, check e0,3,4 +NONE parsed bee (2): -1 +LEFT parsed bee (2): 2, dumped: 0bee, check ee,2,3 +RIGHT parsed bee (2): 2, dumped: bee0, check e0,2,3 diff --git a/tests/testsuite.at b/tests/testsuite.at index 1cfae03..cfbcf78 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -28,6 +28,12 @@ cat $abs_srcdir/conv/conv_test.ok > expout AT_CHECK([$abs_top_builddir/tests/conv/conv_test], [], [expout]) AT_CLEANUP +AT_SETUP([hex]) +AT_KEYWORDS([hex]) +cat $abs_srcdir/hex/hex_test.ok > expout +AT_CHECK([$abs_top_builddir/tests/hex/hex_test], [], [expout]) +AT_CLEANUP + if ENABLE_MSGFILE AT_SETUP([msgfile]) AT_KEYWORDS([msgfile]) -- 1.7.10.4 --------------080702070805090503080203--