Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡️ (ble): Set dynamic data in advertising (name, battery level, battery is charging) #633

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/BLEKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ target_link_libraries(BLEKit
if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests")

leka_unit_tests_sources(
tests/AdvertisingData_test.cpp
tests/CoreGapEventHandler_test.cpp
tests/CoreGap_test.cpp
tests/CoreGattServerEventHandler_test.cpp
Expand Down
32 changes: 32 additions & 0 deletions libs/BLEKit/include/AdvertisingData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <array>
#include <cstdint>
#include <span>

namespace leka {

struct AdvertisingData {
const char *name = "Leka"; // TODO: Get default name from configuration files
uint8_t battery {};
uint8_t is_charging {};

auto data()
{
updateValues();
return _internal_values.data();
}

[[nodiscard]] auto size() const -> uint32_t { return _internal_values.size(); }

// private:
void updateValues() { _internal_values = {battery, is_charging}; }

std::array<uint8_t, 2> _internal_values = {};
};

} // namespace leka
5 changes: 5 additions & 0 deletions libs/BLEKit/include/BLEKit.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ class BLEKit

void init();

void setAdvertisingData(const AdvertisingData &advertising_data);
[[nodiscard]] auto getAdvertisingData() const -> AdvertisingData;

private:
// ? mbed::BLE specific function
void processEvents(BLE::OnEventsToProcessCallbackContext *context);

CoreEventQueue _event_queue {};

AdvertisingData _advertising_data {};

BLE &_ble = BLE::Instance();
CoreGap _core_gap {_ble.gap()};
CoreGattServer _core_gatt_server {_ble.gattServer()};
Expand Down
4 changes: 2 additions & 2 deletions libs/BLEKit/include/CoreGap.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ble/BLE.h"
#include "ble/Gap.h"

#include "AdvertisingData.h"
#include "CoreGapEventHandler.h"

namespace leka {
Expand All @@ -24,9 +25,8 @@ class CoreGap
void onInitializationComplete(BLE::InitializationCompleteCallbackContext *params);
// void onInit(std::function<void()> cb) { _post_init = cb; }

void setDeviceName(const char *name);

void startAdvertising();
void setAdvertising(AdvertisingData advertising_data);

private:
ble::advertising_handle_t _advertising_handle {ble::LEGACY_ADVERTISING_HANDLE};
Expand Down
13 changes: 12 additions & 1 deletion libs/BLEKit/source/BLEKit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ void BLEKit::init()
_ble.onEventsToProcess({this, &BLEKit::processEvents});

_core_gap.setDefaultAdvertising();
_core_gap.setDeviceName("Leka");

_ble.init(&_core_gap, &CoreGap::onInitializationComplete);

Expand All @@ -30,3 +29,15 @@ void BLEKit::processEvents(BLE::OnEventsToProcessCallbackContext *context)
{
_event_queue.callMbedCallback(mbed::callback(&context->ble, &BLE::processEvents));
}

void BLEKit::setAdvertisingData(const AdvertisingData &advertising_data)
{
_advertising_data = advertising_data;

_core_gap.setAdvertising(_advertising_data);
}

auto BLEKit::getAdvertisingData() const -> AdvertisingData
{
return _advertising_data;
}
27 changes: 16 additions & 11 deletions libs/BLEKit/source/CoreGap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ using namespace ble;

void CoreGap::setDefaultAdvertising()
YannLocatelli marked this conversation as resolved.
Show resolved Hide resolved
{
_advertising_data_builder.setAppearance(adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR);
_advertising_data_builder.setFlags();
_advertising_data_builder.setManufacturerSpecificData({{0x2A, 0x2B, 0x2C, 0x2D}});
_advertising_data_builder.setAdvertisingInterval(adv_interval_t::min());
_advertising_data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, {{0x42}});
_advertising_data_builder.setServiceData(leka::service::commands::uuid, {{0}});
auto default_advertising_data = AdvertisingData {};

_advertising_data_builder.setName(default_advertising_data.name);
_advertising_data_builder.setServiceData(
leka::service::commands::uuid, // TODO: commands::uuid only for compatibility with LekaApp
{default_advertising_data.data(), default_advertising_data.size()});
}

void CoreGap::setEventHandler()
Expand All @@ -27,11 +27,6 @@ void CoreGap::onInitializationComplete(BLE::InitializationCompleteCallbackContex
_gap_event_handler.onInitializationComplete(params);
}

void CoreGap::setDeviceName(const char *name)
{
_advertising_data_builder.setName(name);
}

void CoreGap::startAdvertising()
{
if (_gap.isAdvertisingActive(_advertising_handle)) {
Expand All @@ -43,3 +38,13 @@ void CoreGap::startAdvertising()

_gap.startAdvertising(_advertising_handle, adv_duration_t(millisecond_t(4000)));
}

void CoreGap::setAdvertising(AdvertisingData advertising_data)
{
_advertising_data_builder.setName(advertising_data.name);
_advertising_data_builder.setServiceData(
leka::service::commands::uuid, // TODO: commands::uuid only for compatibility with LekaApp
{advertising_data.data(), advertising_data.size()});

_gap.setAdvertisingPayload(_advertising_handle, _advertising_data_builder.getAdvertisingData());
}
28 changes: 28 additions & 0 deletions libs/BLEKit/tests/AdvertisingData_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Leka - LekaOS
// Copyright 2022 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "AdvertisingData.h"

#include "gtest/gtest.h"

using namespace leka;

TEST(AdvertisingDataTest, initialisation)
{
auto advertising_data = AdvertisingData {};

EXPECT_NE(&advertising_data, nullptr);
}

TEST(AdvertisingDataTest, data)
{
auto advertising_data = AdvertisingData {.battery = 0x2A, .is_charging = 0x2B};

auto expected_data_array = std::to_array({advertising_data.battery, advertising_data.is_charging});

auto actual_data_array = std::span {advertising_data.data(), advertising_data.size()};

EXPECT_EQ(std::size(actual_data_array), std::size(expected_data_array));
EXPECT_TRUE(0 == memcmp(expected_data_array.data(), actual_data_array.data(), std::size(expected_data_array)));
}
10 changes: 10 additions & 0 deletions libs/BLEKit/tests/BLEKit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,13 @@ TEST_F(BLEKitTest, callOnEventsToProcess)

EXPECT_TRUE(spy_CoreEventQueue_did_call_function);
}

TEST_F(BLEKitTest, getAdvertisingDataThenSetAdvertisingData)
{
auto advertising_data = ble.getAdvertisingData();
advertising_data.name = "NewLeka";

EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload).Times(1);

ble.setAdvertisingData(advertising_data);
}
48 changes: 21 additions & 27 deletions libs/BLEKit/tests/CoreGap_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,12 @@ TEST_F(CoreGapTest, defaultAdvertisingParameters)
TEST_F(CoreGapTest, defaultAdvertisingPayload)
{
std::array<uint8_t, 64> buffer {};
auto data_builder = AdvertisingDataBuilder {{buffer.begin(), buffer.end()}};
auto data_builder = AdvertisingDataBuilder {{buffer.begin(), buffer.end()}};
auto default_advertising_data = AdvertisingData {};

data_builder.setAppearance(ble::adv_data_appearance_t::GENERIC_HEART_RATE_SENSOR);
data_builder.setFlags();
data_builder.setManufacturerSpecificData({{0x2A, 0x2B, 0x2C, 0x2D}});
data_builder.setAdvertisingInterval(ble::adv_interval_t::min());
data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, {{0x42}});
data_builder.setServiceData(service::commands::uuid, {{0}});
data_builder.setName(default_advertising_data.name);
data_builder.setServiceData(service::commands::uuid,
{{default_advertising_data.battery, default_advertising_data.is_charging}});

EXPECT_CALL(mbed_mock_gap,
setAdvertisingPayload(LEGACY_ADVERTISING_HANDLE, compareAdvertisingPayload(data_builder)))
Expand All @@ -113,26 +111,6 @@ TEST_F(CoreGapTest, defaultAdvertisingPayload)
coregap.startAdvertising();
}

