re-advertise after disconnect (ESP32 & ESP32_NimBLE)

This commit is contained in:
lathoub 2021-09-22 22:42:12 +02:00
parent 927b3ac8be
commit e0afefb9a2
3 changed files with 155 additions and 134 deletions

View File

@ -170,6 +170,7 @@ protected:
{ {
if (_bleMidiTransport->_disconnectedCallback) if (_bleMidiTransport->_disconnectedCallback)
_bleMidiTransport->_disconnectedCallback(); _bleMidiTransport->_disconnectedCallback();
_central = nullptr; _central = nullptr;
} }

View File

@ -11,37 +11,37 @@ BEGIN_BLEMIDI_NAMESPACE
class BLEMIDI_ESP32 class BLEMIDI_ESP32
{ {
private: private:
BLEServer* _server = nullptr; BLEServer *_server = nullptr;
BLEAdvertising* _advertising = nullptr; BLEAdvertising *_advertising = nullptr;
BLECharacteristic* _characteristic = nullptr; BLECharacteristic *_characteristic = nullptr;
BLEMIDI_Transport<class BLEMIDI_ESP32>* _bleMidiTransport = nullptr;
friend class MyServerCallbacks; BLEMIDI_Transport<class BLEMIDI_ESP32> *_bleMidiTransport = nullptr;
friend class MyCharacteristicCallbacks;
friend class MyServerCallbacks;
friend class MyCharacteristicCallbacks;
protected: protected:
QueueHandle_t mRxQueue; QueueHandle_t mRxQueue;
public: public:
BLEMIDI_ESP32() BLEMIDI_ESP32()
{ {
}
bool begin(const char*, BLEMIDI_Transport<class BLEMIDI_ESP32>*);
void end()
{
} }
void write(uint8_t* buffer, size_t length) bool begin(const char *, BLEMIDI_Transport<class BLEMIDI_ESP32> *);
void end()
{
Serial.println("end");
}
void write(uint8_t *buffer, size_t length)
{ {
_characteristic->setValue(buffer, length); _characteristic->setValue(buffer, length);
_characteristic->notify(); _characteristic->notify();
} }
bool available(byte* pvBuffer) bool available(byte *pvBuffer)
{ {
return xQueueReceive(mRxQueue, pvBuffer, 0); // return immediately when the queue is empty return xQueueReceive(mRxQueue, pvBuffer, 0); // return immediately when the queue is empty
} }
@ -53,86 +53,97 @@ public:
} }
protected: protected:
void receive(uint8_t* buffer, size_t length) void receive(uint8_t *buffer, size_t length)
{ {
// parse the incoming buffer // parse the incoming buffer
_bleMidiTransport->receive(buffer, length); _bleMidiTransport->receive(buffer, length);
} }
void connected() void connected()
{ {
if (_bleMidiTransport->_connectedCallback) if (_bleMidiTransport->_connectedCallback)
_bleMidiTransport->_connectedCallback(); _bleMidiTransport->_connectedCallback();
} }
void disconnected() void disconnected()
{ {
if (_bleMidiTransport->_disconnectedCallback) if (_bleMidiTransport->_disconnectedCallback)
_bleMidiTransport->_disconnectedCallback(); _bleMidiTransport->_disconnectedCallback();
}
end();
}
}; };
class MyServerCallbacks: public BLEServerCallbacks { class MyServerCallbacks : public BLEServerCallbacks
{
public: public:
MyServerCallbacks(BLEMIDI_ESP32* bluetoothEsp32) MyServerCallbacks(BLEMIDI_ESP32 *bluetoothEsp32)
: _bluetoothEsp32(bluetoothEsp32) { : _bluetoothEsp32(bluetoothEsp32)
{
} }
protected: protected:
BLEMIDI_ESP32* _bluetoothEsp32 = nullptr; BLEMIDI_ESP32 *_bluetoothEsp32 = nullptr;
void onConnect(BLEServer*) { void onConnect(BLEServer *)
{
if (_bluetoothEsp32) if (_bluetoothEsp32)
_bluetoothEsp32->connected(); _bluetoothEsp32->connected();
}; };
void onDisconnect(BLEServer*) { void onDisconnect(BLEServer *server)
{
if (_bluetoothEsp32) if (_bluetoothEsp32)
_bluetoothEsp32->disconnected(); _bluetoothEsp32->disconnected();
}
server->getAdvertising()->start();
}
}; };
class MyCharacteristicCallbacks: public BLECharacteristicCallbacks { class MyCharacteristicCallbacks : public BLECharacteristicCallbacks
{
public: public:
MyCharacteristicCallbacks(BLEMIDI_ESP32* bluetoothEsp32) MyCharacteristicCallbacks(BLEMIDI_ESP32 *bluetoothEsp32)
: _bluetoothEsp32(bluetoothEsp32 ) { : _bluetoothEsp32(bluetoothEsp32)
{
} }
protected:
BLEMIDI_ESP32* _bluetoothEsp32 = nullptr;
void onWrite(BLECharacteristic * characteristic) { protected:
BLEMIDI_ESP32 *_bluetoothEsp32 = nullptr;
void onWrite(BLECharacteristic *characteristic)
{
std::string rxValue = characteristic->getValue(); std::string rxValue = characteristic->getValue();
if (rxValue.length() > 0) { if (rxValue.length() > 0)
_bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length()); {
_bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length());
} }
} }
}; };
bool BLEMIDI_ESP32::begin(const char* deviceName, BLEMIDI_Transport<class BLEMIDI_ESP32>* bleMidiTransport) bool BLEMIDI_ESP32::begin(const char *deviceName, BLEMIDI_Transport<class BLEMIDI_ESP32> *bleMidiTransport)
{ {
_bleMidiTransport = bleMidiTransport; _bleMidiTransport = bleMidiTransport;
BLEDevice::init(deviceName); BLEDevice::init(deviceName);
// To communicate between the 2 cores. // To communicate between the 2 cores.
// Core_0 runs here, core_1 runs the BLE stack // Core_0 runs here, core_1 runs the BLE stack
mRxQueue = xQueueCreate(64, sizeof(uint8_t)); // TODO Settings::MaxBufferSize mRxQueue = xQueueCreate(64, sizeof(uint8_t)); // TODO Settings::MaxBufferSize
_server = BLEDevice::createServer(); _server = BLEDevice::createServer();
_server->setCallbacks(new MyServerCallbacks(this)); _server->setCallbacks(new MyServerCallbacks(this));
// Create the BLE Service // Create the BLE Service
auto service = _server->createService(BLEUUID(SERVICE_UUID)); auto service = _server->createService(BLEUUID(SERVICE_UUID));
// Create a BLE Characteristic // Create a BLE Characteristic
_characteristic = service->createCharacteristic( _characteristic = service->createCharacteristic(
BLEUUID(CHARACTERISTIC_UUID), BLEUUID(CHARACTERISTIC_UUID),
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_WRITE_NR BLECharacteristic::PROPERTY_WRITE_NR);
);
// Add CCCD 0x2902 to allow notify // Add CCCD 0x2902 to allow notify
_characteristic->addDescriptor(new BLE2902()); _characteristic->addDescriptor(new BLE2902());
@ -143,25 +154,27 @@ bool BLEMIDI_ESP32::begin(const char* deviceName, BLEMIDI_Transport<class BLEMID
// Start the service // Start the service
service->start(); service->start();
// Start advertising // Start advertising
_advertising = _server->getAdvertising(); _advertising = _server->getAdvertising();
_advertising->addServiceUUID(service->getUUID()); _advertising->addServiceUUID(service->getUUID());
_advertising->setAppearance(0x00); _advertising->setAppearance(0x00);
_advertising->start(); _advertising->start();
Serial.println("begin");
return true; return true;
} }
/*! \brief Create an instance for ESP32 named <DeviceName> /*! \brief Create an instance for ESP32 named <DeviceName>
*/ */
#define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \ #define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \
BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32> BLE##Name(DeviceName); \ BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32> BLE##Name(DeviceName); \
MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32> &)BLE##Name); MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32> &)BLE##Name);
/*! \brief Create a default instance for ESP32 named BLE-MIDI /*! \brief Create a default instance for ESP32 named BLE-MIDI
*/ */
#define BLEMIDI_CREATE_DEFAULT_INSTANCE() \ #define BLEMIDI_CREATE_DEFAULT_INSTANCE() \
BLEMIDI_CREATE_INSTANCE("Esp32-BLE-MIDI", MIDI) BLEMIDI_CREATE_INSTANCE("Esp32-BLE-MIDI", MIDI)
END_BLEMIDI_NAMESPACE END_BLEMIDI_NAMESPACE

