3 #include "AudioBLEStream.h"
4 #include "ConstantsESP32.h"
9 #include "AudioTools/CoreAudio/AudioBasic/StrView.h"
20 class AudioBLEServer :
public AudioBLEStream,
21 public BLECharacteristicCallbacks,
22 public BLEServerCallbacks {
24 AudioBLEServer(
int mtu = BLE_MTU) : AudioBLEStream(mtu) {}
27 bool begin(
const char *name) {
29 ble_server_name = name;
30 BLEDevice::init(name);
32 p_server = BLEDevice::createServer();
33 p_server->setCallbacks(
this);
36 p_advertising = BLEDevice::getAdvertising();
37 p_advertising->addServiceUUID(BLE_AUDIO_SERVICE_UUID);
38 BLEDevice::startAdvertising();
48 size_t readBytes(uint8_t *data,
size_t len)
override {
50 size_t read_size = getReadSize(len);
51 return receive_buffer.
readArray(data, read_size);
54 int available()
override {
56 return receive_sizes.
peek();
60 size_t write(
const uint8_t *data,
size_t dataSize)
override {
61 LOGD(
"AudioBLEStream::write: %d", dataSize);
65 if (is_framed && availableForWrite() < dataSize) {
68 return transmit_buffer.
writeArray(data, dataSize);
71 int availableForWrite()
override {
74 if (result < DEFAULT_BUFFER_SIZE) result = 0;
78 bool connected()
override {
return p_server->getConnectedCount() > 0; }
82 BLEServer *p_server =
nullptr;
83 BLEService *p_service =
nullptr;
84 BLEAdvertising *p_advertising =
nullptr;
85 BLECharacteristic *ch01_char;
86 BLECharacteristic *ch02_char;
87 BLECharacteristic *info_char;
88 BLEDescriptor ch01_desc{
"2901"};
89 BLEDescriptor ch02_desc{
"2901"};
90 BLEDescriptor info_desc{
"2901"};
91 RingBuffer<uint8_t> receive_buffer{0};
92 RingBuffer<uint16_t> receive_sizes{0};
93 RingBuffer<uint8_t> transmit_buffer{0};
94 RingBuffer<uint16_t> transmit_buffer_sizes{0};
96 virtual void receiveAudio(
const uint8_t *data,
size_t size) {
102 receive_sizes.
write(size);
106 void writeAudioInfoCharacteristic(AudioInfo info) {
109 StrView str = toStr(info);
110 LOGI(
"AudioInfo: %s", str.c_str());
111 info_char->setValue((uint8_t *)str.c_str(), str.length() + 1);
115 int getMTU()
override {
117 if (max_transfer_size == 0) {
118 int peer_max_transfer_size =
119 p_server->getPeerMTU(p_server->getConnId()) - BLE_MTU_OVERHEAD;
120 max_transfer_size = std::min(BLE_MTU - BLE_MTU, peer_max_transfer_size);
122 LOGI(
"max_transfer_size: %d", max_transfer_size);
124 return max_transfer_size;
127 void setupBLEService() {
131 if (p_service ==
nullptr) {
132 p_service = p_server->createService(BLE_AUDIO_SERVICE_UUID);
134 ch01_char = p_service->createCharacteristic(
135 BLE_CH1_UUID, BLECharacteristic::PROPERTY_READ );
136 ch01_desc.setValue(
"Channel 1");
137 ch01_char->addDescriptor(&ch01_desc);
138 ch01_char->setCallbacks(
this);
140 ch02_char = p_service->createCharacteristic(
141 BLE_CH2_UUID, BLECharacteristic::PROPERTY_WRITE);
142 ch02_desc.setValue(
"Channel 2");
143 ch02_char->addDescriptor(&ch02_desc);
144 ch02_char->setCallbacks(
this);
147 if (is_audio_info_active && info_char ==
nullptr) {
149 info_char = p_service->createCharacteristic(
150 BLE_INFO_UUID, BLECharacteristic::PROPERTY_NOTIFY |
151 BLECharacteristic::PROPERTY_READ |
152 BLECharacteristic::PROPERTY_NOTIFY |
153 BLECharacteristic::PROPERTY_INDICATE);
154 info_desc.setValue(
"Audio Info");
155 info_char->addDescriptor(&info_desc);
156 info_char->setCallbacks(
this);
164 if (info_char !=
nullptr) {
165 writeAudioInfoCharacteristic(info);
170 void onConnect(BLEServer *pServer)
override {
174 void onDisconnect(BLEServer *pServer)
override {
176 BLEDevice::startAdvertising();
180 void onWrite(BLECharacteristic *pCharacteristic)
override {
184 auto value = pCharacteristic->getValue();
185 if (pCharacteristic->getUUID().toString() == BLE_INFO_UUID) {
188 receiveAudio((uint8_t *)&value[0], value.length());
193 void onRead(BLECharacteristic *pCharacteristic)
override {
196 auto uuid = pCharacteristic->getUUID().toString();
197 if (uuid == BLE_CH1_UUID || uuid == BLE_CH2_UUID) {
199 int len = std::min(getMTU() - BLE_MTU_OVERHEAD, (
int)transmit_buffer.
available());
201 len = transmit_buffer_sizes.
read();
203 LOGD(
"%s: len: %d, buffer: %d", uuid.c_str(), len,
204 transmit_buffer.
size());
207 pCharacteristic->setValue(tmp, len);
211 void setupTXBuffer() {
212 if (transmit_buffer.
size() == 0) {
213 LOGI(
"Setting transmit_buffer to %d for mtu %d", RX_BUFFER_SIZE, getMTU());
214 transmit_buffer.resize(TX_BUFFER_SIZE);
216 transmit_buffer_sizes.resize(TX_COUNT);
221 void setupRXBuffer() {
222 if (receive_buffer.
size() == 0) {
223 LOGI(
"Setting receive_buffer to %d for mtu %d", RX_BUFFER_SIZE, getMTU());
224 receive_buffer.resize(RX_BUFFER_SIZE);
226 receive_sizes.resize(RX_COUNT);
231 size_t getReadSize(
size_t dataSize) {
232 size_t read_size = dataSize;
236 read_size = receive_sizes.
read();
238 if (dataSize < read_size) {
239 LOGE(
"read size too small: %d - it must be >= %d", dataSize, read_size);
242 if (receive_buffer.
available() < read_size) {
243 LOGE(
"missing data in buffer");