Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restart peripheral service causes crash #530

Closed
sdetweil opened this issue Apr 18, 2023 · 4 comments
Closed

restart peripheral service causes crash #530

sdetweil opened this issue Apr 18, 2023 · 4 comments

Comments

@sdetweil
Copy link

in my business solution

  1. don't advertise til app is detected (scan)
  2. the UUID text means something (advertise)
  3. given an additional sensor triggers, change the advertised UUID

on ArduinoBLE and ESP32 BLE I have to basically destroy all the setup
undo the service , and characteristics, and server
and rebuild them.

issues

  1. BLEservice->start(), doesn't have a stop().
  2. BLEserver doesn't have a delete
changed
14:17:09.729 -> new service string=32179901-27b9-42f0-82aa-2e951747bbf9
14:17:09.729 -> after UUID create
14:17:09.729 -> add service
14:17:09.729 -> ble server
14:17:09.729 -> after server create
14:17:09.729 -> config as string={"config":{"gender":3,"type":2,"subtype":"99","sequence":23,"td":227,"UWBSerial":"12345678"}}
14:17:09.729 -> config length=93
14:17:09.729 -> after characteristic setCallbacks 
14:17:09.729 -> after service start
14:17:09.766 -> after advertising setup
14:17:09.766 -> restart advertising after resetup
14:17:09.766 -> Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
14:17:09.766 -> 
14:17:09.766 -> Core  1 register dump:
14:17:09.766 -> PC      : 0x400dc86c  PS      : 0x00060230  A0      : 0x800dcb52  A1      : 0x3ffc8ce0  
14:17:09.766 -> A2      : 0x00000020  A3      : 0x00000000  A4      : 0x3ffcda58  A5      : 0x3ffcd780  
14:17:09.797 -> A6      : 0x00000001  A7      : 0x00000000  A8      : 0x00000020  A9      : 0x3ffcd770  
14:17:09.797 -> A10     : 0x3ffcda68  A11     : 0x00000008  A12     : 0x00000000  A13     : 0xffffffff  
14:17:09.797 -> A14     : 0x400dc630  A15     : 0x00000000  SAR     : 0x0000001a  EXCCAUSE: 0x0000001c  
14:17:09.797 -> EXCVADDR: 0x00000020  LBEG    : 0x40090c2d  LEND    : 0x40090c3d  LCOUNT  : 0xfffffff7  
14:17:09.797 -> 
14:17:09.797 -> 
14:17:09.797 -> Backtrace: 0x400dc869:0x3ffc8ce0 0x400dcb4f:0x3ffc8d60 0x400d562b:0x3ffc8d90 0x400d3d56:0x3ffc8dd0 0x400d4abc:0x3ffc8e00 0x400d2fcf:0x3ffc8e20 0x400e86f1:0x3ffc8ec0

the code at time to change UUID

#ifdef ESP32
          BLEDevice::stopAdvertising();
          pAdvertising->removeServiceUUID(ourService->getUUID()); // will be added back by setupService()
          pBLEScanner->stop();
          #if USE_NIMBLE == 0
              ourService->stop();  // not available in Nimble
          #endif   
          delete ourService;   
          #if USE_NIMBLE == 0 
            delete pServer;        // no delete on server in Nimble
          #endif
          pServer=NULL;   // force new create (now 2?)
          setupService();
          Serial.println("restart advertising after resetup");
          BLEDevice::startAdvertising();    // <-  crash here 
          Serial.println("after restart advertising after resetup");
          advertising=true;

from the setupservice function

Serial.println("add service");
  #ifdef ESP32
    if(pServer == NULL){
      pServer = BLEDevice::createServer();
    }
    Serial.println("after server create");   
    ourService = pServer->createService(buffer);
  #else
    ourService= new BLEService(buffer); // BLE LED Service
  #endif
   
#ifdef ESP32
  LEDCharacteristic= ourService->createCharacteristic(
                      "9A61",
#if USE_NIMBLE
                     NIMBLE_PROPERTY::WRITE
#else                      
                      BLECharacteristic::PROPERTY_WRITE  
#endif                      
                    );
  LEDCharacteristic->setCallbacks(new MyCallbacks());                    
#else   
  LEDCharacteristic=new BLEByteCharacteristic("9A61", BLEWrite);
  ourService->addCharacteristic(*LEDCharacteristic);  
#endif
 
  String jsonString = JSON.stringify(configInfo);
  Serial.print("config as string=");  
  Serial.println(jsonString);
 
 Serial.print("config length=");
 Serial.println(jsonString.length());
