LCOV - code coverage report
Current view: top level - src/MIDI_Interfaces/BLEMIDI - BLEAPI.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 100.0 % 3 3
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : /**
       4              :  * @file
       5              :  * Type definitions and callback interfaces for communication between the
       6              :  * low-level BLE stacks and higher-level MIDI BLE backends.
       7              :  */
       8              : 
       9              : #include <Settings/NamespaceSettings.hpp>
      10              : 
      11              : #include "Util/compat.hpp"
      12              : 
      13              : #include <cstddef>
      14              : #include <cstdint>
      15              : 
      16              : BEGIN_CS_NAMESPACE
      17              : 
      18              : /// Represents a handle to the connection to another device.
      19              : struct BLEConnectionHandle {
      20              :     uint16_t conn = 0xFFFF;
      21              :     explicit operator bool() const { return conn != 0xFFFF; }
      22              : 
      23              : #if __cplusplus < 201402L
      24              :     BLEConnectionHandle() = default;
      25              :     BLEConnectionHandle(uint16_t conn) : conn {conn} {}
      26              : #endif
      27              : };
      28              : 
      29              : /// Represents a handle to a local GATT characteristic.
      30              : struct BLECharacteristicHandle {
      31              :     uint16_t characteristic = 0xFFFF;
      32              :     explicit operator bool() const { return characteristic != 0xFFFF; }
      33              : 
      34              : #if __cplusplus < 201402L
      35              :     BLECharacteristicHandle() = default;
      36              :     BLECharacteristicHandle(uint16_t characteristic)
      37              :         : characteristic {characteristic} {}
      38              : #endif
      39              : };
      40              : 
      41              : /// Non-owning, std::span-style read-only view of BLE data.
      42              : struct BLEDataView {
      43              :     const uint8_t *data = nullptr;
      44              :     uint16_t length = 0;
      45           30 :     explicit operator bool() const { return length > 0; }
      46              : 
      47              : #if __cplusplus < 201402L
      48              :     BLEDataView() = default;
      49              :     BLEDataView(const uint8_t *data, uint16_t length)
      50              :         : data {data}, length {length} {}
      51              : #endif
      52              : };
      53              : 
      54              : /// Describes a byte buffer containing (part of) a BLE packet.
      55              : /// Packets can be stored across multiple buffers, in which case the first
      56              : /// first buffer has type `Packet` and subsequent buffers of the same packet
      57              : /// have the type `Continuation`.
      58              : enum class BLEDataType : uint8_t {
      59              :     None = 0,     ///< No buffers available.
      60              :     Packet,       ///< Buffer contains the start of a BLE packet.
      61              :     Continuation, ///< Buffer contains a chunk of a BLE packet.
      62              : };
      63              : 
      64              : /// Callable that returns the next chunk of data from a BLE packet when called.
      65              : /// Uses type erasure with a static buffer (no dynamic memory allocations).
      66              : class BLEDataGenerator {
      67              :   public:
      68              :     /// Get the next chunk of data from the BLE packet.
      69              :     /// Returns a chunk of size zero to indicate completion.
      70              :     /// @pre This wrapper is not empty.
      71              :     /// @pre There is still data available. Calling this function again after
      72              :     ///      the previous call returned an empty chunk is not allowed.
      73              :     BLEDataView operator()();
      74              :     /// Release the resources of the underlying data generator.
      75              :     void clear();
      76              :     /// Check if this wrapper contains an underlying data generator.
      77              :     explicit operator bool() const { return instance; }
      78              : 
      79              :     /// Create an empty BLEDataGenerator.
      80              :     BLEDataGenerator() = default;
      81              :     /// Store a callable of type @p T and initialize it by @p args.
      82              :     template <class T, class... Args>
      83              :     BLEDataGenerator(compat::in_place_type_t<T>, Args &&...args);
      84              :     /// Store a callable of type @p T (with cv qualifiers and references
      85              :     /// removed) and initialize it by forwarding @p t.
      86              :     template <class T>
      87              :     BLEDataGenerator(compat::in_place_t, T &&t);
      88              :     BLEDataGenerator(const BLEDataGenerator &) = delete;
      89              :     BLEDataGenerator &operator=(const BLEDataGenerator &) = delete;
      90              :     BLEDataGenerator(BLEDataGenerator &&other) noexcept;
      91              :     BLEDataGenerator &operator=(BLEDataGenerator &&other) noexcept;
      92           15 :     ~BLEDataGenerator() { clear(); }
      93              : 
      94              :   private:
      95              :     /// Type-erased interface.
      96              :     struct Iface;
      97              :     /// Specific class that implements the type-erased interface, wrapping the
      98              :     /// type @p T.
      99              :     template <class T>
     100              :     struct Impl;
     101              :     /// Alignment of the buffer to allocate the underlying data generator.
     102              :     using buffer_align_t = max_align_t;
     103              :     /// Size of the buffer to allocate the underlying data generator.
     104              :     static constexpr size_t capacity = 4 * sizeof(void *) - sizeof(Iface *);
     105              :     /// Buffer used for allocation of the underlying data generator.
     106              :     alignas(buffer_align_t) compat::byte storage[capacity];
     107              :     //// Type-erased pointer to the underlying data generator in @ref storage.
     108              :     Iface *instance = nullptr;
     109              : };
     110              : 
     111              : /// Should a buffer of BLEData be consumed immediately inside of the callback,
     112              : /// or can we hold on to it and process it later?
     113              : enum class BLEDataLifetime {
     114              :     /// Buffer is valid only during the callback. Do not keep any pointers to it.
     115              :     ConsumeImmediately,
     116              :     /// Buffer is valid for as long as the owning @ref BLEDataGenerator is not
     117              :     /// resumed or destroyed.
     118              :     Managed,
     119              : };
     120              : 
     121              : /// Defines the interface for callback functions registered by the low-level
     122              : /// BLE code.
     123              : /// @warning    These functions may be called from different tasks/threads or
     124              : ///             low-priority interrupt handlers. You cannot take locks, and you
     125              : ///             need to synchronize appropriately (e.g. using `std::atomic` or
     126              : ///             by using critical sections).
     127              : class MIDIBLEInstance {
     128              :   public:
     129           29 :     virtual ~MIDIBLEInstance() = default;
     130              :     /// Called by the BLE stack when a connection is established.
     131              :     virtual void handleConnect(BLEConnectionHandle conn_handle) = 0;
     132              :     /// Called by the BLE stack when a connection is terminated.
     133              :     virtual void handleDisconnect(BLEConnectionHandle conn_handle) = 0;
     134              :     /// Called by the BLE stack when the maximum transmission unit for the
     135              :     /// connection changes.
     136              :     virtual void handleMTU(BLEConnectionHandle conn_handle, uint16_t mtu) = 0;
     137              :     /// Called by the BLE stack when the central subscribes to receive
     138              :     /// notifications for the MIDI GATT characteristic.
     139              :     virtual void handleSubscribe(BLEConnectionHandle conn_handle,
     140              :                                  BLECharacteristicHandle char_handle,
     141              :                                  bool notify) = 0;
     142              :     /// Called by the BLE stack when the central writes data to the MIDI GATT
     143              :     /// characteristic.
     144              :     virtual void handleData(BLEConnectionHandle conn_handle,
     145              :                             BLEDataGenerator &&data,
     146              :                             BLEDataLifetime lifetime) = 0;
     147              : };
     148              : 
     149              : /// Configuration options for the low-level BLE code.
     150              : struct BLESettings {
     151              :     /// Device name (used for advertising)
     152              :     const char *device_name = "Control Surface MIDI";
     153              :     /// Connection intervals as multiples of 1.25 milliseconds
     154              :     /// (e.g.0x000C = 15 ms).
     155              :     struct {
     156              :         uint16_t minimum = 0x000C;
     157              :         uint16_t maximum = 0x000C;
     158              :     } connection_interval {};
     159              :     /// Encrypt the MIDI characteristic (NimBLE only).
     160              :     bool require_encryption = false;
     161              :     /// Set to true if you want the Arduino to always initiate the Bluetooth
     162              :     /// bonding or secure connection. As a result, it will show up as a "paired"
     163              :     /// device on your computer/phone/tablet. If set to false, security is still
     164              :     /// supported, but the central device should take the initiative.
     165              :     bool initiate_security = false;
     166              : };
     167              : 
     168              : END_CS_NAMESPACE
     169              : 
     170              : #include "BLEAPI.ipp"
        

Generated by: LCOV version 2.4-beta