Hello! I am attempting to have a client ESP32 receive data from a server ESP32 connected to a BNO055 9DOF sensor. Both ESP32s are connected to 128x32 LCD displays to be able to see if the data matches. When running the client code, the client connects to the server, but receives a "stack smashing protect failure" when it reaches the getCharacteristic(BLEUUID). The server code works fine to advertise the data and has been read through a bluetooth phone app. I followed the near exact same syntax as an example code , but still running into this stack error. I have already ran the Exception Decoder tool and received the following results:
Here is the client code, any suggestions/hints as to what I can do is greatly appreciated:
//altium || eaglepcb
//CLIENT | CENTRAL | RECEIVER (screen)
//SDA GPIO21 SCK GPIO22 for ESP32-WROOM-32
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
#include <Adafruit_SSD1306.h>
#include <BLEDevice.h>
/* #include <BLEUtils.h>
#include <BLEServer.h> */
//BLE Server name (the other ESP32 name running the server sketch)
#define bleServerName "Right Glove"
//replaced upper bytes with 0s, first two bytes will be for services and second two bytes characteristics
//#define RGlove_SERVICE_UUID BLEUUID((uint16_t)0x0000)
static BLEUUID RGlove_SERVICE_UUID("5adad05b-dee6-4c49-9a60-ce8cf0fe6a19");
//configure the characteristic to understand what kind of data the server is expecting to receive from the client
//or what the client will be receiving from the server
//BLEUnsignedIntCharacteristic
/* #define CHAR_UUID_ORI1_X BLEUUID((uint16_t)0x0001)
#define CHAR_UUID_ORI1_Y BLEUUID((uint16_t)0x0002)
#define CHAR_UUID_ORI1_Z BLEUUID((uint16_t)0x0003)
#define CHAR_UUID_ACC1_X BLEUUID((uint16_t)0x0101)
#define CHAR_UUID_ACC1_Y BLEUUID((uint16_t)0x0102)
#define CHAR_UUID_ACC1_Z BLEUUID((uint16_t)0x0103) */
static BLEUUID CHAR_UUID_ORI1_X("5adad051-dee6-4c49-9a60-ce8cf0fe6a19");
static BLEUUID CHAR_UUID_ORI1_Y("5adad052-dee6-4c49-9a60-ce8cf0fe6a19");
static BLEUUID CHAR_UUID_ORI1_Z("5adad053-dee6-4c49-9a60-ce8cf0fe6a19");
static BLEUUID CHAR_UUID_ACC1_X("5adad054-dee6-4c49-9a60-ce8cf0fe6a19");
static BLEUUID CHAR_UUID_ACC1_Y("5adad055-dee6-4c49-9a60-ce8cf0fe6a19");
static BLEUUID CHAR_UUID_ACC1_Z("5adad056-dee6-4c49-9a60-ce8cf0fe6a19");
//Flags stating if should begin connecting and if the connection is up
static bool doConnect = false;
static bool connected = false;
//Address of the peripheral device. Address will be found during scanning...
static BLEAddress *pServerAddress;
//Characteristicd that we want to read
static BLERemoteCharacteristic* ORI1_CHAR_X;
static BLERemoteCharacteristic* ORI1_CHAR_Y;
static BLERemoteCharacteristic* ORI1_CHAR_Z;
static BLERemoteCharacteristic* ACC1_CHAR_X;
static BLERemoteCharacteristic* ACC1_CHAR_Y;
static BLERemoteCharacteristic* ACC1_CHAR_Z;
//Activate notify
const uint8_t notificationOn[] = {0x1, 0x0};
const uint8_t notificationOff[] = {0x0, 0x0};
/* SCREEN STUFF */
//screen dimensions
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
//Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//Variables to store orientation and acceleration values
char* acc1CharX; //originally char, might need to convert at rgb change
char* acc1CharY;
char* acc1CharZ;
char* ori1CharX;
char* ori1CharY;
char* ori1CharZ;
//Flags to check whether new temperature and humidity readings are available
bool newAcc1X = false;
bool newAcc1Y = false;
bool newAcc1Z = false;
bool newOri1X = false;
bool newOri1Y = false;
bool newOri1Z = false;
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
//Connect to the BLE Server that has the name, Service, and Characteristics
bool connectToServer(BLEAddress pAddress) {
BLEClient* pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyClientCallback()); //not sure
// Connect to the remove BLE Server.
pClient->connect(pAddress);
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(RGlove_SERVICE_UUID);
Serial.println(" 1");
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(RGlove_SERVICE_UUID.toString().c_str());
return (false);
}
Serial.println(" 11"); //testing
// Obtain a reference to the characteristics in the service of the remote BLE server.
ORI1_CHAR_X = pRemoteService->getCharacteristic(CHAR_UUID_ORI1_X); //STACK SMASHING FAILURE FROM HERE
Serial.println(" 2");
ORI1_CHAR_Y = pRemoteService->getCharacteristic(CHAR_UUID_ORI1_Y);
Serial.println(" 3");
ORI1_CHAR_Z = pRemoteService->getCharacteristic(CHAR_UUID_ORI1_Z);
Serial.println(" 4");
ACC1_CHAR_X = pRemoteService->getCharacteristic(CHAR_UUID_ACC1_X);
Serial.println(" 5");
ACC1_CHAR_Y = pRemoteService->getCharacteristic(CHAR_UUID_ACC1_Y);
Serial.println(" 6");
ACC1_CHAR_Z = pRemoteService->getCharacteristic(CHAR_UUID_ACC1_Z);
Serial.println(" 7");
if (ORI1_CHAR_Y == nullptr || ORI1_CHAR_Z == nullptr ||
ACC1_CHAR_X == nullptr || ACC1_CHAR_Y == nullptr || ACC1_CHAR_Z == nullptr) {
Serial.print("Failed to find our characteristic UUID");
return false;
}
Serial.println(" - Found our characteristics");
//Assign callback functions for the Characteristics
ORI1_CHAR_X->registerForNotify(ORI1_X_NotifyCallback);
ORI1_CHAR_Y->registerForNotify(ORI1_Y_NotifyCallback);
ORI1_CHAR_Z->registerForNotify(ORI1_Z_NotifyCallback);
ACC1_CHAR_X->registerForNotify(ACC1_X_NotifyCallback);
ACC1_CHAR_Y->registerForNotify(ACC1_Y_NotifyCallback);
ACC1_CHAR_Z->registerForNotify(ACC1_Z_NotifyCallback);
connected = true; //not sure
return true;
}
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.getName() == bleServerName) { //Check if the name of the advertiser matches
advertisedDevice.getScan()->stop(); //Scan can be stopped, we found what we are looking for
pServerAddress = new BLEAddress(advertisedDevice.getAddress()); //Address of advertiser is the one we need
doConnect = true; //Set indicator, stating that we are ready to connect
Serial.println("Device found. Connecting!");
}
}
};
//When the BLE Server sends a new reading with the notify property
static void ORI1_X_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("OXNC1"); //FOR TESTING
ori1CharX = (char*)pData; //callback used to use (char*)
newOri1X = true;
Serial.println("OXNC2"); //FOR TESTING
display.setCursor(0, 10);
display.print((char*)pData);
Serial.print("ORIENTATION X: ");
Serial.print((char*)pData);
display.display();
}
static void ORI1_Y_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("OYNC1"); //FOR TESTING
ori1CharY = (char*)pData;
newOri1Y = true;
Serial.println("OYNC2"); //FOR TESTING
display.setCursor(0, 10);
display.print((char*)pData);
Serial.print("ORIENTATION Y: ");
Serial.print((char*)pData);
display.display();
}
static void ORI1_Z_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("OZNC1"); //FOR TESTING
ori1CharZ = (char*)pData;
newOri1Z = true;
Serial.println("OZNC2"); //FOR TESTING
display.setCursor(0, 10);
display.print((char*)pData);
Serial.print("ORIENTATION Z: ");
Serial.print((char*)pData);
display.display();
}
static void ACC1_X_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("AXNC1"); //FOR TESTING
acc1CharX = (char*)pData;
newAcc1X = true;
Serial.println("AXNC2"); //FOR TESTING
display.setCursor(0, 20);
display.print((char*)pData);
Serial.print("ACCELERATION X: ");
Serial.print((char*)pData);
display.display();
}
static void ACC1_Y_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("AYNC1"); //FOR TESTING
acc1CharY = (char*)pData;
newAcc1Y = true;
Serial.println("AYNC2"); //FOR TESTING
display.setCursor(0, 20);
display.print((char*)pData);
Serial.print("ACCELERATION Y: ");
Serial.print((char*)pData);
display.display();
}
static void ACC1_Z_NotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
//store value
Serial.println("AZNC1"); //FOR TESTING
acc1CharZ = (char*)pData;
newAcc1Z = true;
Serial.println("AZNC2"); //FOR TESTING
display.setCursor(0, 20);
display.print((char*)pData);
Serial.print("ACCELERATION Z: ");
Serial.print((char*)pData);
display.display();
}
void setup() {
//Start serial communication
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
//screen initialization
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("CLIENT");
display.display();
//Init BLE device
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 30 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
}
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
//Activate the Notify property of each Characteristic
ORI1_CHAR_X->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("OX Desc"); //for testing (delete after)
ORI1_CHAR_Y->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("OY Desc"); //for testing (delete after)
ORI1_CHAR_Z->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("OZ Desc"); //for testing (delete after)
ACC1_CHAR_X->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("AX Desc"); //for testing (delete after)
ACC1_CHAR_Y->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("AY Desc"); //for testing (delete after)
ACC1_CHAR_Z->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
Serial.println("AZ Desc"); //for testing (delete after)
display.setTextSize(1.3);
display.setCursor(0,25);
display.print("CONNECTED");
connected = true;
} else {
Serial.println("We have failed to connect to the server; Restart your device to scan for nearby BLE server again.");
}
doConnect = false;
}
//delay(1000); // Delay a second between loops.
}