View File

@ -8,40 +8,39 @@ BEGIN_BLEMIDI_NAMESPACE
class BLEMIDI_ESP32_NimBLE class BLEMIDI_ESP32_NimBLE
{ {
private: private:
BLEServer* _server = nullptr; BLEServer *_server = nullptr;
BLEAdvertising* _advertising = nullptr; BLEAdvertising *_advertising = nullptr;
BLECharacteristic* _characteristic = nullptr; BLECharacteristic *_characteristic = nullptr;
BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE>* _bleMidiTransport = nullptr;
friend class MyServerCallbacks; BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE> *_bleMidiTransport = nullptr;
friend class MyCharacteristicCallbacks;
friend class MyServerCallbacks;
friend class MyCharacteristicCallbacks;
protected: protected:
QueueHandle_t mRxQueue; QueueHandle_t mRxQueue;
public: public:
BLEMIDI_ESP32_NimBLE() BLEMIDI_ESP32_NimBLE()
{ {
}
bool begin(const char*, BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE>*);
void end()
{
} }
void write(uint8_t* buffer, size_t length) bool begin(const char *, BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE> *);
void end()
{
}
void write(uint8_t *buffer, size_t length)
{ {
_characteristic->setValue(buffer, length); _characteristic->setValue(buffer, length);
_characteristic->notify(); _characteristic->notify();
} }
bool available(byte* pvBuffer) bool available(byte *pvBuffer)
{ {
// return 1 byte from the Queue // return 1 byte from the Queue
return xQueueReceive(mRxQueue, (void*)pvBuffer, 0); // return immediately when the queue is empty return xQueueReceive(mRxQueue, (void *)pvBuffer, 0); // return immediately when the queue is empty
} }
void add(byte value) void add(byte value)
@ -51,86 +50,94 @@ public:
} }
protected: protected:
void receive(uint8_t* buffer, size_t length) void receive(uint8_t *buffer, size_t length)
{ {
// forward the buffer so it can be parsed // forward the buffer so it can be parsed
_bleMidiTransport->receive(buffer, length); _bleMidiTransport->receive(buffer, length);
} }
void connected() void connected()
{ {
if (_bleMidiTransport->_connectedCallback) if (_bleMidiTransport->_connectedCallback)
_bleMidiTransport->_connectedCallback(); _bleMidiTransport->_connectedCallback();
} }
void disconnected() void disconnected()
{ {
if (_bleMidiTransport->_disconnectedCallback) if (_bleMidiTransport->_disconnectedCallback)
_bleMidiTransport->_disconnectedCallback(); _bleMidiTransport->_disconnectedCallback();
} }
}; };
class MyServerCallbacks: public BLEServerCallbacks { class MyServerCallbacks : public BLEServerCallbacks
{
public: public:
MyServerCallbacks(BLEMIDI_ESP32_NimBLE* bluetoothEsp32) MyServerCallbacks(BLEMIDI_ESP32_NimBLE *bluetoothEsp32)
: _bluetoothEsp32(bluetoothEsp32) { : _bluetoothEsp32(bluetoothEsp32)
{
} }
protected: protected:
BLEMIDI_ESP32_NimBLE* _bluetoothEsp32 = nullptr; BLEMIDI_ESP32_NimBLE *_bluetoothEsp32 = nullptr;
void onConnect(BLEServer*) { void onConnect(BLEServer *)
{
if (_bluetoothEsp32) if (_bluetoothEsp32)
_bluetoothEsp32->connected(); _bluetoothEsp32->connected();
}; };
void onDisconnect(BLEServer*) { void onDisconnect(BLEServer *)
{
if (_bluetoothEsp32) if (_bluetoothEsp32)
_bluetoothEsp32->disconnected(); _bluetoothEsp32->disconnected();
} }
}; };
class MyCharacteristicCallbacks: public BLECharacteristicCallbacks { class MyCharacteristicCallbacks : public BLECharacteristicCallbacks
{
public: public:
MyCharacteristicCallbacks(BLEMIDI_ESP32_NimBLE* bluetoothEsp32) MyCharacteristicCallbacks(BLEMIDI_ESP32_NimBLE *bluetoothEsp32)
: _bluetoothEsp32(bluetoothEsp32 ) { : _bluetoothEsp32(bluetoothEsp32)
{
} }
protected:
BLEMIDI_ESP32_NimBLE* _bluetoothEsp32 = nullptr;
void onWrite(BLECharacteristic * characteristic) { protected:
BLEMIDI_ESP32_NimBLE *_bluetoothEsp32 = nullptr;
void onWrite(BLECharacteristic *characteristic)
{
std::string rxValue = characteristic->getValue(); std::string rxValue = characteristic->getValue();
if (rxValue.length() > 0) { if (rxValue.length() > 0)
_bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length()); {
_bluetoothEsp32->receive((uint8_t *)(rxValue.c_str()), rxValue.length());
} }
} }
}; };
bool BLEMIDI_ESP32_NimBLE::begin(const char* deviceName, BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE>* bleMidiTransport) bool BLEMIDI_ESP32_NimBLE::begin(const char *deviceName, BLEMIDI_Transport<class BLEMIDI_ESP32_NimBLE> *bleMidiTransport)
{ {
_bleMidiTransport = bleMidiTransport; _bleMidiTransport = bleMidiTransport;
BLEDevice::init(deviceName); BLEDevice::init(deviceName);
// To communicate between the 2 cores. // To communicate between the 2 cores.
// Core_0 runs here, core_1 runs the BLE stack // Core_0 runs here, core_1 runs the BLE stack
mRxQueue = xQueueCreate(64, sizeof(uint8_t)); // TODO Settings::MaxBufferSize mRxQueue = xQueueCreate(64, sizeof(uint8_t)); // TODO Settings::MaxBufferSize
_server = BLEDevice::createServer(); _server = BLEDevice::createServer();
_server->setCallbacks(new MyServerCallbacks(this)); _server->setCallbacks(new MyServerCallbacks(this));
_server->advertiseOnDisconnect(true);
// Create the BLE Service // Create the BLE Service
auto service = _server->createService(BLEUUID(SERVICE_UUID)); auto service = _server->createService(BLEUUID(SERVICE_UUID));
// Create a BLE Characteristic // Create a BLE Characteristic
_characteristic = service->createCharacteristic( _characteristic = service->createCharacteristic(
BLEUUID(CHARACTERISTIC_UUID), BLEUUID(CHARACTERISTIC_UUID),
NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ |
NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE |
NIMBLE_PROPERTY::NOTIFY | NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::WRITE_NR NIMBLE_PROPERTY::WRITE_NR);
);
_characteristic->setCallbacks(new MyCharacteristicCallbacks(this)); _characteristic->setCallbacks(new MyCharacteristicCallbacks(this));
@ -145,19 +152,19 @@ bool BLEMIDI_ESP32_NimBLE::begin(const char* deviceName, BLEMIDI_Transport<class
_advertising->addServiceUUID(service->getUUID()); _advertising->addServiceUUID(service->getUUID());
_advertising->setAppearance(0x00); _advertising->setAppearance(0x00);
_advertising->start(); _advertising->start();
return true; return true;
} }
/*! \brief Create an instance for ESP32 named <DeviceName> /*! \brief Create an instance for ESP32 named <DeviceName>
*/ */
#define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \ #define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \
BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE> BLE##Name(DeviceName); \ BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE> BLE##Name(DeviceName); \
MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE> &)BLE##Name); MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ESP32_NimBLE> &)BLE##Name);
/*! \brief Create a default instance for ESP32 named BLE-MIDI /*! \brief Create a default instance for ESP32 named BLE-MIDI
*/ */
#define BLEMIDI_CREATE_DEFAULT_INSTANCE() \ #define BLEMIDI_CREATE_DEFAULT_INSTANCE() \
BLEMIDI_CREATE_INSTANCE("Esp32-NimBLE-MIDI", MIDI) BLEMIDI_CREATE_INSTANCE("Esp32-NimBLE-MIDI", MIDI)
END_BLEMIDI_NAMESPACE END_BLEMIDI_NAMESPACE