diff --git a/Makefile.dep b/Makefile.dep index 5e5872a9e7..a0e6ff9229 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -781,6 +781,10 @@ ifneq (,$(filter skald,$(USEMODULE))) USEMODULE += random endif +ifneq (,$(filter bluetil_addr,$(USEMODULE))) + USEMODULE += fmt +endif + ifneq (,$(filter cord_epsim_standalone,$(USEMODULE))) USEMODULE += cord_epsim USEMODULE += xtimer diff --git a/sys/include/net/bluetil/addr.h b/sys/include/net/bluetil/addr.h new file mode 100644 index 0000000000..f69907bc63 --- /dev/null +++ b/sys/include/net/bluetil/addr.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup ble_bluetil_addr BLE Address Helper + * @ingroup ble_bluetil + * @brief Generic BLE address handling functions + * @{ + * + * @file + * @brief Interface for the generic BLE address helper functions + * + * @author Hauke Petersen + */ + +#ifndef NET_BLUETIL_ADDR_H +#define NET_BLUETIL_ADDR_H + +#include + +#include "net/ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The length of a BLE address string in bytes (including '\0') + */ +#define BLUETIL_ADDR_STRLEN (18U) + +/** + * @brief The length of an IPv6 IID string in bytes (including '\0') + */ +#define BLUETIL_IPV6_IID_STRLEN (28U) + +/** + * @brief Convert the given BLE address to a human readable string + * + * @param[out] out '\0' terminated address string, *must* be able to hold + * BLUETIL_ADDR_STRLEN bytes + * @param[in] addr address buffer, *must* hold BLE_ADDR_LEN bytes + */ +void bluetil_addr_sprint(char *out, const uint8_t *addr); + +/** + * @brief Print the given BLE address to STDOUT + * + * @param[in] addr address to print, is expected to hold BLE_ADDR_LEN bytes + */ +void bluetil_addr_print(const uint8_t *addr); + +/** + * @brief Get a string representation of the given BLE addresses IID-based + * link local address + * + * @param[out] out '\0' terminated string, *must* be able to hold + * BLUETIL_IPV6_IID_STRLEN bytes + * @param[in] addr address to convert, , *must* hold BLE_ADDR_LEN bytes + */ +void bluetil_addr_ipv6_l2ll_sprint(char *out, const uint8_t *addr); + +/** + * @brief Dump the given BLE addresses IPv6 IID-based link local address to + * STDIO + * + * @param[in] addr generate IID for this address + */ +void bluetil_addr_ipv6_l2ll_print(const uint8_t *addr); + +#ifdef __cplusplus +} +#endif + +#endif /* NET_BLUETIL_ADDR_H */ +/** @} */ diff --git a/sys/net/ble/bluetil/bluetil_addr/Makefile b/sys/net/ble/bluetil/bluetil_addr/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/sys/net/ble/bluetil/bluetil_addr/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/net/ble/bluetil/bluetil_addr/bluetil_addr.c b/sys/net/ble/bluetil/bluetil_addr/bluetil_addr.c new file mode 100644 index 0000000000..910f4121e0 --- /dev/null +++ b/sys/net/ble/bluetil/bluetil_addr/bluetil_addr.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup ble_bluetil_addr + * @{ + * + * @file + * @brief Implementation of generic BLE address helper functions + * + * @author Hauke Petersen + * + * @} + */ + +#include +#include + +#include "fmt.h" +#include "assert.h" +#include "net/eui48.h" +#include "net/bluetil/addr.h" + +void bluetil_addr_sprint(char *out, const uint8_t *addr) +{ + assert(out); + assert(addr); + + fmt_byte_hex(out, addr[5]); + for (int i = 4; i >= 0; i--) { + out += 2; + *out++ = ':'; + fmt_byte_hex(out, addr[i]); + } + out += 2; + *out = '\0'; +} + +void bluetil_addr_print(const uint8_t *addr) +{ + assert(addr); + + char str[BLUETIL_ADDR_STRLEN]; + bluetil_addr_sprint(str, addr); + printf("%s", str); +} + +void bluetil_addr_ipv6_l2ll_sprint(char *out, const uint8_t *addr) +{ + assert(out); + assert(addr); + + eui64_t iid; + eui48_to_ipv6_iid(&iid, (const eui48_t *)addr); + memcpy(out, "[FE80::", 6); + out += 6; + for (unsigned i = 0; i < 4; i++) { + *out++ = ':'; + fmt_byte_hex(out, iid.uint8[i * 2]); + out += 2; + fmt_byte_hex(out, iid.uint8[(i * 2) + 1]); + out += 2; + } + *out++ = ']'; + *out = '\0'; +} + +void bluetil_addr_ipv6_l2ll_print(const uint8_t *addr) +{ + assert(addr); + + char tmp[BLUETIL_IPV6_IID_STRLEN]; + bluetil_addr_ipv6_l2ll_sprint(tmp, addr); + printf("%s", tmp); +} diff --git a/tests/unittests/tests-bluetil/Makefile b/tests/unittests/tests-bluetil/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/tests/unittests/tests-bluetil/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-bluetil/Makefile.include b/tests/unittests/tests-bluetil/Makefile.include new file mode 100644 index 0000000000..fd5381925f --- /dev/null +++ b/tests/unittests/tests-bluetil/Makefile.include @@ -0,0 +1 @@ +USEMODULE += bluetil_addr diff --git a/tests/unittests/tests-bluetil/tests-bluetil.c b/tests/unittests/tests-bluetil/tests-bluetil.c new file mode 100644 index 0000000000..629b870f15 --- /dev/null +++ b/tests/unittests/tests-bluetil/tests-bluetil.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include "embUnit.h" +#include "tests-bluetil.h" + +#include "net/bluetil/addr.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +const uint8_t addr[][6] = { + { 0xfe, 0xaf, 0xfe, 0xaf, 0xfe, 0xaf }, + { 0x03, 0x02, 0x01, 0xef, 0xcd, 0xab }, + { 255, 255, 255, 255, 255, 255 }, + { 0, 0, 0, 0, 0, 0 }, +}; + +static void test_bluetil_addr(void) +{ + char astr[BLUETIL_ADDR_STRLEN]; + char istr[BLUETIL_IPV6_IID_STRLEN]; + + bluetil_addr_sprint(astr, addr[0]); + TEST_ASSERT_EQUAL_STRING("AF:FE:AF:FE:AF:FE", astr); + bluetil_addr_ipv6_l2ll_sprint(istr, addr[0]); + TEST_ASSERT_EQUAL_STRING("[FE80::FCAF:FEFF:FEAF:FEAF]", istr); + + bluetil_addr_sprint(astr, addr[1]); + TEST_ASSERT_EQUAL_STRING("AB:CD:EF:01:02:03", astr); + bluetil_addr_ipv6_l2ll_sprint(istr, addr[1]); + TEST_ASSERT_EQUAL_STRING("[FE80::0102:01FF:FEEF:CDAB]", istr); + + bluetil_addr_sprint(astr, addr[2]); + TEST_ASSERT_EQUAL_STRING("FF:FF:FF:FF:FF:FF", astr); + bluetil_addr_ipv6_l2ll_sprint(istr, addr[2]); + TEST_ASSERT_EQUAL_STRING("[FE80::FDFF:FFFF:FEFF:FFFF]", istr); + + bluetil_addr_sprint(astr, addr[3]); + TEST_ASSERT_EQUAL_STRING("00:00:00:00:00:00", astr); + bluetil_addr_ipv6_l2ll_sprint(istr, addr[3]); + TEST_ASSERT_EQUAL_STRING("[FE80::0200:00FF:FE00:0000]", istr); +} + +Test *tests_bluetil_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_bluetil_addr), + }; + + EMB_UNIT_TESTCALLER(bluetil_tests, NULL, NULL, fixtures); + + return (Test *)&bluetil_tests; +} + +void tests_bluetil(void) +{ + TESTS_RUN(tests_bluetil_tests()); +} diff --git a/tests/unittests/tests-bluetil/tests-bluetil.h b/tests/unittests/tests-bluetil/tests-bluetil.h new file mode 100644 index 0000000000..e8cd57c339 --- /dev/null +++ b/tests/unittests/tests-bluetil/tests-bluetil.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the bluetil module + * + * @author Hauke Petersen + */ + +#ifndef TESTS_BLUETIL_H +#define TESTS_BLUETIL_H +#include "embUnit/embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @brief The entry point of this test suite +*/ +void tests_bluetil(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_BLUETIL_H */ +/** @} */