From ae849d6c52769c5dd3925b2d8f141d8e0dd83cb2 Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:15:11 +0200 Subject: [PATCH 1/7] Initial changes to include adv data in the sample --- include/ble_utils/ble_utils.hpp | 19 ++++++- samples/uptime/src/ble.cpp | 63 +++++++++++++++++----- samples/uptime/src/ble.hpp | 13 +++++ samples/uptime/src/main.cpp | 4 +- samples/uptime/src/uptime_service.cpp | 2 - src/ble_utils.cpp | 16 +++++- tests/renode/ble_central/src/discovery.cpp | 36 +++++-------- 7 files changed, 111 insertions(+), 42 deletions(-) diff --git a/include/ble_utils/ble_utils.hpp b/include/ble_utils/ble_utils.hpp index 37b5669..24527c9 100644 --- a/include/ble_utils/ble_utils.hpp +++ b/include/ble_utils/ble_utils.hpp @@ -1,8 +1,8 @@ /*!***************************************************************** -* Copyright 2023, Victor Chavez +* Copyright 2023-2024 Victor Chavez * SPDX-License-Identifier: Apache-2.0 * @file ble_utils.hpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * BLE C++ Utilities for development of BLE GATT applications with the Zephyr OS @@ -85,6 +85,13 @@ class Characteristic return 0; } + /** + * @brief Get the UUID of the characteristic + * + * @return const bt_uuid* Pointer to the UUID of the characteristic + */ + const bt_uuid * get_uuid(); + private: friend ICharacteristicCCC; friend Service; @@ -287,6 +294,14 @@ class Service */ int init(); + + /** + * @brief Get the UUID of the service + * + * @return const bt_uuid* Pointer to the UUID of the service + */ + const bt_uuid * get_uuid(); + private: static constexpr uint8_t MAX_ATTR = CONFIG_BLE_UTILS_MAX_ATTR; diff --git a/samples/uptime/src/ble.cpp b/samples/uptime/src/ble.cpp index cdc6f23..e0cdfc4 100644 --- a/samples/uptime/src/ble.cpp +++ b/samples/uptime/src/ble.cpp @@ -19,6 +19,21 @@ LOG_MODULE_REGISTER(ble, CONFIG_LOG_DEFAULT_LEVEL); namespace ble { +constexpr size_t MAX_SD_SIZE {5U}; +static size_t sd_cnt = 0; + +static struct bt_data sd_data[MAX_SD_SIZE] = {}; +static constexpr bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE | + BT_LE_ADV_OPT_USE_NAME, + BT_GAP_ADV_FAST_INT_MIN_2, + BT_GAP_ADV_FAST_INT_MAX_2, + NULL); + +static constexpr bt_data adv_data[] = +{ + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) +}; + static void connected(bt_conn *conn, uint8_t conn_err) { int err; @@ -57,21 +72,12 @@ BT_CONN_CB_DEFINE(conn_callbacks) = static int start_adv(void) { - static constexpr bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE | - BT_LE_ADV_OPT_USE_NAME, - BT_GAP_ADV_FAST_INT_MIN_2, - BT_GAP_ADV_FAST_INT_MAX_2, - NULL); - - static constexpr bt_data adv_data[] = - { - BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)) - }; int err = bt_le_adv_start(&adv_param, adv_data, ARRAY_SIZE(adv_data), - nullptr, - 0); + sd_data, + sd_cnt); + if (err) { LOG_ERR("Failed to create advertiser set (err %d)", err); return err; @@ -79,6 +85,39 @@ static int start_adv(void) return 0; } +bool register_svc_to_scan_rsp(const bt_uuid *uuid) +{ + uint8_t data_len; + const uint8_t * p_data; + switch(uuid->type){ + case BT_UUID_TYPE_16: + data_len = 2; + p_data = (const uint8_t *)&((bt_uuid_16 *)uuid)->val; + break; + case BT_UUID_TYPE_32: + data_len = 4; + p_data = (const uint8_t *)&((bt_uuid_32 *)uuid)->val; + break; + case BT_UUID_TYPE_128: + data_len = 16; + p_data = (const uint8_t *)&((bt_uuid_128 *)uuid)->val[0]; + break; + default: + return false; + } + + if (sd_cnt < MAX_SD_SIZE) { + bt_data data = {. + type = uuid->type, + .data_len = data_len, + .data = p_data + }; + sd_data[sd_cnt++] = data; + return true; + } + return false; +} + int init() { int err; diff --git a/samples/uptime/src/ble.hpp b/samples/uptime/src/ble.hpp index d5bfa6a..46d3e8c 100644 --- a/samples/uptime/src/ble.hpp +++ b/samples/uptime/src/ble.hpp @@ -11,6 +11,8 @@ * - language: C++17 * - OS: Zephyr v3.2.x ********************************************************************/ +#include + namespace ble { /** @@ -19,4 +21,15 @@ namespace ble * @return zephyr bluetooth error value */ int init(); + +/** + * @brief Registers a service to the scan response message + * when advertising. + * + * @param uuid The 128 bit uuid of the service. + * @return true on success. + * @return false when the maximum number of configurable services is reached. + */ +bool register_svc_to_scan_rsp(const bt_uuid *uuid); + } // namespace ble diff --git a/samples/uptime/src/main.cpp b/samples/uptime/src/main.cpp index 99c9e4a..411ef0c 100644 --- a/samples/uptime/src/main.cpp +++ b/samples/uptime/src/main.cpp @@ -24,9 +24,9 @@ int main(void) { LOG_INF("Starting Uptime BLE Utils sample"); uptime_service.init(); + ble::register_svc_to_scan_rsp(uptime_service.get_uuid()); ble::init(); - for (;;) - { + for (;;) { const uint32_t uptime_ms = k_uptime_get_32(); uptime_service.update(uptime_ms/1000U); k_sleep(K_MSEC(1000)); diff --git a/samples/uptime/src/uptime_service.cpp b/samples/uptime/src/uptime_service.cpp index 941d674..eab680b 100644 --- a/samples/uptime/src/uptime_service.cpp +++ b/samples/uptime/src/uptime_service.cpp @@ -19,8 +19,6 @@ LOG_MODULE_REGISTER(uptime_svc, CONFIG_LOG_DEFAULT_LEVEL); namespace uptime { - - namespace characteristic { diff --git a/src/ble_utils.cpp b/src/ble_utils.cpp index cba26fa..7b3790e 100644 --- a/src/ble_utils.cpp +++ b/src/ble_utils.cpp @@ -52,6 +52,14 @@ Characteristic::Characteristic(const bt_uuid * uuid, uint8_t props, uint8_t perm m_ccc_enable(ccc_enable) { } + + + +const bt_uuid * Characteristic::get_uuid() +{ + return m_attr_value.uuid; +} + ssize_t Characteristic::_read_cb(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, @@ -113,12 +121,18 @@ void Service::register_char(const Characteristic * chrc) attrs[m_gatt_service.attr_count++] = char_ccc->m_ccc_attr; } } + int Service::init() { const int res = bt_gatt_service_register(&m_gatt_service); return res; } +const bt_uuid * Service::get_uuid() +{ + return static_cast(m_gatt_service.attrs[0].user_data); +} + /** * @brief Constructor that defines a BLE Characteristic CCC * @details The member list initializer gives an insight on how zephyr OS Requires @@ -149,8 +163,8 @@ ICharacteristicCCC::ICharacteristicCCC(const bt_uuid * uuid, uint8_t props, uint } ) { - } + ICharacteristicCCC::~ICharacteristicCCC() {} void ICharacteristicCCC::_ccc_changed(const bt_gatt_attr *attr, uint16_t value) diff --git a/tests/renode/ble_central/src/discovery.cpp b/tests/renode/ble_central/src/discovery.cpp index 6752e87..7e1dad2 100644 --- a/tests/renode/ble_central/src/discovery.cpp +++ b/tests/renode/ble_central/src/discovery.cpp @@ -148,26 +148,6 @@ static bool adv_data_cb(bt_data *data, void *user_data) { auto addr = static_cast(user_data); LOG_INF("Adv data type %u len %u", data->type, data->data_len); - int err = bt_le_scan_stop(); - if (err) { - LOG_INF("Stop LE scan failed (err %d)", err); - return false; - } - - LOG_INF("Connecting.."); - err = bt_conn_le_create(addr, &conn_create_param, - &conn_default_param, &default_conn); - if (err) { - LOG_ERR("Create conn failed (err %d)", err); - start_scan(); - } - return true; - - /* - TODO wait for upcoming changes with uuid advertisement - until then do not compare uuid in adv data - */ - /* switch (data->type) { case BT_DATA_UUID128_SOME: case BT_DATA_UUID128_ALL: @@ -185,13 +165,23 @@ static bool adv_data_cb(bt_data *data, void *user_data) continue; } LOG_INF("Matched Uptime adv. UUID"); - + err = bt_le_scan_stop(); + if (err) { + LOG_INF("Stop LE scan failed (err %d)", err); + return false; + } + + LOG_INF("Connecting.."); + err = bt_conn_le_create(addr, &conn_create_param, + &conn_default_param, &default_conn); + if (err) { + LOG_ERR("Create conn failed (err %d)", err); + start_scan(); + } return false; } } - return true; - */ } static void device_found_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, From 8fa0fd673a97e2bb8b15dd894c0b5b98dc56650b Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:16:40 +0200 Subject: [PATCH 2/7] add posix build for testing with android emulator --- .github/workflows/build_test.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 76a0a1d..7a5e58a 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -35,12 +35,19 @@ jobs: run: | west build $GITHUB_WORKSPACE/tests/renode/ble_central -b $BOARD --build-dir $GITHUB_WORKSPACE/tests/renode/ble_central/build + + - name: Build Posix + working-directory: /tmp/ + run: | + west build $GITHUB_WORKSPACE/samples/uptime -b $BOARD --build-dir $GITHUB_WORKSPACE/samples/uptime/build_posix + - name : Upload Firmware uses: actions/upload-artifact@v4 with: name: zephyr-build path: | samples/uptime/build/zephyr/zephyr.elf + samples/uptime/build_posix/zephyr/zephyr.exe tests/renode/ble_central/build/zephyr/zephyr.elf test: From 0632fd986aa02b66f3cadad9e3932162e40f1cff Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:26:56 +0200 Subject: [PATCH 3/7] added correct board for posix build and separate file for conf --- .github/workflows/build_test.yml | 3 +-- samples/boards/native_posix_64.conf | 3 +++ samples/uptime/prj.conf | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 samples/boards/native_posix_64.conf diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 7a5e58a..64a6303 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -35,11 +35,10 @@ jobs: run: | west build $GITHUB_WORKSPACE/tests/renode/ble_central -b $BOARD --build-dir $GITHUB_WORKSPACE/tests/renode/ble_central/build - - name: Build Posix working-directory: /tmp/ run: | - west build $GITHUB_WORKSPACE/samples/uptime -b $BOARD --build-dir $GITHUB_WORKSPACE/samples/uptime/build_posix + west build $GITHUB_WORKSPACE/samples/uptime -b native_posix_64 --build-dir $GITHUB_WORKSPACE/samples/uptime/build_posix - name : Upload Firmware uses: actions/upload-artifact@v4 diff --git a/samples/boards/native_posix_64.conf b/samples/boards/native_posix_64.conf new file mode 100644 index 0000000..ce5e102 --- /dev/null +++ b/samples/boards/native_posix_64.conf @@ -0,0 +1,3 @@ +# Disable HCI ACL for use with Android Emulator +# Refer to https://github.com/google/bumble/issues/220#issuecomment-1651200456 +CONFIG_BT_HCI_ACL_FLOW_CONTROL=n \ No newline at end of file diff --git a/samples/uptime/prj.conf b/samples/uptime/prj.conf index 855b6f4..8d9b5ee 100644 --- a/samples/uptime/prj.conf +++ b/samples/uptime/prj.conf @@ -15,5 +15,4 @@ CONFIG_STD_CPP17=y CONFIG_NEWLIB_LIBC=y CONFIG_BLE_UTILS=y CONFIG_BT_ASSERT=n -CONFIG_LOG=y -CONFIG_BT_HCI_ACL_FLOW_CONTROL=n +CONFIG_LOG=y \ No newline at end of file From 073ad17de767764905601f9b245cf3f4dee24eae Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:32:30 +0200 Subject: [PATCH 4/7] Enable extended advertisement --- samples/uptime/prj.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/uptime/prj.conf b/samples/uptime/prj.conf index 8d9b5ee..fea6d49 100644 --- a/samples/uptime/prj.conf +++ b/samples/uptime/prj.conf @@ -15,4 +15,5 @@ CONFIG_STD_CPP17=y CONFIG_NEWLIB_LIBC=y CONFIG_BLE_UTILS=y CONFIG_BT_ASSERT=n -CONFIG_LOG=y \ No newline at end of file +CONFIG_LOG=y +CONFIG_BT_EXT_ADV=y \ No newline at end of file From 5f3296d56da52a122f0553dd58007059abc9db75 Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:42:38 +0200 Subject: [PATCH 5/7] added CONFIG_BT_HCI_ACL_FLOW_CONTROL=n to sample proj --- samples/uptime/prj.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/uptime/prj.conf b/samples/uptime/prj.conf index fea6d49..6294cf8 100644 --- a/samples/uptime/prj.conf +++ b/samples/uptime/prj.conf @@ -16,4 +16,5 @@ CONFIG_NEWLIB_LIBC=y CONFIG_BLE_UTILS=y CONFIG_BT_ASSERT=n CONFIG_LOG=y -CONFIG_BT_EXT_ADV=y \ No newline at end of file +CONFIG_BT_EXT_ADV=y +CONFIG_BT_HCI_ACL_FLOW_CONTROL=n \ No newline at end of file From 9025c432b862a4881431727bde37aecde68143d3 Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:53:52 +0200 Subject: [PATCH 6/7] Fix adv data types Updated test to check that adv data is sent correctly --- include/ble_utils/uuid.hpp | 2 +- samples/uptime/src/ble.cpp | 6 +++++- tests/renode/ble_central/src/discovery.cpp | 4 ++-- tests/renode/uptime_test.robot | 7 +++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/ble_utils/uuid.hpp b/include/ble_utils/uuid.hpp index 410af4d..25910e2 100644 --- a/include/ble_utils/uuid.hpp +++ b/include/ble_utils/uuid.hpp @@ -67,7 +67,7 @@ static constexpr bt_uuid_128 uuid128_init(uint32_t w32,uint16_t w1,uint16_t w2,u const uint8_t b15 = static_cast(w32 >> 24 & 0xFF); bt_uuid_128 uuid { - .uuid = BT_UUID_TYPE_128, + .uuid = {.type = BT_UUID_TYPE_128}, .val = {b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15} }; return uuid; diff --git a/samples/uptime/src/ble.cpp b/samples/uptime/src/ble.cpp index e0cdfc4..c82642b 100644 --- a/samples/uptime/src/ble.cpp +++ b/samples/uptime/src/ble.cpp @@ -89,17 +89,21 @@ bool register_svc_to_scan_rsp(const bt_uuid *uuid) { uint8_t data_len; const uint8_t * p_data; + uint8_t adv_type; switch(uuid->type){ case BT_UUID_TYPE_16: data_len = 2; + adv_type = BT_DATA_UUID16_SOME; p_data = (const uint8_t *)&((bt_uuid_16 *)uuid)->val; break; case BT_UUID_TYPE_32: data_len = 4; + adv_type = BT_DATA_UUID32_SOME; p_data = (const uint8_t *)&((bt_uuid_32 *)uuid)->val; break; case BT_UUID_TYPE_128: data_len = 16; + adv_type = BT_DATA_UUID128_SOME; p_data = (const uint8_t *)&((bt_uuid_128 *)uuid)->val[0]; break; default: @@ -108,7 +112,7 @@ bool register_svc_to_scan_rsp(const bt_uuid *uuid) if (sd_cnt < MAX_SD_SIZE) { bt_data data = {. - type = uuid->type, + type = adv_type, .data_len = data_len, .data = p_data }; diff --git a/tests/renode/ble_central/src/discovery.cpp b/tests/renode/ble_central/src/discovery.cpp index 7e1dad2..de41d98 100644 --- a/tests/renode/ble_central/src/discovery.cpp +++ b/tests/renode/ble_central/src/discovery.cpp @@ -193,9 +193,9 @@ static void device_found_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, //LOG_INF("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i", // dev, type, ad->len, rssi); - /* We're only interested in connectable events */ if (type == BT_GAP_ADV_TYPE_ADV_IND || - type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { + type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND || + type == BT_GAP_ADV_TYPE_SCAN_RSP) { bt_data_parse(ad, adv_data_cb, (void *)addr); } } diff --git a/tests/renode/uptime_test.robot b/tests/renode/uptime_test.robot index c958b60..b07c1f3 100644 --- a/tests/renode/uptime_test.robot +++ b/tests/renode/uptime_test.robot @@ -1,5 +1,7 @@ -*** Copyright (c) 2024, Victor Chavez *** -*** SPDX-License-Identifier: Apache-2.0 *** +*** Comments *** +Copyright (c) 2024, Victor Chavez +SPDX-License-Identifier: Apache-2.0 + *** Variables *** ${UART} sysbus.uart0 @@ -51,6 +53,7 @@ Uptime Demo Wait For Line On Uart Booting Zephyr testerId=${per_uart} Wait For Line On Uart Scanning successfully started testerId=${cen_uart} Wait For Line On Uart Bluetooth initialized testerId=${per_uart} + Wait For Line On Uart Matched Uptime adv. UUID testerId=${cen_uart} Wait For Line On Uart Connected testerId=${per_uart} Wait For Line On Uart Connected testerId=${cen_uart} Wait For Line On Uart Service found testerId=${cen_uart} From bd0329f1771c2ac957ebe37bb0322366e24f9466 Mon Sep 17 00:00:00 2001 From: Victor Chavez Date: Sat, 13 Apr 2024 17:57:45 +0200 Subject: [PATCH 7/7] fixed sample overlay for native posix and pipeline build --- .github/workflows/build_test.yml | 6 +++++- samples/uptime/prj.conf | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 64a6303..ab21ecb 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -15,6 +15,7 @@ jobs: env: CMAKE_PREFIX_PATH: /opt/toolchains ZEPHYR_VERSION: 3.6.0 + # Board to use with renode BOARD: nrf52840dk_nrf52840 steps: - name: Checkout @@ -25,20 +26,23 @@ jobs: west init --mr v$ZEPHYR_VERSION west update -o=--depth=1 -n + # Sample as DUT for testing with Renode - name: Build Uptime Sample working-directory: /tmp/ run: | west build $GITHUB_WORKSPACE/samples/uptime -b $BOARD --build-dir $GITHUB_WORKSPACE/samples/uptime/build + # BLE Central for testing with Renode - name: Build Central working-directory: /tmp/ run: | west build $GITHUB_WORKSPACE/tests/renode/ble_central -b $BOARD --build-dir $GITHUB_WORKSPACE/tests/renode/ble_central/build + # Posix build for debugging with bluetooth virtual controller - name: Build Posix working-directory: /tmp/ run: | - west build $GITHUB_WORKSPACE/samples/uptime -b native_posix_64 --build-dir $GITHUB_WORKSPACE/samples/uptime/build_posix + west build $GITHUB_WORKSPACE/samples/uptime -b native_posix_64 --build-dir $GITHUB_WORKSPACE/samples/uptime/build_posix -- -DOVERLAY_CONFIG=$GITHUB_WORKSPACE/samples/uptime/boards/native_posix_64.conf - name : Upload Firmware uses: actions/upload-artifact@v4 diff --git a/samples/uptime/prj.conf b/samples/uptime/prj.conf index 6294cf8..fea6d49 100644 --- a/samples/uptime/prj.conf +++ b/samples/uptime/prj.conf @@ -16,5 +16,4 @@ CONFIG_NEWLIB_LIBC=y CONFIG_BLE_UTILS=y CONFIG_BT_ASSERT=n CONFIG_LOG=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_HCI_ACL_FLOW_CONTROL=n \ No newline at end of file +CONFIG_BT_EXT_ADV=y \ No newline at end of file