theheraldproject / herald-for-cpp

Herald for C++ - Reliable mobile Bluetooth communications - Native library & test apps
https://heraldprox.io
Other
13 stars 10 forks source link
bluetooth bluetooth-beacons bluetooth-connection bluetooth-devices bluetooth-le bluetooth-low-energy bluetooth-mesh contact-tracing cpp cpp17 digital-contact-tracing herald herald-library nordic-bluetooth nordicsemi zephyr

Herald for C++ (Native platforms) - Library

This repository contains a Herald Bluetooth Protocol and Payload set of implementations for native platforms. This includes Windows 10 desktop and Nordic Semiconductor or other Zephyr RTOS capable boards. The board used for development is the Seeed nRF52840MK-USB-Dongle.

This particular code base is the core Herald library. It is used by all examples, including Wearables (just like the Herald for iOS and Herald for Android library use case), Bluetooth MESH Gateway, and Windows Desktop Herald communication examples.

This implementation was introduced in Herald v1.2.

License and Copyright

Copyright 2020-2023 Herald Project Contributors

License: Apache-2.0

See LICENSE.txt and NOTICE.txt for details.

Demonstration apps / libraries

The following apps are available:-

The following are libraries available for your own projects:-

The following are 'coming soon':-

Supported / tested platforms

The Herald team use the C++ API for specific use cases and so only provide support for a specific subset of use cases. If you'd like to contribute platform support feel free to provide code, tests, documentation and raise a PR.

Other platforms which may work but which we do not provide direct advice for:-

Implementation differences

Some thin wrappers were not required in the C++ version compared to the Java and Swift versions as the base primitives were already accesible in C++17. These include:-

We've also added some classes to make porting easier. We may fall back in their implementation C++ files on some platforms where known utility libraries are always present. Current list includes:-

Implementation details

Any trivial wrapper classes have been implemented as structs.

Any Interfaces from Java and Swift have been implemented as pure virtual base classes. The code base is being heavily refactored to use references only and avoid using any pointers, including smart pointers. This allows us to be able to predict and restrict memory use at compile time, and provide for maximum memory safety.

This code base implements Bluetooth Low Energy (BLe) implementations on Zephyr/nRF Connect as standard.

What isn't implemented

Any higher level implementation details, such as Mesh gateway payloads and interconnect logic is within a downstream library project. That is to keep this set of classes simple and consistent with the iOS and Android equivalent Herald libraries.

What is implemented

We do provide a demo Windows application in this repository, and a demo zephyr serial application. These act as 'Herald consumer / demo devices' and implement the same basic features as the Android and iOS demo apps. They are provided to allow us to carry out regression testing on each version.

These demo apps are not intended as production ready applications. They can be used as a reference implementation for any Herald based apps and devices you wish to create.

Specific platform limitations

The Herald API cannot use all available modern C++ features due to some hardware, OS' and libc++ libraries not supporting those functions. Where possible we always use modern C++17 techniques and STL functions. On specific platforms we also check for local utility libraries rather than respecify our own (E.g. base64, random number generation, uuid).

Zephyr OS limitations

We cannot use dynamic_pointer_cast to cast a std::shared_ptr to a std::shared_ptr because this uses RTTI which is not supported by Zephyr. We use static_pointer_cast instead, but only when we know the class implementation can only have one definition (i.e. the one for the current platform). We are moving to remove all use of smart pointers generally in favour of references.

We also use noexcept rather than throw exceptions for the same reason.

See the Zephyr C++ limitations [External] page for details. Note that this page is out of date somewhat. The 'new' keyword, for example, is supported in Zephyr although it is very buggy.

Note: In the v2.0 release we have removed all internal use of std::unique_ptr and std::shared_ptr in favour of templates and static sizes for things like SensorDelegates throughout the code base. This is to avoid Zephyr memory management bugs and improve (lower) memory use (SRAM) on Nordic Semiconductor devices.

Building with Code Coverage

  1. Open Visual Studio Code
  2. Perform a CMake build using CLang on Windows in Debug mode
  3. Execute this in the build folder on the command line: cmake .. -DCMAKE_BUILD_TYPE=Debug -DCODE_COVERAGE=ON to add code coverage support
  4. Open the CMake tools tab in Visual Studio Code
  5. Expand 'herald-tests'
  6. Run the 'ccov-report' utility