#ifdef ESP32
 configCharacteristic= ourService->createCharacteristic(
                      "9AFF",
#if USE_NIMBLE                      
                      NIMBLE_PROPERTY::READ | 
                      NIMBLE_PROPERTY::WRITE
#else
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_READ
#endif                      
                    );
  configCharacteristic->setCallbacks(new MyCallbacks());       
   Serial.println("after characteristic setCallbacks ");               
  ourService->start();            . 
  Serial.println("after service start");         
#else
  configCharacteristic =  new BLEStringCharacteristic("9AFF", BLERead|BLEWrite, jsonString.length());  
  configCharacteristic->setEventHandler(BLERead, configCharacteristicRead);
  configCharacteristic->setValue(jsonString);
  ourService->addCharacteristic(*configCharacteristic);  
#endif

#ifdef ESP32
  if(pAdvertising == null){  // 1st time
     pAdvertising = BLEDevice::getAdvertising();
     pAdvertising->setScanResponse(true);
  } 
  pAdvertising->addServiceUUID(ourService->getUUID());  // was removed before second call
#else  
  BLE.setAdvertisedService(*ourService);
  BLE.addService(*ourService);
#endif

include setup

#ifdef ESP32
  #define USE_NIMBLE 1
  #if USE_NIMBLE 
    #include <NimBLEDevice.h>
  #else
    #include <BLEDevice.h>
    #include <BLEServer.h>
    #include <BLEUtils.h>
    #include <BLEScan.h>
    #include <BLEAdvertisedDevice.h>
  #endif
#else
  #include <ArduinoBLE.h>
#endif
@sdetweil
Copy link
Author

sdetweil commented May 5, 2023

I need to change the service and UUID being served, so I have decided to try a different approach, as BLEServer has add and remove service, I will create the services statically (well pointers to objects)

assign the 1st at startup
when the conditions change,
I have an array of 2 services, with a variable that controls which I use

      int trigger = !status;
      pServer->removeService(activeService[trigger], false);
      pServer->addService(activeService[status]);
      pAdvertising->addServiceUUID(activeService[status]->getUUID());
      pServer->startAdvertising();

this works, but shortly later there is a crash

13:19:52.712 -> reporting change of conditions
13:19:52.747 ->  need to restart the service with updated UUID
13:19:52.747 -> trigger=0
13:19:52.747 -> status=1
13:19:52.747 -> after restart advertising 
13:19:52.747 -> updated service
13:19:52.747 -> end of changed check
13:19:55.266 -> already advertising to our app
13:19:57.758 -> already advertising to our app
13:20:00.290 -> already advertising to our app
13:20:02.787 -> already advertising to our app

13:20:04.781 ->   some 12 seconds after the service changed  ---- I did bring up an iphone BLE Scanner app to check the UUID (which as correct)

13:20:04.781 -> assert failed: ble_svc_gap_init ble_svc_gap.c:302 (rc == 0)

the stack trace looks like this

Stack trace:

     0x40083d39:  panic_abort  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c: line 408'
     0x40092e01:  esp_system_abort  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c: line 137'
     0x40098a95:  __assert_func  at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/assert.c: line 85'
     0x400d7ca7:  ble_svc_gap_init  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/services/gap/src/ble_svc_gap.c: line 302 (discriminator 1)'
     0x400d57c1:  NimBLEServer::resetGATT()  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/NimBLEServer.cpp:720\n (inlined by) NimBLEServer::resetGATT() at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/NimBLEServer.cpp: line 713'
     0x400d5af6:  NimBLEServer::handleGapEvent(ble_gap_event*, void*)  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/NimBLEServer.cpp: line 395'
     0x400d9a31:  ble_gap_call_event_cb  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_gap.c: line 748'
     0x400da625:  ble_gap_conn_broken  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_gap.c: line 1306'
     0x400da64c:  ble_gap_rx_disconn_complete  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_gap.c: line 1334 (discriminator 4)'
     0x400de6ee:  ble_hs_hci_evt_disconn_complete  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs_hci_evt.c:209\n (inlined by) ble_hs_hci_evt_disconn_complete at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs_hci_evt.c: line 166'
     0x400de901:  ble_hs_hci_evt_process  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs_hci_evt.c: line 879'
     0x400dd275:  ble_hs_event_rx_hci_ev  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/nimble/host/src/ble_hs.c: line 548'
     0x400813ce:  ble_npl_event_run  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/porting/npl/freertos/include/nimble/nimble_npl_os.h:526\n (inlined by) nimble_port_run at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/nimble/porting/nimble/src/nimble_port.c: line 269'
     0x400d49fb:  NimBLEDevice::host_task(void*)  at /Users/sam/Documents/Arduino/libraries/NimBLE-Arduino/src/NimBLEDevice.cpp: line 83