TEST_F(CoreGapTest, setDeviceName)
{
auto expected_device_name = "LekaCoreGap";

std::array<uint8_t, 64> buffer {};
auto data_builder = AdvertisingDataBuilder {{buffer.begin(), buffer.end()}};

data_builder.setName(expected_device_name);

EXPECT_CALL(mbed_mock_gap,
setAdvertisingPayload(LEGACY_ADVERTISING_HANDLE, compareAdvertisingPayload(data_builder)))
.Times(1);
EXPECT_CALL(mbed_mock_gap, isAdvertisingActive).WillOnce(Return(false));
EXPECT_CALL(mbed_mock_gap, startAdvertising).Times(1);
EXPECT_CALL(mbed_mock_gap, setAdvertisingParameters).Times(1);

coregap.setDeviceName(expected_device_name);
coregap.startAdvertising();
}

TEST_F(CoreGapTest, startAdvertisingAdvertisingWasInactive)
{
Sequence seq1, seq2;
Expand Down Expand Up @@ -166,3 +144,19 @@ TEST_F(CoreGapTest, onInitializationComplete)

// coregap.onInitializationComplete(&context); // Alternative
}

TEST_F(CoreGapTest, setAdvertising)
{
std::array<uint8_t, 64> buffer {};
auto data_builder = AdvertisingDataBuilder {{buffer.begin(), buffer.end()}};
auto new_advertising_data = AdvertisingData {.name = "NewLeka", .battery = 0x42, .is_charging = 0x01};

data_builder.setName(new_advertising_data.name);
data_builder.setServiceData(service::commands::uuid, {new_advertising_data.data(), new_advertising_data.size()});

EXPECT_CALL(mbed_mock_gap,
setAdvertisingPayload(LEGACY_ADVERTISING_HANDLE, compareAdvertisingPayload(data_builder)))
.Times(1);

coregap.setAdvertising(new_advertising_data);
}
6 changes: 6 additions & 0 deletions spikes/lk_ble/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,11 @@ auto main() -> int
auto version = service_update.getVersion();

log_info("Requested version: %d.%d.%d", version.major, version.minor, version.revision);

auto advertising_data = blekit.getAdvertisingData();
advertising_data.name = "NewLeka";
advertising_data.battery = level;
advertising_data.is_charging = charging_status;
blekit.setAdvertisingData(advertising_data);
}
}