Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
BTstackBackgroundBackend.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <AH/Error/Error.hpp>
4
5#include "BLEAPI.hpp"
9
10#include <atomic>
11#include <csignal>
12#include <hardware/sync.h>
13
15
21 : private PollingBLEMIDISender<BTstackBackgroundBackend>,
22 private MIDIBLEInstance {
23 private:
24 // Callbacks from the ArduinoBLE stack.
25 void handleConnect(BLEConnectionHandle conn_handle) override {
26 connected = conn_handle.conn;
27 }
29 connected = subscribed = 0xFFFF;
30 }
31 void handleMTU(BLEConnectionHandle, uint16_t mtu) override {
33 }
35 BLECharacteristicHandle char_handle,
36 bool notify) override {
37 subscribed = notify ? char_handle.characteristic : 0xFFFF;
38 }
40 BLEDataLifetime) override {
41 while (true) {
42 BLEDataView packet = data();
43 if (packet.length == 0) {
44 break;
45 } else if (!parser.pushPacket(packet)) {
46 DEBUGREF(F("BLE packet dropped, size: ") << packet.length);
47 break;
48 }
49 }
50 }
51
52 private:
53 // We cannot use atomics here, because they might not be lock-free on the
54 // Pico's Cortex-M0+ cores.
55 static_assert(sizeof(sig_atomic_t) > sizeof(uint16_t));
57 volatile sig_atomic_t connected = 0xFFFF;
59 volatile sig_atomic_t subscribed = 0xFFFF;
60 struct VolatileSize {
61 constexpr static size_t alignment = alignof(sig_atomic_t);
62 VolatileSize(sig_atomic_t value) : value {value} {}
63 volatile sig_atomic_t value;
64 sig_atomic_t load_acquire() const {
65 auto state = save_and_disable_interrupts(); // Probably overkill ...
66 auto t = value;
67 restore_interrupts(state);
68 std::atomic_signal_fence(std::memory_order_acquire);
69 return t;
70 }
71 void add_release(sig_atomic_t t) {
72 std::atomic_signal_fence(std::memory_order_release);
73 auto state = save_and_disable_interrupts();
74 value += t;
75 restore_interrupts(state);
76 }
77 void sub_release(sig_atomic_t t) {
78 std::atomic_signal_fence(std::memory_order_release);
79 auto state = save_and_disable_interrupts();
80 value -= t;
81 restore_interrupts(state);
82 }
83 };
86
87 public:
89
91 bool popMessage(IncomingMIDIMessage &incomingMessage) {
92 // This function is assumed to be polled regularly by the higher-level
93 // MIDI_Interface, so we check the sender's timer here.
94 auto lck = Sender::acquirePacket();
96 // Actually get a MIDI message from the buffer
97 return parser.popMessage(incomingMessage);
98 }
99
100 public:
102 void begin(BLESettings ble_settings) {
103 midi_ble_btstack::init(*this, ble_settings);
105 }
108 void end() {}
110 bool isConnected() const { return connected != 0xFFFF; }
111
112 private:
113 // Implement the interface for the BLE sender.
115 friend Sender;
118 if (connected != 0xFFFF && subscribed != 0xFFFF)
119 midi_ble_btstack::notify(
120 BLEConnectionHandle {static_cast<uint16_t>(connected)},
121 BLECharacteristicHandle {static_cast<uint16_t>(subscribed)},
122 data);
123 }
124
125 public:
126 // Expose the necessary BLE sender functions.
129 using Sender::getMinMTU;
131 using Sender::sendNow;
132 using Sender::setTimeout;
133};
134
Type definitions and callback interfaces for communication between the low-level BLE stacks and highe...
BLEDataLifetime
Should a buffer of BLEData be consumed immediately inside of the callback, or can we hold on to it an...
Definition BLEAPI.hpp:113
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Callable that returns the next chunk of data from a BLE packet when called.
Definition BLEAPI.hpp:66
Raspberry Pi Pico BTstack background backend intended to be plugged into GenericBLEMIDI_Interface.
void handleConnect(BLEConnectionHandle conn_handle) override
Called by the BLE stack when a connection is established.
BufferedBLEMIDIParser< 1024, VolatileSize > parser
Contains incoming BLE MIDI data to be parsed.
void handleMTU(BLEConnectionHandle, uint16_t mtu) override
Called by the BLE stack when the maximum transmission unit for the connection changes.
void sendData(BLEDataView data)
Send the given MIDI BLE packet.
void handleData(BLEConnectionHandle, BLEDataGenerator &&data, BLEDataLifetime) override
Called by the BLE stack when the central writes data to the MIDI GATT characteristic.
volatile sig_atomic_t connected
Are we connected to a BLE Central?
void begin(BLESettings ble_settings)
Initialize the BLE stack etc.
bool isConnected() const
Returns true if we are connected to a BLE Central device.
volatile sig_atomic_t subscribed
Did the BLE Central subscribe to be notified for the MIDI characteristic?
void end()
Deinitialize the BLE stack.
bool popMessage(IncomingMIDIMessage &incomingMessage)
Retrieve and remove a single incoming MIDI message from the buffer.
void handleDisconnect(BLEConnectionHandle) override
Called by the BLE stack when a connection is terminated.
void handleSubscribe(BLEConnectionHandle, BLECharacteristicHandle char_handle, bool notify) override
Called by the BLE stack when the central subscribes to receive notifications for the MIDI GATT charac...
FIFO buffer that you can push BLE packets into, and pop MIDI messages out of.
Defines the interface for callback functions registered by the low-level BLE code.
Definition BLEAPI.hpp:127
Class that buffers MIDI BLE packets.
BLEMIDIPacketBuilder packet
View of the data to send.
uint16_t getMinMTU() const
Get the minimum MTU of all connected clients.
void setTimeout(std::chrono::milliseconds timeout)
Set the timeout, the number of milliseconds to buffer the outgoing MIDI messages.
void forceMinMTU(uint16_t mtu)
Force the MTU to an artificially small value (used for testing).
ProtectedBuilder acquirePacket()
Acquire exclusive access to the buffer.
void releasePacketAndNotify(ProtectedBuilder &lck)
Release exclusive access to the buffer and notify the sender thread that data is available.
void updateMTU(uint16_t mtu)
Set the maximum transmission unit of the Bluetooth link.
void sendNow(ProtectedBuilder &lck)
Sends the data immediately without waiting for the timeout.
#define DEBUGREF(x)
Print an expression and its location (file and line number) to the debug output if debugging is enabl...
Definition Debug.hpp:105
MIDI message variant type (with timestamp).
Represents a handle to a local GATT characteristic.
Definition BLEAPI.hpp:30
Represents a handle to the connection to another device.
Definition BLEAPI.hpp:19
Non-owning, std::span-style read-only view of BLE data.
Definition BLEAPI.hpp:42
Configuration options for the low-level BLE code.
Definition BLEAPI.hpp:150