diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml new file mode 100644 index 0000000..76a0a1d --- /dev/null +++ b/.github/workflows/build_test.yml @@ -0,0 +1,78 @@ +# Copyright (c) 2024, Victor Chavez (vchavezb@protonmail.com) +# SPDX-License-Identifier: Apache-2.0 + +name: Build + +on: + push: + pull_request: + +jobs: + + build: + runs-on: ubuntu-22.04 + container: ghcr.io/zephyrproject-rtos/ci:v0.26.2 + env: + CMAKE_PREFIX_PATH: /opt/toolchains + ZEPHYR_VERSION: 3.6.0 + BOARD: nrf52840dk_nrf52840 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Initialize + run: | + cd /tmp/ + west init --mr v$ZEPHYR_VERSION + west update -o=--depth=1 -n + + - name: Build Uptime Sample + working-directory: /tmp/ + run: | + west build $GITHUB_WORKSPACE/samples/uptime -b $BOARD --build-dir $GITHUB_WORKSPACE/samples/uptime/build + + - 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 + + - name : Upload Firmware + uses: actions/upload-artifact@v4 + with: + name: zephyr-build + path: | + samples/uptime/build/zephyr/zephyr.elf + tests/renode/ble_central/build/zephyr/zephyr.elf + + test: + needs: build + runs-on: ubuntu-20.04 + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Download zephyr binaries + uses: actions/download-artifact@v4 + with: + name: zephyr-build + + - name: Run tests on latest Renode + uses: antmicro/renode-test-action@v3.0.0 + with: + renode-version: '1.13.3' + tests-to-run: 'tests/renode/uptime_test.robot' + renode-path: renode-1.13 + artifacts-path: ${{ github.workspace }} + + + - name: Archive latest results + uses: actions/upload-artifact@v4 + if: failure() + with: + name: test-results-latest + path: | + report.html + log.html + robot_output.xml + + + diff --git a/.gitignore b/.gitignore index 1b2211d..d761534 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,8 @@ build* +*.pyc +*.idea +*/.vscode/* +tests/renode/logs/* +tests/renode/*.html +tests/renode/*.xml +tests/renode/snapshots diff --git a/README.md b/README.md index 1d41132..68c7909 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,33 @@ The definition of BLE services and characteristics can be done at compile time A demo is located in the samples folder. This demo can be used as a reference on how to use this module. +# Tests + +Some basic tests are done with [Renode](https://renode.readthedocs.io/en/latest/) to simulate the correct setup of the BLE Services and characteristics. + +## Requirements + +- Renode v1.13.3 +- Robot framework + +## Robot + +To run the unit test suite with robot execute: + +```bash +renode-test -t tests/renode/uptime_test.robot +``` + +## Debug + +If you want to manually debug the tests instead load the Renode script + +```bash +renode tests/renode/uptime.resc +``` + + ## Contact -Contact for issues, contributions as git patches or general information at chavez-bermudez@fh-aachen.de +Contact for issues, contributions as git patches or general information at vchavezb(at)protonmail.com diff --git a/samples/uptime/prj.conf b/samples/uptime/prj.conf index 2b4aea7..855b6f4 100644 --- a/samples/uptime/prj.conf +++ b/samples/uptime/prj.conf @@ -1,5 +1,5 @@ # -# Copyright 2023, Victor Chavez +# Copyright 2024, Victor Chavez # # SPDX-License-Identifier: Apache-2.0 # @@ -14,3 +14,6 @@ CONFIG_LIB_CPLUSPLUS=y 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 diff --git a/samples/uptime/src/ble.cpp b/samples/uptime/src/ble.cpp index 53c1345..cdc6f23 100644 --- a/samples/uptime/src/ble.cpp +++ b/samples/uptime/src/ble.cpp @@ -1,8 +1,8 @@ /*!***************************************************************** -* Copyright 2023, Victor Chavez +* Copyright 2023-2024, Victor Chavez * SPDX-License-Identifier: Apache-2.0 -* @file ble.cpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) +* @file main.cpp +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * BLE connection implementation for uptime service demo @@ -12,7 +12,9 @@ * - OS: Zephyr v3.2.x ********************************************************************/ #include +#include #include "ble.hpp" +LOG_MODULE_REGISTER(ble, CONFIG_LOG_DEFAULT_LEVEL); namespace ble { @@ -27,24 +29,24 @@ static void connected(bt_conn *conn, uint8_t conn_err) if (conn_err) { - printk("Connection failed (err %d)\n", conn_err); + LOG_INF("Connection failed (err %d)", conn_err); return; } err = bt_conn_get_info(conn, &info); if (err) { - printk("Failed to get connection info (err %d)\n", err); + LOG_ERR("Failed to get connection info (err %d)", err); } else { - printk("Connected: %s\n", addr); + LOG_INF("Connected: %s\n", addr); } } static void disconnected(struct bt_conn *conn, uint8_t reason) { - printk("Disconnected (reason 0x%02x)\n", reason); + LOG_INF("Disconnected (reason 0x%02x)", reason); } BT_CONN_CB_DEFINE(conn_callbacks) = @@ -71,7 +73,7 @@ static int start_adv(void) nullptr, 0); if (err) { - printk("Failed to create advertiser set (err %d)\n", err); + LOG_ERR("Failed to create advertiser set (err %d)", err); return err; } return 0; @@ -85,15 +87,15 @@ int init() err = bt_enable(NULL); if (err) { - printk("Bluetooth init failed (err %d)\n", err); + LOG_ERR("Bluetooth init failed (err %d)", err); break; } - printk("Bluetooth initialized\n"); + LOG_INF("Bluetooth initialized\n"); err = start_adv(); if (err) { - printk("Advertising failed to create (err %d)\n", err); + LOG_ERR("Advertising failed to create (err %d)", err); break; } }while(0); diff --git a/samples/uptime/src/ble.hpp b/samples/uptime/src/ble.hpp index 0b6a7ac..d5bfa6a 100644 --- a/samples/uptime/src/ble.hpp +++ b/samples/uptime/src/ble.hpp @@ -1,8 +1,8 @@ /*!***************************************************************** * Copyright 2023, Victor Chavez * SPDX-License-Identifier: Apache-2.0 -* @file ble.hpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) +* @file main.cpp +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * BLE connection functions for uptime service demo diff --git a/samples/uptime/src/main.cpp b/samples/uptime/src/main.cpp index a44db50..99c9e4a 100644 --- a/samples/uptime/src/main.cpp +++ b/samples/uptime/src/main.cpp @@ -1,8 +1,8 @@ /*!***************************************************************** -* Copyright 2023, Victor Chavez +* Copyright 2023-2024, Victor Chavez * SPDX-License-Identifier: Apache-2.0 * @file main.cpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * Main source file that implements an uptime service demo for the BLE utils module @@ -14,18 +14,20 @@ #include "ble.hpp" #include +#include #include "uptime_service.hpp" +LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL); uptime::Service uptime_service; int main(void) { - printk("Starting Uptime BLE Utils sample\n"); + LOG_INF("Starting Uptime BLE Utils sample"); uptime_service.init(); ble::init(); for (;;) { - const uint32_t uptime_ms = k_uptime_get_32(); + 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 336cdee..941d674 100644 --- a/samples/uptime/src/uptime_service.cpp +++ b/samples/uptime/src/uptime_service.cpp @@ -1,9 +1,8 @@ /*!***************************************************************** -* Copyright 2023, Victor Chavez +* Copyright 2023-2024, Victor Chavez * SPDX-License-Identifier: Apache-2.0 -* @file uptime_service.cpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) -* @date 13.03.2023 +* @file main.cpp +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * BLE Service implementation @@ -12,24 +11,15 @@ * - language: C++17 * - OS: Zephyr v3.2.x ********************************************************************/ - +#include #include "uptime_service.hpp" +LOG_MODULE_REGISTER(uptime_svc, CONFIG_LOG_DEFAULT_LEVEL); + namespace uptime { -namespace uuid -{ - static constexpr bt_uuid_128 svc_base = ble_utils::uuid::uuid128_init(0xABCD0000, - 0x1234, - 0x5678, - 0x9ABC, - 0xDEF012345678); - - static constexpr bt_uuid_128 char_basic = ble_utils::uuid::derive_uuid(svc_base,0x0001); - static constexpr bt_uuid_128 char_notify = ble_utils::uuid::derive_uuid(svc_base,0x0002); - static constexpr bt_uuid_128 char_indicate = ble_utils::uuid::derive_uuid(svc_base,0x0003); -} + namespace characteristic { @@ -61,19 +51,35 @@ Notify::Notify(): { } +void Notify::ccc_changed(CCCValue_e value) +{ + int val = static_cast(value); + LOG_INF("Characteristic Notify Uptime CCC changed %d\n",val); +} + Indicate::Indicate(): ble_utils::gatt::CharacteristicIndicate((const bt_uuid*)&uuid::char_indicate) { } +void Indicate::ccc_changed(CCCValue_e value) +{ + int val = static_cast(value); + LOG_INF("Characteristic Indicate Uptime CCC changed %d\n",val); +} +void Indicate::indicate_rsp() +{ + LOG_INF("Characteristic Indicate Uptime Completed\n"); +} + } // namespace characteristic Service::Service(): ble_utils::gatt::Service((const bt_uuid*)&uuid::svc_base) { register_char(&m_basic); - register_char(&m_notify); register_char(&m_indicate); + register_char(&m_notify); } void Service::update(uint32_t uptime) diff --git a/samples/uptime/src/uptime_service.hpp b/samples/uptime/src/uptime_service.hpp index eb914e1..d8fb254 100644 --- a/samples/uptime/src/uptime_service.hpp +++ b/samples/uptime/src/uptime_service.hpp @@ -1,8 +1,8 @@ /*!***************************************************************** -* Copyright 2023, Victor Chavez +* Copyright 2023-2024, Victor Chavez * SPDX-License-Identifier: Apache-2.0 -* @file uptime_service.hpp -* @author Victor Chavez (chavez-bermudez@fh-aachen.de) +* @file main.cpp +* @author Victor Chavez (vchavezb@protonmail.com) * * @brief * Uptime BLE Service that uses the BLE Utils module @@ -16,9 +16,23 @@ #include #include + namespace uptime { +namespace uuid +{ + static constexpr bt_uuid_128 svc_base = ble_utils::uuid::uuid128_init(0xABCD0000, + 0x1234, + 0x5678, + 0x9ABC, + 0xDEF012345678); + + static constexpr bt_uuid_128 char_basic = ble_utils::uuid::derive_uuid(svc_base,0x0001); + static constexpr bt_uuid_128 char_notify = ble_utils::uuid::derive_uuid(svc_base,0x0002); + static constexpr bt_uuid_128 char_indicate = ble_utils::uuid::derive_uuid(svc_base,0x0003); +} + namespace characteristic { @@ -37,11 +51,7 @@ class Notify final: public ble_utils::gatt::CharacteristicNotify public: Notify(); private: - void ccc_changed(CCCValue_e value) override - { - int val = static_cast(value); - printk("Characteristic Notify Uptime CCC changed %d\n",val); - } + void ccc_changed(CCCValue_e value) override; }; class Indicate final: public ble_utils::gatt::CharacteristicIndicate @@ -49,16 +59,8 @@ class Indicate final: public ble_utils::gatt::CharacteristicIndicate public: Indicate(); private: - void ccc_changed(CCCValue_e value) override - { - int val = static_cast(value); - printk("Characteristic Indicate Uptime CCC changed %d\n",val); - } - void indicate_rsp() override - { - printk("Characteristic Indicate Uptime Completed\n"); - } - + void ccc_changed(CCCValue_e value) override; + void indicate_rsp(); }; } diff --git a/tests/renode/ble_central/CMakeLists.txt b/tests/renode/ble_central/CMakeLists.txt new file mode 100644 index 0000000..b24a962 --- /dev/null +++ b/tests/renode/ble_central/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Victor Chavez +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..) +# Root dir contains Ble utils +set(ZEPHYR_EXTRA_MODULES ${ROOT_DIR}) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(tester_ble_central) + +target_sources(app PRIVATE src/main.cpp + src/discovery.cpp) + +target_include_directories(app PRIVATE ${ROOT_DIR}/samples/uptime/src + ${ROOT_DIR}/include) \ No newline at end of file diff --git a/tests/renode/ble_central/prj.conf b/tests/renode/ble_central/prj.conf new file mode 100644 index 0000000..6203941 --- /dev/null +++ b/tests/renode/ble_central/prj.conf @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Victor Chavez +# SPDX-License-Identifier: Apache-2.0 +#--------- +#C++ +#---------- +CONFIG_CPLUSPLUS=y +CONFIG_LIB_CPLUSPLUS=y +CONFIG_STD_CPP17=y +CONFIG_NEWLIB_LIBC=y +CONFIG_UART_CONSOLE=y +CONFIG_BLE_UTILS=y +CONFIG_CBPRINTF_FP_SUPPORT=y +CONFIG_BT_ASSERT=n + +CONFIG_BT=y +CONFIG_LOG=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_SMP=y +CONFIG_BT_GATT_CLIENT=y diff --git a/tests/renode/ble_central/src/discovery.cpp b/tests/renode/ble_central/src/discovery.cpp new file mode 100644 index 0000000..6752e87 --- /dev/null +++ b/tests/renode/ble_central/src/discovery.cpp @@ -0,0 +1,297 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "discovery.hpp" +#include "uptime_service.hpp" + +LOG_MODULE_REGISTER(central, CONFIG_LOG_DEFAULT_LEVEL); + + +namespace discovery { + +static bt_conn *default_conn; +static bool device_found; +static uint8_t device_char_cnt; + + +static bt_gatt_discover_params discover_params; +static bt_gatt_subscribe_params subscribe_params; + +static constexpr bt_le_conn_param conn_default_param = +{ + .interval_min = 0x18, + .interval_max= 0x28, + .latency = 0, + .timeout= 400 +}; + +static constexpr bt_conn_le_create_param conn_create_param = +{ + .options=BT_CONN_LE_OPT_NONE, + .interval=BT_GAP_SCAN_FAST_INTERVAL, /* scan fast interval 60 ms */ + .window=BT_GAP_SCAN_FAST_INTERVAL, /* scan fast interval 60 ms */ + .interval_coded=0, + .window_coded=0, + .timeout=0 +}; + +static constexpr uint8_t TOTAL_CHARACTERISTICS = 3; +static const bt_uuid * uptime_characteristics [TOTAL_CHARACTERISTICS] = +{ + &uptime::uuid::char_basic.uuid, + &uptime::uuid::char_indicate.uuid, + &uptime::uuid::char_notify.uuid +}; + +static uint8_t uptime_notify_cb(bt_conn *conn, + bt_gatt_subscribe_params *params, + const void *data, uint16_t length) +{ + if (conn == NULL) { + return BT_GATT_ITER_CONTINUE; + } + + if (!data) { + LOG_INF("Unsubscribed"); + params->value_handle = 0U; + return BT_GATT_ITER_CONTINUE; + } + + if(length != sizeof(uint32_t)) { + LOG_ERR("Uptime data len %d does not match expected len %d", length,sizeof(uint32_t)); + return BT_GATT_ITER_STOP; + } + const uint32_t uptime = sys_get_le32((uint8_t*)(data)); + LOG_INF("Notification Uptime value %d", uptime); + return BT_GATT_ITER_CONTINUE; +} + +static int discover_characteristics(bt_conn *conn, + const bt_gatt_attr *attr, + uint8_t idx) +{ + discover_params.uuid = uptime_characteristics[idx]; + discover_params.start_handle = attr->handle + 1; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + /* Discover the characteristics */ + int err = bt_gatt_discover(conn, &discover_params); + if (err) { + LOG_DBG("Char. %d discover failed (err %d)\n",idx,err); + return err; + } + return 0; +} + + +static uint8_t service_discover_cb(bt_conn *conn, + const bt_gatt_attr *attr, + bt_gatt_discover_params *params) +{ + if (!attr) { + (void)memset(params, 0, sizeof(*params)); + if (!device_found) { + LOG_ERR("BLE peripheral not found"); + } else { + LOG_INF("BLE peripheral found"); + device_found = false; + } + device_char_cnt = 0; + return BT_GATT_ITER_STOP; + } + const bool svc_found = bt_uuid_cmp(params->uuid, &uptime::uuid::svc_base.uuid) == 0; + const bool char_found = bt_uuid_cmp(params->uuid, + uptime_characteristics[device_char_cnt])== 0; + if (svc_found) { + LOG_INF("Service found"); + device_char_cnt = 0; + discover_characteristics(conn, attr, device_char_cnt); + } else if(char_found) { + LOG_INF("Chrc %d/%d found",device_char_cnt+1,TOTAL_CHARACTERISTICS); + if (bt_uuid_cmp(params->uuid, + &uptime::uuid::char_notify.uuid) == 0) { + // Subscribe to uptime notification + subscribe_params.notify = uptime_notify_cb; + subscribe_params.value = BT_GATT_CCC_NOTIFY; + subscribe_params.ccc_handle = attr->handle+2; + subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); + const int err = bt_gatt_subscribe(conn, &subscribe_params); + if (err != 0 && err != -EALREADY) { + LOG_ERR("Subscribe failed (err %d)", err); + } else { + LOG_INF("Subscribed"); + } + return BT_GATT_ITER_STOP; + } + if (device_char_cnt == TOTAL_CHARACTERISTICS-1) { + device_found = true; + } else if (device_char_cnt < TOTAL_CHARACTERISTICS) { + device_char_cnt++; + discover_characteristics(conn, attr, device_char_cnt); + } + } + return BT_GATT_ITER_STOP; +} + + + +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: + if (data->data_len % BT_UUID_SIZE_128 != 0U) { + LOG_INF("AD malformed"); + return true; + } + for (int i = 0; i < data->data_len; i += BT_UUID_SIZE_128) { + int err; + + bt_uuid_128 adv_uuid ={ .uuid = { BT_UUID_TYPE_128 }}; + memcpy(adv_uuid.val, data->data+i, BT_UUID_SIZE_128); + const int uuid_match = bt_uuid_cmp(&adv_uuid.uuid, &uptime::uuid::svc_base.uuid); + if (uuid_match != 0) { + continue; + } + LOG_INF("Matched Uptime adv. UUID"); + + return false; + } + } + + return true; + */ +} + +static void device_found_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + net_buf_simple *ad) +{ + char dev[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(addr, dev, sizeof(dev)); + //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) { + bt_data_parse(ad, adv_data_cb, (void *)addr); + } +} + +int start_scan() +{ + int err; + + /* Use active scanning and disable duplicate filtering to handle any + * devices that might update their advertising data at runtime. */ + bt_le_scan_param scan_param = { + .type = BT_LE_SCAN_TYPE_ACTIVE, + .options = BT_LE_SCAN_OPT_NONE, + .interval = BT_GAP_SCAN_FAST_INTERVAL, + .window = BT_GAP_SCAN_FAST_WINDOW, + }; + + err = bt_le_scan_start(&scan_param, device_found_cb); + if (err) { + LOG_ERR("Scanning failed to start (err %d)", err); + return err; + } + + LOG_INF("Scanning successfully started"); + return err; +} + +static void find_main_service() +{ + discover_params.uuid = &uptime::uuid::svc_base.uuid; + discover_params.func = service_discover_cb; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_PRIMARY; + + int err = bt_gatt_discover(default_conn, &discover_params); + if (err) { + LOG_INF("Service discover failed (err %d)", err); + } +} + + +static void connected(bt_conn *conn, uint8_t conn_err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (conn_err) { + LOG_INF("Failed to connect to %s (%u)", addr, conn_err); + + bt_conn_unref(default_conn); + default_conn = NULL; + + start_scan(); + return; + } + + LOG_INF("Connected: %s", addr); + + if (conn == default_conn) { + find_main_service(); + } +} + +static void disconnected(bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + LOG_INF("Disconnected: %s (reason 0x%02x)", addr, reason); + + if (default_conn != conn) { + return; + } + + bt_conn_unref(default_conn); + default_conn = NULL; + + start_scan(); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +} \ No newline at end of file diff --git a/tests/renode/ble_central/src/discovery.hpp b/tests/renode/ble_central/src/discovery.hpp new file mode 100644 index 0000000..3ba1a59 --- /dev/null +++ b/tests/renode/ble_central/src/discovery.hpp @@ -0,0 +1,13 @@ +/* + Copyright (c) 2024 Victor Chavez + SPDX-License-Identifier: Apache-2.0 +*/ + +#pragma once + +namespace discovery { + +int start_scan(); + + +} \ No newline at end of file diff --git a/tests/renode/ble_central/src/main.cpp b/tests/renode/ble_central/src/main.cpp new file mode 100644 index 0000000..997f113 --- /dev/null +++ b/tests/renode/ble_central/src/main.cpp @@ -0,0 +1,26 @@ +/* + Copyright (c) 2024 Victor Chavez + SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include +#include +#include "discovery.hpp" + +LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL); + +int main() +{ + int rc = bt_enable(nullptr); + if (rc != 0) { + LOG_ERR("bt_enable failed,err %d",rc); + return rc; + } + rc = discovery::start_scan(); + if (rc != 0) { + LOG_ERR("Error starting scan,err %d",rc); + return rc; + } + return 0; +} diff --git a/tests/renode/tests.yaml b/tests/renode/tests.yaml new file mode 100644 index 0000000..e74ecd4 --- /dev/null +++ b/tests/renode/tests.yaml @@ -0,0 +1,4 @@ +# Copyright (c) 2024, Victor Chavez (vchavezb@protonmail.com) +# SPDX-License-Identifier: Apache-2.0 + +- uptime_test.robot \ No newline at end of file diff --git a/tests/renode/uptime.resc b/tests/renode/uptime.resc new file mode 100644 index 0000000..e415037 --- /dev/null +++ b/tests/renode/uptime.resc @@ -0,0 +1,25 @@ +using sysbus + +emulation CreateBLEMedium "wireless" + + +mach add "central" +machine LoadPlatformDescription @platforms/cpus/nrf52840.repl +connector Connect sysbus.radio wireless +showAnalyzer uart0 + +mach create "peripheral" +machine LoadPlatformDescription @platforms/cpus/nrf52840.repl +connector Connect sysbus.radio wireless +showAnalyzer uart0 + +emulation SetGlobalQuantum "0.00001" + + +mach set "central" +sysbus LoadELF $ORIGIN/ble_central/build/zephyr/zephyr.elf + +mach set "peripheral" +sysbus LoadELF $ORIGIN/../../samples/uptime/build/zephyr/zephyr.elf + +start \ No newline at end of file diff --git a/tests/renode/uptime_test.robot b/tests/renode/uptime_test.robot new file mode 100644 index 0000000..c958b60 --- /dev/null +++ b/tests/renode/uptime_test.robot @@ -0,0 +1,62 @@ +*** Copyright (c) 2024, Victor Chavez *** +*** SPDX-License-Identifier: Apache-2.0 *** +*** Variables *** +${UART} sysbus.uart0 + +*** Keywords *** +Create Machine + [Arguments] ${elf} + + Execute Command mach create + Execute Command machine LoadPlatformDescription @platforms/cpus/nrf52840.rep + Execute Command sysbus LoadELF ${elf} + Execute Command connector Connect sysbus.radio wireless + Execute Command showAnalyzer sysbus.uart0 + Create Terminal Tester sysbus.uart0 machine=central + +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Teardown Test Teardown +Library Process +Resource ${RENODEKEYWORDS} + +*** Test Cases *** + +Uptime Demo + Execute Command emulation CreateIEEE802_15_4Medium "wireless" + + Execute Command mach add "central" + Execute Command machine LoadPlatformDescription @platforms/cpus/nrf52840.repl + Execute Command sysbus LoadELF @${CURDIR}/ble_central/build/zephyr/zephyr.elf + Execute Command connector Connect sysbus.radio wireless + + Execute Command showAnalyzer ${UART} + ${cen_uart}= Create Terminal Tester ${UART} machine=central + + Execute Command mach add "peripheral" + Execute Command mach set "peripheral" + Execute Command machine LoadPlatformDescription @platforms/cpus/nrf52840.repl + Execute Command sysbus LoadELF @${CURDIR}/../../samples/uptime/build/zephyr/zephyr.elf + Execute Command connector Connect sysbus.radio wireless + + Execute Command showAnalyzer ${UART} + ${per_uart}= Create Terminal Tester ${UART} machine=peripheral + + Execute Command emulation SetGlobalQuantum "0.00001" + + Start Emulation + + Wait For Line On Uart Booting Zephyr testerId=${cen_uart} + 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 Connected testerId=${per_uart} + Wait For Line On Uart Connected testerId=${cen_uart} + Wait For Line On Uart Service found testerId=${cen_uart} + Wait For Line On Uart Chrc 3/3 found testerId=${cen_uart} + Wait For Line On Uart Subscribed testerId=${cen_uart} + Wait For Line On Uart Characteristic Notify Uptime CCC changed testerId=${per_uart} + Wait For Line On Uart Uptime value 1 testerId=${cen_uart} + Wait For Line On Uart Uptime value 2 testerId=${cen_uart} + Wait For Line On Uart Uptime value 3 testerId=${cen_uart} \ No newline at end of file