Added characterisctic protecction in write(). Clean-up the code

This commit is contained in:
Roberto 2021-07-09 18:36:37 +02:00
parent 665f343d74
commit 5f7d493acd
1 changed files with 54 additions and 47 deletions

View File

@ -2,8 +2,8 @@
/* /*
############################################# #############################################
########### USER DEFINE BEGINING ############ ########## USER DEFINES BEGINNING ###########
####### Only modify these parameters ######## ####### Modify only these parameters ########
############################################# #############################################
*/ */
@ -12,13 +12,13 @@
*/ */
/** /**
* Set always the same name independiently of name server * Set always the same name independently of name server
*/ */
//#define BLEMIDI_CLIENT_FIXED_NAME "BleMidiClient" //#define BLEMIDI_CLIENT_FIXED_NAME "BleMidiClient"
#ifndef BLEMIDI_CLIENT_FIXED_NAME //Not modify #ifndef BLEMIDI_CLIENT_FIXED_NAME //Not modify
/** /**
* BLE name is composed by the nex way when client try to connect to speccific server: * When client tries to connect to specific server, BLE name is composed as follows:
* BLEMIDI_CLIENT_NAME_PREFIX + <NameServer/addrServer> + BLEMIDI_CLIENT_NAME_SUBFIX * BLEMIDI_CLIENT_NAME_PREFIX + <NameServer/addrServer> + BLEMIDI_CLIENT_NAME_SUBFIX
* *
* example: * example:
@ -32,7 +32,7 @@
#define BLEMIDI_CLIENT_NAME_SUBFIX "" #define BLEMIDI_CLIENT_NAME_SUBFIX ""
/** /**
* BLE name when it tries to connect to first midi server found. * When client tries to connect to the first midi server found:
*/ */
#define BLEMIDI_CLIENT_DEFAULT_NAME "BLEMIDI-CLIENT" #define BLEMIDI_CLIENT_DEFAULT_NAME "BLEMIDI-CLIENT"
#endif //Not modify #endif //Not modify
@ -48,23 +48,22 @@
*/ */
#define BLEMIDI_CLIENT_SECURITY_CAP BLE_HS_IO_NO_INPUT_OUTPUT #define BLEMIDI_CLIENT_SECURITY_CAP BLE_HS_IO_NO_INPUT_OUTPUT
/** Set security method. /** Set the security method.
* bonding * bonding
* man in the middle protection * man in the middle protection
* pair. secure connections * pair. secure connections
* *
* More info in nimBLE lib * More info in nimBLE lib
* *
* Uncomment that you need * Uncomment what you need
* These are the default values. * These are the default values.
*/ */
//#define BLEMIDI_CLIENT_BOND //#define BLEMIDI_CLIENT_BOND
//#define BLEMIDI_CLIENT_MITM //#define BLEMIDI_CLIENT_MITM
#define BLEMIDI_CLIENT_PAIR #define BLEMIDI_CLIENT_PAIR
/** /**
* This callback funtion defines what it must to do when server requieres PassKey. * This callback function defines what will be done when server requieres PassKey.
* Add your custom code here. * Add your custom code here.
*/ */
static uint32_t userOnPassKeyRequest() static uint32_t userOnPassKeyRequest()
@ -79,14 +78,15 @@ static uint32_t userOnPassKeyRequest()
return passkey; return passkey;
}; };
/* /*
###### BLE COMMUNICATION PARAMS ###### ###### BLE COMMUNICATION PARAMS ######
*/ */
/** Set connection parameters: /** Set connection parameters:
* If only use one connection, put recomended BLE server param communication (you may scan it ussing "nRF Connect" app or other similar). * If you only use one connection, put recomended BLE server param communication
* (you may scan it ussing "nRF Connect" app or other similar apps).
* *
* If you use more than one connection use, for example, settings like 15ms interval, 0 latency, 120ms timout. * If you use more than one connection adjust, for example, settings like 15ms interval, 0 latency, 120ms timout.
* These settings may be safe for 3 clients to connect reliably, can go faster if you have less * These settings may be safe for 3 clients to connect reliably, set faster values if you have less
* connections. * connections.
* *
* Min interval (unit: 1.25ms): 12 * 1.25ms = 15 ms, * Min interval (unit: 1.25ms): 12 * 1.25ms = 15 ms,
@ -99,7 +99,6 @@ static uint32_t userOnPassKeyRequest()
#define BLEMIDI_CLIENT_COMM_LATENCY 0 #define BLEMIDI_CLIENT_COMM_LATENCY 0
#define BLEMIDI_CLIENT_COMM_TIMEOUT 400 //4000ms #define BLEMIDI_CLIENT_COMM_TIMEOUT 400 //4000ms
/* /*
############################################# #############################################
############ USER DEFINES END ############### ############ USER DEFINES END ###############
@ -129,7 +128,7 @@ BEGIN_BLEMIDI_NAMESPACE
#define BLEMIDI_CLIENT_PAIR_DUMMY 0x00 #define BLEMIDI_CLIENT_PAIR_DUMMY 0x00
#endif #endif
/** Set security method. /** Set the security method.
* bonding * bonding
* man in the middle protection * man in the middle protection
* pair. secure connections * pair. secure connections
@ -163,11 +162,15 @@ protected:
{ {
/** Ready to connect now */ /** Ready to connect now */
doConnect = true; doConnect = true;
/** Save the device reference in a global for the client to use*/ /** Save the device reference in a public variable the client can use*/
advDevice = *advertisedDevice; advDevice = *advertisedDevice;
/** stop scan before connecting */ /** stop scan before connecting */
NimBLEDevice::getScan()->stop(); NimBLEDevice::getScan()->stop();
} }
else
{
Serial.println("Name error");
}
} }
else else
{ {
@ -180,7 +183,7 @@ protected:
/** Define a funtion to handle the callbacks when scan ends */ /** Define a funtion to handle the callbacks when scan ends */
void scanEndedCB(NimBLEScanResults results); void scanEndedCB(NimBLEScanResults results);
/** Define the class that perform Client Midi (nimBLE) */ /** Define the class that performs Client Midi (nimBLE) */
class BLEMIDI_Client_ESP32 class BLEMIDI_Client_ESP32
{ {
private: private:
@ -195,7 +198,7 @@ private:
friend class AdvertisedDeviceCallbacks; friend class AdvertisedDeviceCallbacks;
friend class MyClientCallbacks; friend class MyClientCallbacks;
friend class MIDI_NAMESPACE::MidiInterface<BLEMIDI_Transport<BLEMIDI_Client_ESP32>, MySettings>;// friend class MIDI_NAMESPACE::MidiInterface<BLEMIDI_Transport<BLEMIDI_Client_ESP32>, MySettings>; //
AdvertisedDeviceCallbacks myAdvCB; AdvertisedDeviceCallbacks myAdvCB;
@ -221,7 +224,10 @@ public:
void write(uint8_t *data, uint8_t length) void write(uint8_t *data, uint8_t length)
{ {
if (myAdvCB.enableConnection) if (!myAdvCB.enableConnection)
return;
if (_characteristic == NULL)
return;
_characteristic->writeValue(data, length, true); _characteristic->writeValue(data, length, true);
} }
@ -230,13 +236,13 @@ public:
void add(byte value) void add(byte value)
{ {
// called from BLE-MIDI, to add it to a buffer here // called from BLE-MIDI, to add it to a buffer here
xQueueSend(mRxQueue, &value, portMAX_DELAY); xQueueSend(mRxQueue, &value, portMAX_DELAY/2);
} }
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 that it can be parsed
_bleMidiTransport->receive(buffer, length); _bleMidiTransport->receive(buffer, length);
} }
@ -262,7 +268,7 @@ protected:
bool connect(); bool connect();
}; };
/** Define the class that perform interrupts callbacks */ /** Define the class that performs interruption callbacks */
class MyClientCallbacks : public BLEClientCallbacks class MyClientCallbacks : public BLEClientCallbacks
{ {
public: public:
@ -300,7 +306,7 @@ protected:
_bluetoothEsp32->disconnected(); _bluetoothEsp32->disconnected();
} }
//Try reconnection or look for a new one //Try reconnection or search a new one
NimBLEDevice::getScan()->start(3, scanEndedCB); NimBLEDevice::getScan()->start(3, scanEndedCB);
} }
@ -338,7 +344,7 @@ bool BLEMIDI_Client_ESP32::begin(const char *deviceName, BLEMIDI_Transport<class
_bleMidiTransport = bleMidiTransport; _bleMidiTransport = bleMidiTransport;
std::string strDeviceName(deviceName); std::string strDeviceName(deviceName);
if (strDeviceName == "") // Connect to first midi server found if (strDeviceName == "") // Connect to the first midi server found
{ {
myAdvCB.specificTarget = false; myAdvCB.specificTarget = false;
myAdvCB.nameTarget = ""; myAdvCB.nameTarget = "";
@ -349,7 +355,7 @@ bool BLEMIDI_Client_ESP32::begin(const char *deviceName, BLEMIDI_Transport<class
strDeviceName = BLEMIDI_CLIENT_DEFAULT_NAME; strDeviceName = BLEMIDI_CLIENT_DEFAULT_NAME;
#endif #endif
} }
else // Connect to a specific name or addr else // Connect to a specific name or address
{ {
myAdvCB.specificTarget = true; myAdvCB.specificTarget = true;
myAdvCB.nameTarget = strDeviceName; myAdvCB.nameTarget = strDeviceName;
@ -368,7 +374,7 @@ bool BLEMIDI_Client_ESP32::begin(const char *deviceName, BLEMIDI_Transport<class
// Core_0 runs here, core_1 runs the BLE stack // Core_0 runs here, core_1 runs the BLE stack
mRxQueue = xQueueCreate(256, sizeof(uint8_t)); // TODO Settings::MaxBufferSize mRxQueue = xQueueCreate(256, sizeof(uint8_t)); // TODO Settings::MaxBufferSize
NimBLEDevice::setSecurityIOCap(BLEMIDI_CLIENT_SECURITY_CAP); // Attenction, may need passkey NimBLEDevice::setSecurityIOCap(BLEMIDI_CLIENT_SECURITY_CAP); // Attention, it may need a passkey
NimBLEDevice::setSecurityAuth(BLEMIDI_CLIENT_SECURITY_AUTH); NimBLEDevice::setSecurityAuth(BLEMIDI_CLIENT_SECURITY_AUTH);
/** Optional: set the transmit power, default is 3db */ /** Optional: set the transmit power, default is 3db */
@ -411,14 +417,17 @@ bool BLEMIDI_Client_ESP32::available(byte *pvBuffer)
/** Notification receiving handler callback */ /** Notification receiving handler callback */
void BLEMIDI_Client_ESP32::notifyCB(NimBLERemoteCharacteristic *pRemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) void BLEMIDI_Client_ESP32::notifyCB(NimBLERemoteCharacteristic *pRemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify)
{ {
if (this->_characteristic == pRemoteCharacteristic) //Redundant protection
{
if (uxQueueSpacesAvailable(mRxQueue) >= length) //Don't overflow the queue. If the queue is overflowed, comunication breaks out if (uxQueueSpacesAvailable(mRxQueue) >= length) //Don't overflow the queue. If the queue is overflowed, comunication breaks out
receive(pData, length); receive(pData, length);
}
} }
void BLEMIDI_Client_ESP32::scan() void BLEMIDI_Client_ESP32::scan()
{ {
// Retrieve a Scanner and set the callback we want to use to be informed when we // Retrieve a Scanner and set the callback you want to use to be informed when a new device is detected.
// have detected a new device. Specify that we want active scanning and start the // Specify that you want active scanning and start the
// scan to run for 3 seconds. // scan to run for 3 seconds.
myAdvCB.scanDone = true; myAdvCB.scanDone = true;
NimBLEScan *pBLEScan = BLEDevice::getScan(); NimBLEScan *pBLEScan = BLEDevice::getScan();
@ -439,8 +448,8 @@ bool BLEMIDI_Client_ESP32::connect()
Serial.println("Try Connection..."); Serial.println("Try Connection...");
using namespace std::placeholders; //<- for bind funtion in callback notification using namespace std::placeholders; //<- for bind funtion in callback notification
/** Check if we have a client we should reuse first / /** Check if we have a client we should reuse first
/ Special case when we already know this device * Special case when we already know this device
* This saves considerable time and power. * This saves considerable time and power.
*/ */
@ -450,7 +459,6 @@ bool BLEMIDI_Client_ESP32::connect()
{ {
if (_client->connect(&myAdvCB.advDevice, false)) if (_client->connect(&myAdvCB.advDevice, false))
{ {
//_client->updateConnParams(BLEMIDI_CLIENT_COMM_MIN_INTERVAL, BLEMIDI_CLIENT_COMM_MAX_INTERVAL, BLEMIDI_CLIENT_COMM_LATENCY, BLEMIDI_CLIENT_COMM_TIMEOUT);
if (_characteristic->canNotify()) if (_characteristic->canNotify())
{ {
if (!_characteristic->subscribe(true, std::bind(&BLEMIDI_Client_ESP32::notifyCB, this, _1, _2, _3, _4))) if (!_characteristic->subscribe(true, std::bind(&BLEMIDI_Client_ESP32::notifyCB, this, _1, _2, _3, _4)))
@ -485,7 +493,7 @@ bool BLEMIDI_Client_ESP32::connect()
_client->setClientCallbacks(new MyClientCallbacks(this), false); _client->setClientCallbacks(new MyClientCallbacks(this), false);
_client->setConnectionParams(BLEMIDI_CLIENT_COMM_MIN_INTERVAL, BLEMIDI_CLIENT_COMM_MAX_INTERVAL+10, BLEMIDI_CLIENT_COMM_LATENCY+1, BLEMIDI_CLIENT_COMM_TIMEOUT+10); _client->setConnectionParams(BLEMIDI_CLIENT_COMM_MIN_INTERVAL, BLEMIDI_CLIENT_COMM_MAX_INTERVAL + 10, BLEMIDI_CLIENT_COMM_LATENCY + 1, BLEMIDI_CLIENT_COMM_TIMEOUT + 10);
/** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */
_client->setConnectTimeout(15); _client->setConnectTimeout(15);
@ -497,7 +505,6 @@ bool BLEMIDI_Client_ESP32::connect()
Serial.println("Failed to connect, deleted client"); Serial.println("Failed to connect, deleted client");
return false; return false;
} }
vTaskDelay(100);
if (!_client->isConnected()) if (!_client->isConnected())
{ {
@ -506,7 +513,6 @@ bool BLEMIDI_Client_ESP32::connect()
_client = nullptr; _client = nullptr;
return false; return false;
} }
//_client->updateConnParams(BLEMIDI_CLIENT_COMM_MIN_INTERVAL, BLEMIDI_CLIENT_COMM_MAX_INTERVAL, BLEMIDI_CLIENT_COMM_LATENCY, BLEMIDI_CLIENT_COMM_TIMEOUT);
Serial.print("Connected to: "); Serial.print("Connected to: ");
Serial.print(myAdvCB.advDevice.getName().c_str()); Serial.print(myAdvCB.advDevice.getName().c_str());
@ -560,8 +566,9 @@ void scanEndedCB(NimBLEScanResults results)
} }
END_BLEMIDI_NAMESPACE END_BLEMIDI_NAMESPACE
/*! \brief Create an instance for ESP32 named "Prefix + <DeviceName> + Subfix"
It will try to connect to a specific server with equal name or addr than <DeviceName> /*! \brief Create an instance for ESP32 named <DeviceName>, and adviertise it like "Prefix + <DeviceName> + Subfix"
It will try to connect to a specific server with equal name or addr than <DeviceName>. If <DeviceName> is "", it will connect to first midi server
*/ */
#define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \ #define BLEMIDI_CREATE_INSTANCE(DeviceName, Name) \
BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_Client_ESP32> BLE##Name(DeviceName); \ BLEMIDI_NAMESPACE::BLEMIDI_Transport<BLEMIDI_NAMESPACE::BLEMIDI_Client_ESP32> BLE##Name(DeviceName); \