diff --git a/sys/fmt/fmt.c b/sys/fmt/fmt.c index 5ea21e8b8e9a705a766cc6d15d5c2b2c3d7e9e86..58aa01483b45a4cc13ef744371e622d09a4af3af 100644 --- a/sys/fmt/fmt.c +++ b/sys/fmt/fmt.c @@ -132,18 +132,22 @@ static uint8_t _hex_nib(uint8_t nib) return _byte_mod25((nib & 0x1f) + 9); } +uint8_t fmt_hex_byte(const char *hex) +{ + return (_hex_nib(hex[0]) << 4) | _hex_nib(hex[1]); +} + size_t fmt_hex_bytes(uint8_t *out, const char *hex) { size_t len = fmt_strlen(hex); if (len & 1) { - out = NULL; return 0; } size_t final_len = len >> 1; for (size_t i = 0, j = 0; j < final_len; i += 2, j++) { - out[j] = (_hex_nib(hex[i]) << 4) | _hex_nib(hex[i+1]); + out[j] = fmt_hex_byte(hex + i); } return final_len; diff --git a/sys/include/fmt.h b/sys/include/fmt.h index 229f9396112267c227f70598b9f1e3478d1476e9..7176494d3098f6071807d8d75e69f8071f5a718f 100644 --- a/sys/include/fmt.h +++ b/sys/include/fmt.h @@ -91,6 +91,17 @@ size_t fmt_bytes_hex(char *out, const uint8_t *ptr, size_t n); */ size_t fmt_bytes_hex_reverse(char *out, const uint8_t *ptr, size_t n); +/** + * @brief Converts a sequence of two hex characters to a byte + * + * The hex characters sequence must contain valid hexadecimal characters + * otherwise the result is undefined. + * + * @param[in] hex Pointer to input buffer + * @returns byte based on hex string + */ +uint8_t fmt_hex_byte(const char *hex); + /** * @brief Converts a sequence of hex bytes to an array of bytes * diff --git a/tests/unittests/tests-fmt/tests-fmt.c b/tests/unittests/tests-fmt/tests-fmt.c index 949405ff7f506fa57af14618adaf119c5e6eac9d..0a7d537828c19432d58f74bee427413fbd907cd6 100644 --- a/tests/unittests/tests-fmt/tests-fmt.c +++ b/tests/unittests/tests-fmt/tests-fmt.c @@ -118,6 +118,31 @@ static void test_fmt_bytes_hex_reverse(void) TEST_ASSERT_EQUAL_STRING("zz", &out[9]); } +static void test_fmt_hex_byte(void) +{ + char hex[3] = "00"; + uint8_t byte; + + byte = fmt_hex_byte(hex); + TEST_ASSERT_EQUAL_INT(0x00, byte); + + memcpy(hex, "12", 2); + byte = fmt_hex_byte(hex); + TEST_ASSERT_EQUAL_INT(0x12, byte); + + memcpy(hex, "AB", 2); + byte = fmt_hex_byte(hex); + TEST_ASSERT_EQUAL_INT(0xAB, byte); + + memcpy(hex, "CD", 2); + byte = fmt_hex_byte(hex); + TEST_ASSERT_EQUAL_INT(0xCD, byte); + + memcpy(hex, "EF", 2); + byte = fmt_hex_byte(hex); + TEST_ASSERT_EQUAL_INT(0xEF, byte); +} + static void test_fmt_hex_bytes(void) { uint8_t val = 0; @@ -772,6 +797,7 @@ Test *tests_fmt_tests(void) new_TestFixture(test_fmt_byte_hex), new_TestFixture(test_fmt_bytes_hex), new_TestFixture(test_fmt_bytes_hex_reverse), + new_TestFixture(test_fmt_hex_byte), new_TestFixture(test_fmt_hex_bytes), new_TestFixture(test_fmt_u32_hex), new_TestFixture(test_fmt_u64_hex),