3 #include "AudioBLEStream.h"
4 #include "ConstantsArduino.h"
5 #include <ArduinoBLE.h>
6 #include "AudioTools/CoreAudio/AudioBasic/StrView.h"
11 class AudioBLEServer *selfAudioBLEServer =
nullptr;
28 selfAudioBLEServer =
this;
32 bool begin(
const char *name) {
34 ble_server_name = name;
37 LOGE(
"starting BLE failed");
42 BLE.setLocalName(ble_server_name);
45 BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
46 BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
63 size_t readBytes(uint8_t *data,
size_t len)
override {
65 if (!checkCentralConnected())
67 size_t read_size = getReadSize(len);
68 return receive_buffer.
readArray(data, read_size);
71 int available()
override {
72 if (!checkCentralConnected())
75 return receive_sizes.
peek();
79 size_t write(
const uint8_t *data,
size_t len)
override {
80 LOGD(
"AudioBLEStream::write: %d", len);
81 if (!checkCentralConnected())
83 if (is_framed && availableForWrite() < len) {
89 int availableForWrite()
override {
90 if (!checkCentralConnected())
95 if (result < DEFAULT_BUFFER_SIZE)
100 bool connected()
override {
return checkCentralConnected(); }
105 BLEService service{BLE_AUDIO_SERVICE_UUID};
106 BLECharacteristic ch01_char{BLE_CH1_UUID, BLERead, getMTU()};
107 BLECharacteristic ch02_char{BLE_CH2_UUID, BLEWrite, getMTU()};
108 BLECharacteristic info_char{BLE_INFO_UUID, BLERead | BLEWrite | BLENotify,
110 BLEDescriptor ch01_desc{
"2901",
"channel 1"};
111 BLEDescriptor ch02_desc{
"2901",
"channel 2"};
112 BLEDescriptor info_desc{
"2901",
"info"};
119 static void blePeripheralConnectHandler(BLEDevice device) {
120 selfAudioBLEServer->onConnect(device);
123 static void blePeripheralDisconnectHandler(BLEDevice device) {
124 selfAudioBLEServer->onDisconnect(device);
127 static void bleOnWrite(BLEDevice device, BLECharacteristic characteristic) {
128 selfAudioBLEServer->
onWrite(characteristic);
131 static void bleOnRead(BLEDevice device, BLECharacteristic characteristic) {
133 selfAudioBLEServer->
onRead(characteristic);
136 void onConnect(BLEDevice device) { TRACEI(); }
138 void onDisconnect(BLEDevice device) {
144 void onWrite(BLECharacteristic characteristic) {
149 if (
StrView(BLE_INFO_UUID).equals(characteristic.uuid())) {
151 characteristic.valueLength());
153 receiveAudio((uint8_t *)characteristic.value(),
154 characteristic.valueLength());
159 void onRead(BLECharacteristic characteristic) {
161 auto uuid =
StrView(characteristic.uuid());
162 if (uuid == BLE_CH1_UUID || uuid == BLE_CH2_UUID) {
164 int len = std::min(getMTU(), (
int)transmit_buffer.
available());
166 len = transmit_buffer_sizes.
read();
168 LOGI(
"%s: len: %d, buffer: %d", uuid.c_str(), len,
169 transmit_buffer.
size());
172 transmit_buffer.peekArray(tmp, len);
173 if (characteristic.writeValue(tmp, len)) {
176 LOGW(
"writeValue failed")
182 bool checkCentralConnected() {
183 central = BLE.central();
186 return central.connected();
190 virtual void receiveAudio(
const uint8_t *data,
size_t size) {
196 receive_sizes.
write(size);
200 void writeAudioInfoCharacteristic(AudioInfo info) {
203 StrView str = toStr(info);
204 LOGI(
"AudioInfo: %s", str.c_str());
205 info_char.setValue((uint8_t *)str.c_str(), str.length() + 1);
208 int getMTU()
override {
210 if (max_transfer_size == 0) {
216 max_transfer_size = BLE_MTU - BLE_MTU_OVERHEAD;
218 LOGI(
"max_transfer_size: %d", max_transfer_size);
220 return max_transfer_size;
223 void setupBLEService() {
226 BLE.setAdvertisedService(service);
228 ch01_char.addDescriptor(ch01_desc);
229 ch02_char.addDescriptor(ch02_desc);
232 service.addCharacteristic(ch01_char);
233 service.addCharacteristic(ch02_char);
236 ch02_char.setEventHandler(BLEWritten, bleOnWrite);
237 ch01_char.setEventHandler(BLERead, bleOnRead);
239 if (is_audio_info_active) {
240 info_char.addDescriptor(info_desc);
241 service.addCharacteristic(info_char);
245 BLE.addService(service);
248 if (is_audio_info_active) {
249 writeAudioInfoCharacteristic(info);
253 uint8_t tmp[512] = {0xFF};
254 ch01_char.writeValue(tmp, 512,
false);
257 void setupTXBuffer() {
258 if (transmit_buffer.
size() == 0) {
259 LOGI(
"Setting transmit_buffer to %d", RX_BUFFER_SIZE);
260 transmit_buffer.resize(TX_BUFFER_SIZE);
262 transmit_buffer_sizes.resize(TX_COUNT);
267 void setupRXBuffer() {
268 if (receive_buffer.
size() == 0) {
269 LOGI(
"Setting receive_buffer to %d for mtu %d", RX_BUFFER_SIZE, getMTU());
270 receive_buffer.resize(RX_BUFFER_SIZE);
272 receive_sizes.resize(RX_COUNT);
277 size_t getReadSize(
size_t dataSize) {
278 size_t read_size = dataSize;
282 read_size = receive_sizes.
read();
284 if (dataSize < read_size) {
285 LOGE(
"read size too small: %d - it must be >= %d", dataSize, read_size);
288 if (receive_buffer.
available() < read_size) {
289 LOGE(
"missing data in buffer");