From edd2f21a399c09a4daaf095ea07c8e8d9669e473 Mon Sep 17 00:00:00 2001 From: lathoub <4082369+lathoub@users.noreply.github.com> Date: Sat, 4 Jun 2022 22:34:11 +0200 Subject: [PATCH] Update BLEMIDI_ArduinoBLE.h added : _midiChar.writeValue((uint8_t)0); otherwise the device will disconnect immediately --- src/hardware/BLEMIDI_ArduinoBLE.h | 195 +++++++++++++++--------------- 1 file changed, 100 insertions(+), 95 deletions(-) diff --git a/src/hardware/BLEMIDI_ArduinoBLE.h b/src/hardware/BLEMIDI_ArduinoBLE.h index 8a232bb..5209dfa 100644 --- a/src/hardware/BLEMIDI_ArduinoBLE.h +++ b/src/hardware/BLEMIDI_ArduinoBLE.h @@ -7,53 +7,49 @@ BEGIN_BLEMIDI_NAMESPACE -BLEService midiService(SERVICE_UUID); - -BLEStringCharacteristic midiChar(CHARACTERISTIC_UUID, // standard 16-bit characteristic UUID - BLERead | BLEWrite | BLENotify | BLEWriteWithoutResponse, 16); // remote clients will be able to get notifications if this characteristic changes - -template -class Fifo { +template +class Fifo +{ public: - const size_t size; //speculative feature, in case it's needed + const size_t size; // speculative feature, in case it's needed - Fifo(): size(rawSize) + Fifo() : size(rawSize) { - flush(); + flush(); } - T dequeue() + T dequeue() { numberOfElements--; nextOut %= size; - return raw[ nextOut++]; + return raw[nextOut++]; }; - - bool enqueue( T element ) + + bool enqueue(T element) { - if ( count() >= rawSize ) + if (count() >= rawSize) return false; numberOfElements++; nextIn %= size; raw[nextIn] = element; - nextIn++; //advance to next index + nextIn++; // advance to next index return true; }; T peek() const { - return raw[ nextOut % size]; + return raw[nextOut % size]; } void flush() { - nextIn = nextOut = numberOfElements = 0; + nextIn = nextOut = numberOfElements = 0; } - // how many elements are currently in the FIFO? - size_t count() { return numberOfElements; } + // how many elements are currently in the FIFO? + size_t count() { return numberOfElements; } private: size_t numberOfElements; @@ -65,56 +61,58 @@ private: template class BLEMIDI_ArduinoBLE { -private: - BLEMIDI_Transport, _Settings>* _bleMidiTransport; - BLEDevice* _central; +private: + BLEMIDI_Transport, _Settings> *_bleMidiTransport; + BLEDevice *_central; + + BLEService _midiService; + BLECharacteristic _midiChar; Fifo mRxBuffer; public: - BLEMIDI_ArduinoBLE() - { - } - - bool begin(const char*, BLEMIDI_Transport, _Settings>*); - - void end() + BLEMIDI_ArduinoBLE() : _midiService(SERVICE_UUID), + _midiChar(CHARACTERISTIC_UUID, BLERead | BLEWrite | BLENotify | BLEWriteWithoutResponse, _Settings::MaxBufferSize) { } - void write(uint8_t* buffer, size_t length) - { - // TODO: test length - ((BLECharacteristic)midiChar).writeValue(buffer, length); - } - - bool available(byte* pvBuffer) - { - #ifdef BLE_POLLING + bool begin(const char *, BLEMIDI_Transport, _Settings> *); - if (mRxBuffer.count() > 0) { + void end() + { + } + + void write(uint8_t *buffer, size_t length) + { + if (length > 0) + ((BLECharacteristic)_midiChar).writeValue(buffer, length); + } + + bool available(byte *pvBuffer) + { +#ifdef BLE_POLLING + if (mRxBuffer.count() > 0) + { *pvBuffer = mRxBuffer.dequeue(); - return true; } poll(); - - if (midiChar.written()) { - // auto buffer = midiChar.value(); - auto length = midiChar.valueLength(); - if (length > 0) { - auto buffer = midiChar.value().c_str(); - _bleMidiTransport->receive((byte*)buffer, length); - + if (_midiChar.written()) + { + auto length = _midiChar.valueLength(); + if (length > 0) + { + auto buffer = _midiChar.value(); + _bleMidiTransport->receive((byte *)buffer, length); } } return false; #endif #ifdef BLE_EVENTS BLE.poll(); - return false; + return false; #endif } @@ -125,59 +123,64 @@ public: } protected: - void receive(const unsigned char* buffer, size_t length) - { - // forward the buffer so it can be parsed - _bleMidiTransport->receive((uint8_t*)buffer, length); - } + void receive(const unsigned char *buffer, size_t length) + { + if (length > 0) + _bleMidiTransport->receive((uint8_t *)buffer, length); + } - bool poll() - { + bool poll() + { BLEDevice central = BLE.central(); - if (!central) { - if (_central) { + if (!central) + { + if (_central) + { BLEMIDI_ArduinoBLE::blePeripheralDisconnectHandler(*_central); _central = nullptr; } return false; } - if (!central.connected()) { + if (!central.connected()) return false; - } - if (nullptr == _central) { + if (nullptr == _central) + { BLEMIDI_ArduinoBLE::blePeripheralConnectHandler(central); _central = ¢ral; } - else { - if (*_central != central) { + else + { + if (*_central != central) + { BLEMIDI_ArduinoBLE::blePeripheralDisconnectHandler(*_central); BLEMIDI_ArduinoBLE::blePeripheralConnectHandler(central); _central = ¢ral; - } + } } return true; } - void blePeripheralConnectHandler(BLEDevice central) - { + void blePeripheralConnectHandler(BLEDevice central) + { _central = ¢ral; - if (_bleMidiTransport->_connectedCallback) - _bleMidiTransport->_connectedCallback(); - } + if (_bleMidiTransport->_connectedCallback) + _bleMidiTransport->_connectedCallback(); + } - void blePeripheralDisconnectHandler(BLEDevice central) - { - if (_bleMidiTransport->_disconnectedCallback) - _bleMidiTransport->_disconnectedCallback(); + void blePeripheralDisconnectHandler(BLEDevice central) + { + if (_bleMidiTransport->_disconnectedCallback) + _bleMidiTransport->_disconnectedCallback(); _central = nullptr; - } + } - void characteristicWritten(BLEDevice central, BLECharacteristic characteristic) { + void characteristicWritten(BLEDevice central, BLECharacteristic characteristic) + { auto buffer = characteristic.value(); auto length = characteristic.valueLength(); @@ -187,50 +190,52 @@ protected: }; template -bool BLEMIDI_ArduinoBLE<_Settings>::begin(const char* deviceName, BLEMIDI_Transport, _Settings>* bleMidiTransport) +bool BLEMIDI_ArduinoBLE<_Settings>::begin(const char *deviceName, BLEMIDI_Transport, _Settings> *bleMidiTransport) { - _bleMidiTransport = bleMidiTransport; + _bleMidiTransport = bleMidiTransport; // initialize the Bluetooth® Low Energy hardware - if (!BLE.begin()) + if (!BLE.begin()) return false; BLE.setLocalName(deviceName); - BLE.setAdvertisedService(midiService); - midiService.addCharacteristic(midiChar); - BLE.addService(midiService); + BLE.setAdvertisedService(_midiService); + _midiService.addCharacteristic(_midiChar); + BLE.addService(_midiService); + + // set the initial value for the characeristic: + // (when not set, the device will disconnect after 0.5 seconds) + _midiChar.writeValue((uint8_t)0); #ifdef BLE_EVENTS // assign event handlers for connected, disconnected to peripheral - BLE.setEventHandler(BLEConnected, BLEMIDI_ArduinoBLE::blePeripheralConnectHandler); + BLE.setEventHandler(BLEConnected, BLEMIDI_ArduinoBLE::blePeripheralConnectHandler); BLE.setEventHandler(BLEDisconnected, BLEMIDI_ArduinoBLE::blePeripheralDisconnectHandler); - midiChar.setEventHandler(BLEWritten, characteristicWritten); + _midiChar.setEventHandler(BLEWritten, characteristicWritten); #endif - /* Start advertising BLE. It will start continuously transmitting BLE - advertising packets and will be visible to remote BLE central devices - until it receives a new connection */ - - // start advertising + /* Start advertising BLE. It will start continuously transmitting BLE + advertising packets and will be visible to remote BLE central devices + until it receives a new connection */ BLE.advertise(); - + return true; } - /*! \brief Create an instance for ArduinoBLE +/*! \brief Create an instance for ArduinoBLE */ -#define BLEMIDI_CREATE_CUSTOM_INSTANCE(DeviceName, Name, _Settings) \ +#define BLEMIDI_CREATE_CUSTOM_INSTANCE(DeviceName, Name, _Settings) \ BLEMIDI_NAMESPACE::BLEMIDI_Transport, _Settings> BLE##Name(DeviceName); \ MIDI_NAMESPACE::MidiInterface, _Settings>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport, _Settings> &)BLE##Name); - /*! \brief Create an instance for ArduinoBLE +/*! \brief Create an instance for ArduinoBLE */ #define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \ - BLEMIDI_CREATE_CUSTOM_INSTANCE (DeviceName, Name, BLEMIDI_NAMESPACE::DefaultSettings) + BLEMIDI_CREATE_CUSTOM_INSTANCE(DeviceName, Name, BLEMIDI_NAMESPACE::DefaultSettings) - /*! \brief Create a default instance for ArduinoBLE named BLE-MIDI +/*! \brief Create a default instance for ArduinoBLE named BLE-MIDI */ #define BLEMIDI_CREATE_DEFAULT_INSTANCE() \ BLEMIDI_CREATE_INSTANCE("BLE-MIDI", MIDI)