Core panic on using connect( advDevice ) from examples #560
frankcohen
started this conversation in
General
Replies: 1 comment 1 reply
-
You are accessing a nullptr somewhere in your code. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi Everyone, I'm getting a core panic crash when trying to connect to a BLE server. I'm using an ESP32-S3 and NimBLE-Arduino v 1.4.1. I am building/uploading using Arduino IDE 2.1.1 nightly. I copied my code below. I created my code by deriving from https://github.com/h2zero/NimBLE-Arduino/tree/release/1.4/examples/NimBLE_Client/NimBLE_Client.ino and https://github.com/h2zero/NimBLE-Arduino/blob/release/1.4/examples/NimBLE_Server/NimBLE_Server.ino. Here's what I see in the serial monitor:
. . .
CALLIOPE-F4: Server advertising started
CALLIOPE-F4: BLE Advertised Device found: Name: CALLIOPE-B4, Address: 60:55:f9:f5:c3:b5, serviceUUID: 7d9029fe-48d5-49e0-b9ad-8fd7dac70354
New client created
a
b
c
advDevice == nothing
CALLIOPE-F4: Failed to connect to server
CALLIOPE-F4: BLE Advertised Device found: Name: CALLIOPE-B4, Address: 60:55:f9:f5:c3:b5, serviceUUID: 7d9029fe-48d5-49e0-b9ad-8fd7dac70354
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x40056f17 PS : 0x00060530 A0 : 0x82007fc8 A1 : 0x3fcebe30
A2 : 0x3fcebe49 A3 : 0x00000000 A4 : 0x00000007 A5 : 0x3fcebe49
A6 : 0x02c982d8 A7 : 0x00ffffff A8 : 0x60023000 A9 : 0x60023040
A10 : 0x1d87af98 A11 : 0x000fffff A12 : 0x00000003 A13 : 0x3fca4c40
A14 : 0x00060023 A15 : 0x00000003 SAR : 0x0000000a EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0xffffffff
Backtrace: 0x40056f14:0x3fcebe30 |<-CORRUPTED
ELF file SHA256: 9c739da8436c0751
Rebooting...
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x28 (SPI_FAST_FLASH_BOOT)
Saved PC:0x420c07e2
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbe4
load:0x403cc700,len:0x2a38
entry 0x403c98d4
. . .
I get the panic when it executes this:
I'm going to continue debugging the problem. And I'll post a solution when I find it. Still, if anyone wants to give me pointers, feedback, and criticism, I'd be glad to receive it. Thanks.
-Frank
BLE.h contents:
#ifndef BLE
#define BLE
#include "Arduino.h"
#include <WiFi.h>
#include "config.h"
#include "secrets.h"
#include <NimBLEDevice.h>
class BLE
{
public:
BLE();
void begin();
void loop();
String getHeading();
void setHeading( String heading );
String getHeadingValue();
bool connectToServer();
private:
std::string devname;
int mycounter;
unsigned long serverWaitTime;
unsigned long clientWaitTime;
String heading;
};
#endif // BLE
BLE.cpp contents:
/*
Reflections, distributed entertainment device
Repository is at https://github.com/frankcohen/ReflectionsOS
Includes board wiring directions, server side components, examples, support
Licensed under GPL v3 Open Source Software
(c) Frank Cohen, All rights reserved. fcohen@starlingwatch.com
Read the license in the license.txt file that comes with this code.
I originally tried using the ESP32 blue BLE library. I ran out of memory. Switched to
NimBLE-Arduino, an Arduino fork of Apache NimBLE, a replacement open-source BLE library
https://github.com/h2zero/NimBLE-Arduino
https://www.arduino.cc/reference/en/libraries/nimble-arduino/
https://h2zero.github.io/esp-nimble-cpp/md__migration_guide.html#autotoc_md46
Todo:
Make this work among multiple Reflections devices
Balance the active scanning for battery life
*/
#include "BLE.h"
BLE::BLE(){}
// Server
static NimBLEServer* pServer;
static NimBLECharacteristic* pHeadingCharacteristic;
static boolean serverConnected;
static boolean clientConnected;
static String devicename;
static NimBLERemoteCharacteristic* pRemoteCharacteristic;
static NimBLEAdvertisedDevice* myDevice;
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static String remotename;
static NimBLEAdvertisedDevice* advDevice;
static uint32_t scanTime = 0; /** 0 = scan forever */
static BLEUUID serviceUUID( SERVICE_UUID_CALLIOPE );
static BLEUUID charUUID( CHARACTERISTIC_UUID_HEADING );
// Client
String BLE::getHeading()
{
return heading;
}
void BLE::setHeading( String _heading )
{
heading = _heading;
}
String BLE::getHeadingValue()
{
String myc = String( mycounter++ ) + heading;
std::string mys = myc.c_str();
return myc;
}
/** Callback to process the results of the last scan or restart it */
void scanEndedCB(NimBLEScanResults results){
Serial.println("Scan Ended");
}
/**
/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/*
*/
void onResult(BLEAdvertisedDevice* advertisedDevice)
{
//Serial.print( devicename );
//Serial.print(": BLE advertised device found: ");
//Serial.println(advertisedDevice->toString().c_str());
}
};
class ServerCallbacks: public NimBLEServerCallbacks {
};
class MyClientCallback: public BLEClientCallbacks {
void onConnect(BLEClient* pclient)
{
Serial.print( devicename );
Serial.println(": onConnect");
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.print( devicename );
Serial.println(": onDisconnect");
}
};
/** None of these are required as they will be handled by the library with defaults. **
** Remove as you see fit for your needs /
class ClientCallbacks: public NimBLEClientCallbacks {
void onConnect(NimBLEClient pClient) {
Serial.println("Connected");
/** After connection we should change the parameters if we don't need fast response times.
* These settings are 150ms interval, 0 latency, 450ms timout.
* Timeout should be a multiple of the interval, minimum is 100ms.
* I find a multiple of 3-5 * the interval works best for quick response/reconnect.
* Min interval: 120 * 1.25ms = 150, Max interval: 120 * 1.25ms = 150, 0 latency, 60 * 10ms = 600ms timeout
*/
pClient->updateConnParams(120,120,0,60);
};
};
/** Handler class for server characteristic actions */
class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
void onRead(NimBLECharacteristic* pCharacteristic){
Serial.print( devicename );
Serial.print(": BLE server ");
Serial.print(pCharacteristic->getUUID().toString().c_str());
Serial.print(": onRead(), value: ");
Serial.println(pCharacteristic->getValue().c_str());
};
};
/** Notification / Indication receiving handler callback */
void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
std::string str = (isNotify == true) ? "Notification" : "Indication";
str += " from ";
/** NimBLEAddress and NimBLEUUID have std::string operators /
str += std::string(pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress());
str += ": Service = " + std::string(pRemoteCharacteristic->getRemoteService()->getUUID());
str += ", Characteristic = " + std::string(pRemoteCharacteristic->getUUID());
str += ", Value = " + std::string((char)pData, length);
Serial.println(str.c_str());
}
/** Create a single global instance of the callback class to be used by all clients */
static ClientCallbacks clientCB;
bool BLE::connectToServer()
{
NimBLEClient* pClient = nullptr;
/** Check if we have a client we should reuse first /
if(NimBLEDevice::getClientListSize())
{
/ Special case when we already know this device, we send false as the
* second argument in connect() to prevent refreshing the service database.
* This saves considerable time and power.
*/
pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
if(pClient)
{
if(!pClient->connect(advDevice, false))
{
Serial.print( devicename );
Serial.println(": Reconnect failed");
return false;
}
Serial.print( devicename );
Serial.println(": Reconnected client");
}
else
{
pClient = NimBLEDevice::getDisconnectedClient();
}
}
/** No client to reuse? Create a new one. */
if( !pClient )
{
if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS)
{
Serial.println("Max clients reached - no more connections available");
return false;
}
}
}
static CharacteristicCallbacks chrCallbacks;
void BLE::begin()
{
devname = "CALLIOPE-";
std::string mac = WiFi.macAddress().c_str();
devname.append( mac.substr( 15, 2 ) );
NimBLEDevice::init( devname );
devicename = devname.c_str();
advDevice = nullptr;
mycounter = 0;
clientWaitTime = millis();
clientConnected = false;
serverWaitTime = millis();
serverConnected = false;
// Server set-up
pServer = NimBLEDevice::createServer();
pServer->setCallbacks( new ServerCallbacks() );
NimBLEService* pService = pServer -> createService( SERVICE_UUID_CALLIOPE );
pHeadingCharacteristic = pService -> createCharacteristic( CHARACTERISTIC_UUID_HEADING, NIMBLE_PROPERTY::READ );
pHeadingCharacteristic -> setCallbacks( &chrCallbacks );
pHeadingCharacteristic -> setValue( getHeadingValue() );
pService->start();
NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising -> addServiceUUID( pService -> getUUID() );
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMaxPreferred(0x12);
NimBLEDevice::startAdvertising();
Serial.print( devicename );
Serial.println(": Server advertising started");
// Client set-up
// 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 5 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan -> setAdvertisedDeviceCallbacks( new MyAdvertisedDeviceCallbacks() );
pBLEScan -> setInterval(1349);
pBLEScan -> setWindow(449);
pBLEScan -> setActiveScan(true);
pBLEScan -> start(5, false);
}
void BLE::loop()
{
// Server
if ((millis() - serverWaitTime) > 5000)
{
serverWaitTime = millis();
}
// Client
if ((millis() - clientWaitTime) > 5000)
{
clientWaitTime = millis();
}
}
Beta Was this translation helpful? Give feedback.
All reactions