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
-
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