Update BLEMIDI_ArduinoBLE.h

added :     _midiChar.writeValue((uint8_t)0);

otherwise the device will disconnect immediately
This commit is contained in:
lathoub 2022-06-04 22:34:11 +02:00
parent 8c605fea37
commit edd2f21a39
1 changed files with 100 additions and 95 deletions

View File

@ -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<typename T, short rawSize>
class Fifo {
template <typename T, short rawSize>
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 _Settings>
class BLEMIDI_ArduinoBLE
{
private:
BLEMIDI_Transport<class BLEMIDI_ArduinoBLE<_Settings>, _Settings>* _bleMidiTransport;
BLEDevice* _central;
private:
BLEMIDI_Transport<class BLEMIDI_ArduinoBLE<_Settings>, _Settings> *_bleMidiTransport;
BLEDevice *_central;
BLEService _midiService;
BLECharacteristic _midiChar;
Fifo<byte, _Settings::MaxBufferSize> mRxBuffer;
public:
BLEMIDI_ArduinoBLE()
{
}
bool begin(const char*, BLEMIDI_Transport<class BLEMIDI_ArduinoBLE<_Settings>, _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<class BLEMIDI_ArduinoBLE<_Settings>, _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 = &central;
}
else {
if (*_central != central) {
else
{
if (*_central != central)
{
BLEMIDI_ArduinoBLE::blePeripheralDisconnectHandler(*_central);
BLEMIDI_ArduinoBLE::blePeripheralConnectHandler(central);
_central = &central;
}
}
}
return true;
}
void blePeripheralConnectHandler(BLEDevice central)
{
void blePeripheralConnectHandler(BLEDevice central)
{
_central = &central;
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 <class _Settings>
bool BLEMIDI_ArduinoBLE<_Settings>::begin(const char* deviceName, BLEMIDI_Transport<class BLEMIDI_ArduinoBLE<_Settings>, _Settings>* bleMidiTransport)
bool BLEMIDI_ArduinoBLE<_Settings>::begin(const char *deviceName, BLEMIDI_Transport<class BLEMIDI_ArduinoBLE<_Settings>, _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 <DeviceName>
/*! \brief Create an instance for ArduinoBLE <DeviceName>
*/
#define BLEMIDI_CREATE_CUSTOM_INSTANCE(DeviceName, Name, _Settings) \
#define BLEMIDI_CREATE_CUSTOM_INSTANCE(DeviceName, Name, _Settings) \
BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ArduinoBLE<_Settings>, _Settings> BLE##Name(DeviceName); \
MIDI_NAMESPACE::MidiInterface<BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ArduinoBLE<_Settings>, _Settings>, BLEMIDI_NAMESPACE::MySettings> Name((BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_ArduinoBLE<_Settings>, _Settings> &)BLE##Name);
/*! \brief Create an instance for ArduinoBLE <DeviceName>
/*! \brief Create an instance for ArduinoBLE <DeviceName>
*/
#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)