arduino-audio-tools
Loading...
Searching...
No Matches
BLESerialClientESP32.h
Go to the documentation of this file.
1#pragma once
2
3#include <BLEDevice.h>
4#include <BLEScan.h>
5#include <BLEUtils.h>
7#include "BLESerialStream.h"
8
9namespace audio_tools {
10
21 public BLEClientCallbacks,
23 public:
28
29 void end() override {
30 TRACEI();
31 flush();
32 is_started = false;
33 is_setup = false;
34 is_found = false;
35 BLEDevice::deinit();
36 p_client = nullptr;
37 }
38
39 protected:
40 BLEClient *p_client = nullptr;
41 BLERemoteCharacteristic *ch01_char = nullptr; // read
42 BLERemoteCharacteristic *ch02_char = nullptr; // write
43 BLERemoteCharacteristic *info_char = nullptr;
44 BLEAdvertisedDevice advertised_device;
46 volatile bool is_found = false;
47 volatile bool is_setup = false;
48
50 static BLESerialClientESP32 *self = nullptr;
51 return self;
52 }
53
54 bool startClient(const char *localName) override {
55 if (!BLEDevice::init(localName)) return false;
56 BLEDevice::setMTU(max_transfer_size);
57 BLEScan *p_scan = BLEDevice::getScan();
58 p_scan->setAdvertisedDeviceCallbacks(this);
59 p_scan->setActiveScan(true);
60 startScan();
61 return true;
62 }
63
64 void startScan() {
65 BLEScan *p_scan = BLEDevice::getScan();
66 if (!p_scan->isScanning()) {
67 LOGI("BLESerial: scanning for %s", BLE_SERIAL_SERVICE_UUID);
68 // scan in the background until the server was found
69 p_scan->start(0, nullptr, false);
70 }
71 }
72
73 bool isConnected() override {
74 return is_setup && p_client != nullptr && p_client->isConnected();
75 }
76
77 int getMTU() override {
78 int result = max_transfer_size;
79 if (isConnected()) {
80 int mtu = p_client->getMTU();
81 if (mtu > 0 && mtu < result) result = mtu;
82 }
83 return result;
84 }
85
86 bool connect() override {
87 if (!is_found) {
88 startScan();
89 return false;
90 }
91 TRACEI();
92
93 if (p_client == nullptr) {
94 p_client = BLEDevice::createClient();
95 p_client->setClientCallbacks(this);
96 }
97
98 // connect to the BLE server
99 LOGI("BLESerial: connecting to %s",
100 advertised_device.getAddress().toString().c_str());
101 if (!p_client->connect(&advertised_device)) {
102 LOGE("BLESerial: connect failed");
103 return reconnectLater();
104 }
106
107 // obtain a reference to the service in the remote BLE server
108 BLERemoteService *p_remote_service =
110 if (p_remote_service == nullptr) {
111 LOGE("BLESerial: service not found: %s", BLE_SERIAL_SERVICE_UUID);
112 return reconnectLater();
113 }
114
115 ch01_char = p_remote_service->getCharacteristic(BLE_CH1_UUID);
116 ch02_char = p_remote_service->getCharacteristic(BLE_CH2_UUID);
117 if (ch01_char == nullptr || ch02_char == nullptr) {
118 LOGE("BLESerial: characteristics not found");
119 return reconnectLater();
120 }
121
122 info_char = nullptr;
124 info_char = p_remote_service->getCharacteristic(BLE_INFO_UUID);
125 if (info_char == nullptr) {
126 LOGW("BLESerial: audio info not supported by server");
127 } else if (info_char->canNotify()) {
128 info_char->registerForNotify(notifyCallback);
129 }
130 }
131
132 LOGI("BLESerial: connected with mtu %d", getMTU());
133 is_setup = true;
134 return true;
135 }
136
139 is_found = false;
140 if (p_client != nullptr && p_client->isConnected()) p_client->disconnect();
141 startScan();
142 return false;
143 }
144
145 int readPacket(uint8_t *data, int maxLen) override {
146 if (!ch01_char->canRead()) return 0;
147 // auto: it changed from std::string to String
148 auto str = ch01_char->readValue();
149 int len = str.length();
150 if (len > maxLen) len = maxLen;
151 memcpy(data, str.c_str(), len);
152 return len;
153 }
154
155 bool writePacket(const uint8_t *data, int len) override {
156 if (!ch02_char->canWrite() && !ch02_char->canWriteNoResponse()) return false;
157 return ch02_char->writeValue((uint8_t *)data, len, write_confirmation_flag);
158 }
159
160 void writeAudioInfo(StrView str) override {
161 TRACEI();
162 if (!isConnected() || info_char == nullptr) return;
163 info_char->writeValue((uint8_t *)str.c_str(), str.length() + 1, true);
164 }
165
166 bool readAudioInfo() override {
167 if (info_char == nullptr || !info_char->canRead()) return false;
168 auto str = info_char->readValue();
169 receiveAudioInfo((const uint8_t *)str.c_str(), str.length());
170 return str.length() > 0;
171 }
172
173 void onConnect(BLEClient *pClient) override { TRACEI(); }
174
175 void onDisconnect(BLEClient *pClient) override {
176 TRACEI();
177 is_setup = false;
178 is_found = false;
179 }
180
182 void onResult(BLEAdvertisedDevice advertisedDevice) override {
183 if (advertisedDevice.haveServiceUUID() &&
184 advertisedDevice.isAdvertisingService(
185 BLEUUID(BLE_SERIAL_SERVICE_UUID))) {
186 LOGI("BLESerial: service '%s' found", BLE_SERIAL_SERVICE_UUID);
187 advertised_device = advertisedDevice;
188 is_found = true;
189 // we found what we are looking for
190 BLEDevice::getScan()->stop();
191 }
192 }
193
194 static void notifyCallback(BLERemoteCharacteristic *characteristic,
195 uint8_t *data, size_t length, bool isNotify) {
196 TRACEI();
198 if (self != nullptr && characteristic == self->info_char) {
199 self->receiveAudioInfo(data, length);
200 }
201 }
202};
203
204} // namespace audio_tools
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACEI()
Definition AudioLoggerIDF.h:32
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGE(...)
Definition AudioLoggerIDF.h:30
Generic BLE serial client logic which is independent of the BLE API. In BLE terminology the client is...
Definition BLESerialStream.h:383
void flush() override
Sends the buffered data which does not fill a complete packet.
Definition BLESerialStream.h:444
bool is_started
Definition BLESerialStream.h:476
bool write_confirmation_flag
Definition BLESerialStream.h:475
BLESerialPacketBuffer rx_buffer
Definition BLESerialStream.h:471
A BLE client that implements a serial protocol, so that it can be used to send and receive audio....
Definition BLESerialClientESP32.h:22
static void notifyCallback(BLERemoteCharacteristic *characteristic, uint8_t *data, size_t length, bool isNotify)
Definition BLESerialClientESP32.h:194
void writeAudioInfo(StrView str) override
Provides the audio info to the other side.
Definition BLESerialClientESP32.h:160
BLESerialClientESP32(int mtu=517)
Definition BLESerialClientESP32.h:24
bool writePacket(const uint8_t *data, int len) override
Writes a packet to the server.
Definition BLESerialClientESP32.h:155
BLERemoteCharacteristic * ch01_char
Definition BLESerialClientESP32.h:41
Mutex rx_mutex
Definition BLESerialClientESP32.h:45
static BLESerialClientESP32 *& selfBLESerialClientESP32()
Definition BLESerialClientESP32.h:49
BLEClient * p_client
Definition BLESerialClientESP32.h:40
void startScan()
Definition BLESerialClientESP32.h:64
void onResult(BLEAdvertisedDevice advertisedDevice) override
scanning results
Definition BLESerialClientESP32.h:182
void end() override
Definition BLESerialClientESP32.h:29
int readPacket(uint8_t *data, int maxLen) override
Reads the next packet (incl. header) from the server: returns the size.
Definition BLESerialClientESP32.h:145
volatile bool is_found
Definition BLESerialClientESP32.h:46
bool connect() override
Connects to the server if it was found: returns true if successful.
Definition BLESerialClientESP32.h:86
BLERemoteCharacteristic * info_char
Definition BLESerialClientESP32.h:43
bool startClient(const char *localName) override
Starts BLE and the scanning for the server.
Definition BLESerialClientESP32.h:54
void onDisconnect(BLEClient *pClient) override
Definition BLESerialClientESP32.h:175
bool readAudioInfo() override
Requests the audio info from the server: returns true if successful.
Definition BLESerialClientESP32.h:166
void onConnect(BLEClient *pClient) override
Definition BLESerialClientESP32.h:173
volatile bool is_setup
Definition BLESerialClientESP32.h:47
BLERemoteCharacteristic * ch02_char
Definition BLESerialClientESP32.h:42
bool isConnected() override
Returns true if we are connected.
Definition BLESerialClientESP32.h:73
BLEAdvertisedDevice advertised_device
Definition BLESerialClientESP32.h:44
bool reconnectLater()
disconnect and scan again
Definition BLESerialClientESP32.h:138
int getMTU() override
Effective MTU.
Definition BLESerialClientESP32.h:77
void setMutex(MutexBase *mutex)
Definition BLESerialStream.h:44
int max_transfer_size
Definition BLESerialStream.h:218
const char * BLE_SERIAL_SERVICE_UUID
Definition BLESerialStream.h:229
const char * BLE_INFO_UUID
Definition BLESerialStream.h:234
const char * BLE_CH2_UUID
Definition BLESerialStream.h:233
void receiveAudioInfo(const uint8_t *data, size_t size)
Process the audio info which was received from the other side.
Definition BLESerialStream.h:243
bool is_audio_info_active
Definition BLESerialStream.h:223
const char * BLE_CH1_UUID
Definition BLESerialStream.h:231
Mutex implemntation based on std::mutex.
Definition Mutex.h:16
A simple wrapper to provide string functions on existing allocated char*. If the underlying char* is ...
Definition StrView.h:29
virtual int length()
Definition StrView.h:460
virtual const char * c_str()
provides the string value as const char*
Definition StrView.h:456
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6