From 495e104ad8413a163cc6afcd7a8bd4b6fc345ee5 Mon Sep 17 00:00:00 2001 From: Bang Dao Date: Thu, 8 Aug 2024 10:01:46 +0700 Subject: [PATCH 1/3] Add arduino esp32 bluetooth device script --- src/BLE/ERaBLEDevice.hpp | 183 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 src/BLE/ERaBLEDevice.hpp diff --git a/src/BLE/ERaBLEDevice.hpp b/src/BLE/ERaBLEDevice.hpp new file mode 100644 index 0000000..750457f --- /dev/null +++ b/src/BLE/ERaBLEDevice.hpp @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include + +const int ledPin = 2; + +#define CODE "1d91d980-bbe4-4db4-8790-829a2fc62450" +#define DEVICE_NAME "E-Ra - Trung Thu" + +#define SERVICE_UUID "c459d382-3ecd-41a2-8769-c502dbb88648" +#define PASSWORD "f01f1e6b-e404-4534-bdfd-58af0e1fbb59" +#define CHARACTERISTIC_CONFIRM_CODE_UUID "6ee26cfb-b42f-43ae-9ecf-f70d84bbd64f" +#define CHARACTERISTIC_CONTROL_UUID "f0e7aa38-e466-42af-b4c7-5e6ec5c9a614" + + +char** verifiedCodes = new char*[5]; // max +u_int8_t verifiedCount = 0; +LinkedList verifiedConnectionId = LinkedList(); +BLEServer *pServer = nullptr; + + +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { + Serial.print("Connected BLE"); + Serial.println(param->connect.conn_id); + pServer->startAdvertising(); + }; + void onDisconnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { + Serial.print("Disconnected BLE"); + Serial.println(param->connect.conn_id); + pServer->startAdvertising(); + verifiedConnectionId.remove(param->connect.conn_id); + } +}; + + +class ControlCallbacks: public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t* param) { + int size = verifiedConnectionId.size(); + bool hasPermission = false; + for (int i = 0; i < size; i++) { + if (verifiedConnectionId.get(i) == param->connect.conn_id) { + hasPermission = true; + break; + } + } + if (!hasPermission) { + Serial.println("NO PERMISSION"); + return; + } + std::string message = pCharacteristic->getValue(); + Serial.println(message.c_str()); + u_int8_t index = message.find(';'); // ; reduce message size because bluetooth is slow + const char* pinStr = message.substr(0, index).c_str(); + const char* value = message.substr(index + 1).c_str(); + + // handle case virtual pin later + u_int8_t pin = atoi(pinStr); + pinMode(pin, OUTPUT); // should put in setup or setup characteristic + digitalWrite(pin, atoi(value)); + } +}; + + +class ConfirmCallbacks: public BLECharacteristicCallbacks { + char currentVerificationCode[9]; + void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t* param) { + if (verifiedCount >= 5) { // reach max + pCharacteristic->setValue("Max connections."); + pCharacteristic->notify(); + return; + } + + + + + std::string value = pCharacteristic->getValue(); + + Serial.println(value.c_str()); + + if (value == "start") { + // random and write back + currentVerificationCode[0] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[1] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[2] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[3] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[4] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[5] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[6] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[7] = (char) (esp_random() % 26 + '0'); + currentVerificationCode[8] = 0; + + Serial.println(currentVerificationCode); + pCharacteristic->setValue(currentVerificationCode); + pCharacteristic->notify(); + } + + if (value.substr(0, 7) == "confirm") { + char code[36 + 8 + 1]; // uuid4 + random + endstring + for(int i = 0; i < 36; i++) { + code[i] = PASSWORD[i]; + } + for (int i = 0; i < 8; i++) { + code[36 + i] = currentVerificationCode[i]; + } + code[44] = 0; + + MD5Builder md5; + md5.begin(); + md5.add(code); + md5.calculate(); + + char* output = new char[33]; + md5.getChars(output); + + Serial.println("verified code"); + Serial.println(output); + + if (value.substr(7, 32) == output) { + digitalWrite(ledPin, HIGH); + char* confirmText = new char[11]; + confirmText[0] ='c'; + confirmText[1] ='o'; + confirmText[2] ='n'; + confirmText[3] ='f'; + confirmText[4] ='i'; + confirmText[5] ='r'; + confirmText[6] ='m'; + confirmText[7] ='e'; + confirmText[8] ='d'; + confirmText[9] = verifiedCount + '0'; + confirmText[10] = 0; + pCharacteristic->setValue(confirmText); // confirmed + verifiedConnectionId.add(param->connect.conn_id); + } else { + digitalWrite(ledPin, LOW); + + Serial.print("Disconnecting BLE"); + Serial.println(param->disconnect.conn_id); + pServer->disconnect(param->disconnect.conn_id); + delete output; + } + } + } +}; + +void setup() { + Serial.begin(9600); + pinMode(ledPin, OUTPUT); + + BLEDevice::init(DEVICE_NAME); + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + BLEService *pService = pServer->createService(SERVICE_UUID); + + BLECharacteristic *confirmCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_CONFIRM_CODE_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY + ); + confirmCharacteristic->setCallbacks(new ConfirmCallbacks()); + + + BLECharacteristic *controlCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_CONTROL_UUID, + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY + ); + controlCharacteristic->setCallbacks(new ControlCallbacks()); + + pService->start(); + BLEAdvertising *pAdvertising = pServer->getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->start(); +} + +void loop() { +} \ No newline at end of file From 861b15d73915757c503f0068fabc9dfeacea14e2 Mon Sep 17 00:00:00 2001 From: Bang Dao Date: Thu, 8 Aug 2024 10:03:11 +0700 Subject: [PATCH 2/3] Add comment --- src/BLE/ERaBLEDevice.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/BLE/ERaBLEDevice.hpp b/src/BLE/ERaBLEDevice.hpp index 750457f..2509474 100644 --- a/src/BLE/ERaBLEDevice.hpp +++ b/src/BLE/ERaBLEDevice.hpp @@ -5,15 +5,15 @@ #include #include -const int ledPin = 2; +const int ledPin = 2; // this is for debug, can remove -#define CODE "1d91d980-bbe4-4db4-8790-829a2fc62450" -#define DEVICE_NAME "E-Ra - Trung Thu" +#define CODE "1d91d980-bbe4-4db4-8790-829a2fc62450" // this is chip code, keeping there +#define DEVICE_NAME "E-Ra - Trung Thu" // this is nothing -#define SERVICE_UUID "c459d382-3ecd-41a2-8769-c502dbb88648" -#define PASSWORD "f01f1e6b-e404-4534-bdfd-58af0e1fbb59" -#define CHARACTERISTIC_CONFIRM_CODE_UUID "6ee26cfb-b42f-43ae-9ecf-f70d84bbd64f" -#define CHARACTERISTIC_CONTROL_UUID "f0e7aa38-e466-42af-b4c7-5e6ec5c9a614" +#define SERVICE_UUID "c459d382-3ecd-41a2-8769-c502dbb88648" // this is bluetooth address +#define PASSWORD "f01f1e6b-e404-4534-bdfd-58af0e1fbb59" // this is bluetooth password +#define CHARACTERISTIC_CONFIRM_CODE_UUID "6ee26cfb-b42f-43ae-9ecf-f70d84bbd64f" // this is E-Ra constant, not change +#define CHARACTERISTIC_CONTROL_UUID "f0e7aa38-e466-42af-b4c7-5e6ec5c9a614" // this is E-Ra constant, not change char** verifiedCodes = new char*[5]; // max From 8818dad71128b67c3022ea78dbd5e709917ea985 Mon Sep 17 00:00:00 2001 From: Bang Dao Date: Thu, 8 Aug 2024 10:07:35 +0700 Subject: [PATCH 3/3] Add more comment --- src/BLE/ERaBLEDevice.hpp | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/BLE/ERaBLEDevice.hpp b/src/BLE/ERaBLEDevice.hpp index 2509474..81f9d61 100644 --- a/src/BLE/ERaBLEDevice.hpp +++ b/src/BLE/ERaBLEDevice.hpp @@ -26,19 +26,20 @@ class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { Serial.print("Connected BLE"); Serial.println(param->connect.conn_id); - pServer->startAdvertising(); + pServer->startAdvertising(); // accepting more than 1 connection }; void onDisconnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { Serial.print("Disconnected BLE"); Serial.println(param->connect.conn_id); - pServer->startAdvertising(); - verifiedConnectionId.remove(param->connect.conn_id); + pServer->startAdvertising(); // accepting more than 1 connection + verifiedConnectionId.remove(param->connect.conn_id); // remove trusted connection } }; class ControlCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t* param) { + // check permission before control int size = verifiedConnectionId.size(); bool hasPermission = false; for (int i = 0; i < size; i++) { @@ -50,6 +51,7 @@ class ControlCallbacks: public BLECharacteristicCallbacks { if (!hasPermission) { Serial.println("NO PERMISSION"); return; + } std::string message = pCharacteristic->getValue(); Serial.println(message.c_str()); @@ -68,21 +70,18 @@ class ControlCallbacks: public BLECharacteristicCallbacks { class ConfirmCallbacks: public BLECharacteristicCallbacks { char currentVerificationCode[9]; void onWrite(BLECharacteristic *pCharacteristic, esp_ble_gatts_cb_param_t* param) { - if (verifiedCount >= 5) { // reach max + if (verifiedCount >= 5) { // hardware define max connection accept, this is not a big problem pCharacteristic->setValue("Max connections."); - pCharacteristic->notify(); + pCharacteristic->notify(); // no need to notify return; } - - - std::string value = pCharacteristic->getValue(); Serial.println(value.c_str()); if (value == "start") { - // random and write back + // random code and write back currentVerificationCode[0] = (char) (esp_random() % 26 + '0'); currentVerificationCode[1] = (char) (esp_random() % 26 + '0'); currentVerificationCode[2] = (char) (esp_random() % 26 + '0'); @@ -98,7 +97,7 @@ class ConfirmCallbacks: public BLECharacteristicCallbacks { pCharacteristic->notify(); } - if (value.substr(0, 7) == "confirm") { + if (value.substr(0, 7) == "confirm") { // using string for shorten message char code[36 + 8 + 1]; // uuid4 + random + endstring for(int i = 0; i < 36; i++) { code[i] = PASSWORD[i]; @@ -113,7 +112,7 @@ class ConfirmCallbacks: public BLECharacteristicCallbacks { md5.add(code); md5.calculate(); - char* output = new char[33]; + char* output = new char[33]; // can use char output[33] instead md5.getChars(output); Serial.println("verified code"); @@ -121,28 +120,16 @@ class ConfirmCallbacks: public BLECharacteristicCallbacks { if (value.substr(7, 32) == output) { digitalWrite(ledPin, HIGH); - char* confirmText = new char[11]; - confirmText[0] ='c'; - confirmText[1] ='o'; - confirmText[2] ='n'; - confirmText[3] ='f'; - confirmText[4] ='i'; - confirmText[5] ='r'; - confirmText[6] ='m'; - confirmText[7] ='e'; - confirmText[8] ='d'; - confirmText[9] = verifiedCount + '0'; - confirmText[10] = 0; - pCharacteristic->setValue(confirmText); // confirmed + pCharacteristic->setValue("confirmed"); verifiedConnectionId.add(param->connect.conn_id); } else { digitalWrite(ledPin, LOW); - Serial.print("Disconnecting BLE"); + Serial.print("Disconnecting BLE"); // not correct then disconnect Serial.println(param->disconnect.conn_id); pServer->disconnect(param->disconnect.conn_id); - delete output; } + delete output; } } };