I am using library 1.4.1

void
ble_svc_gap_init(void)
{
#if NIMBLE_BLE_CONNECT
    int rc;
#endif

    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

#if NIMBLE_BLE_CONNECT
    rc = ble_gatts_count_cfg(ble_svc_gap_defs);
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = ble_gatts_add_svcs(ble_svc_gap_defs);
    SYSINIT_PANIC_ASSERT(rc == 0);    //<----- this line did panic, rc = 1
#endif
}

called from

void NimBLEServer::resetGATT() {
    if(getConnectedCount() > 0) {
        return;
    }

    NimBLEDevice::stopAdvertising();
    ble_gatts_reset();
    ble_svc_gap_init();  // <--- here
    ble_svc_gatt_init();

    for(auto it = m_svcVec.begin(); it != m_svcVec.end(); ) {
        if ((*it)->m_removed > 0) {
            if ((*it)->m_removed == NIMBLE_ATT_REMOVE_DELETE) {
                delete *it;
                it = m_svcVec.erase(it);
            } else {
                ++it;
            }
            continue;
        }

        (*it)->start();
        ++it;
    }

@sdetweil
Copy link
Author

sdetweil commented May 5, 2023

no matter what I do, the client still sees both services advertised

in setup

// create and save a service instance
 activeService[index]= pServer->createService(ServiceUUID->c_str());  // <--- creating new service, on new server() instance
 // but remove it from the server
  pServer->removeService( activeService[index],true);

and then 
if(index==0){    // thru the loop on 1st or last time, 0-->2, or 2--->0
    #ifdef ESP32             
      if (pAdvertising == null) {
        pAdvertising = BLEDevice::getAdvertising(); // init the advertising pointer
        pAdvertising->setScanResponse(true); // set scan response (one time) 
      }
      pAdvertising->addServiceUUID(activeService[index]->getUUID()); add this uuid to the adverting data... (but its supposedly not added to the server

then at runtime, on the switch

     int trigger - = !status;   // get the inverse of curent status (0 or 1 toggle) 
     pAdvertising->removeServiceUUID(activeService[trigger]->getUUID());  // remove it from advertising
      pServer->removeService(activeService[trigger],true);   // remove it from server, delete, not just hidden
      pServer->addService(activeService[status]);   // add the other service
      pAdvertising->addServiceUUID(activeService[status]->getUUID()); // add it to advertising
      pAdvertising->start();  // and start advertising...

client ble characteristic discover

{
  "status": "discovered",
  "services": [
    {
      "characteristics": [
        {
          "descriptors": [],
          "properties": {
            "write": true
          },
          "uuid": "9A61"
        },
        {
          "descriptors": [],
          "properties": {
            "write": true
          },
          "uuid": "9A62"
        },
        {
          "descriptors": [],
          "properties": {
            "write": true,
            "read": true
          },
          "uuid": "9AFF"
        },
        {
          "descriptors": [
            {
              "uuid": "2902"
            }
          ],
          "properties": {
            "notify": true,
            "read": true
          },
          "uuid": "2A05"
        },
        {
          "descriptors": [],
          "properties": {
            "read": true
          },
          "uuid": "9A63"
        }
      ],
      "uuid": "11050011-27B9-42F0-82AA-2E951747BBF9"
    },
    {
      "characteristics": [
        {
          "descriptors": [],
          "properties": {
            "write": true
          },
          "uuid": "9A61"
        },
        {
          "descriptors": [],
          "properties": {
            "write": true
          },
          "uuid": "9A62"
        },
        {
          "descriptors": [],
          "properties": {
            "write": true,
            "read": true
          },
          "uuid": "9AFF"
        },
        {
          "descriptors": [],
          "properties": {
            "notify": true,
            "read": true
          },
          "uuid": "2A05"
        },
        {
          "descriptors": [],
          "properties": {
            "read": true
          },
          "uuid": "9A63"
        }
      ],
      "uuid": "11050001-27B9-42F0-82AA-2E951747BBF9"
    }
  ],
  "name": "c8:f0:9e:75:1a:26",
  "address": "97CAB758-A70B-9867-D2D5-4C678EF5BD1D"
}

@h2zero
Copy link
Owner

h2zero commented May 14, 2023

I think #544 may be of help here.

@sdetweil
Copy link
Author

no need to delete/recreate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants