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.
29 connected = subscribed = 0xFFFF;
30 }
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);
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 }
72 std::atomic_signal_fence(std::memory_order_release);
73 auto state = save_and_disable_interrupts();
74 value += t;
75 restore_interrupts(state);
76 }
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)},
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...
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
An array wrapper for easy copying, comparing, and iterating.
Definition Array.hpp:32
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