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

Question: can a client and server run at the same time? #298

Closed
paulhamsh opened this issue Oct 5, 2021 · 19 comments
Closed

Question: can a client and server run at the same time? #298

paulhamsh opened this issue Oct 5, 2021 · 19 comments

Comments

@paulhamsh
Copy link

I have seen this question asked before and it looked like 'yes, but you can't scan and advertise at the same time'

I want to create a server and client to sit between two devices. The aim is to get the server to mimic the services and characteristics of the end device, so I can intercept and change the commands on the way. But the current problem is that my code crashes with an abort() error.

I am using an M5 Stack Core 2.

My code is here: https://github.com/paulhamsh/BLEAppSpark
The client works by itself, and the server works by itself - just not together.

I am scanning, connecting to a client, building the server, then it crashes just as I advertise the server:

pAdvertising->start(); // start advertising

I had to move

pServer = NimBLEDevice::createServer();

to the start of setup() else it failed on an ASSERT when it ran that.
(C:\Users\Family\Documents\Arduino\libraries\NimBLE-Arduino\src\nimble\host\services\gap\src\ble_svc_gap.c, line 297, function: ble_svc_gap_init)

Is it possible? Am I missing a way to close the scan before starting the advertise?

I would appreciate any help.

**Example of the abort**

abort() was called at PC 0x400dcad4 on core 1

Backtrace: 0x40094110:0x3ffc6b20 0x40094341:0x3ffc6b40 0x400dcad4:0x3ffc6b60 0x400d9aed:0x3ffc6bb0 0x400d228a:0x3ffc6be0 0x400f1adb:0x3ffc6c70 0x40090529:0x3ffc6c90

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5816
entry 0x400806ac
@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

Code looks ok to me. Any chance you could provide logs with the debugging level set to debug?

@paulhamsh
Copy link
Author

paulhamsh commented Oct 5, 2021

Hi
Thanks - I've put a long log on my github repo, and a short version below.

I changed it to use the other BLE library and this bit works - it gets to having two connections but the other library doesn't have your nice onSubscribe method so I've lost some useful info!

D NimBLEServer: ">> createService - 0xffc0"
D NimBLEServer: "<< createService"
D NimBLEUUID: "Comparing UUIDs; type 16 to 16; UUID 0xffc1 to 0xffc2"
D NimBLEService: ">> start(): Starting service: UUID: 0xffc0, handle: 0xffff"
D NimBLEService: "Adding 2 characteristics for service UUID: 0xffc0, handle: 0xffff"
E NimBLEService: "ble_gatts_add_svcs, rc= 15, "
WAS OK TO HERE 8
D NimBLEAdvertising: ">> Advertising start: customAdvData: 0, customScanResponseData: 0"
E NimBLEServer: "ble_gatts_start; rc=15, "
abort() was called at PC 0x400debb7 on core 1

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

interesting, could you please try commenting out this line

it should be ok for testing to do this, the error code you have there is BLE_HS_EDONE, which is actually another success code, therefore there is no error here, just a bug that the check doesn't account for that.

@paulhamsh
Copy link
Author

I made the changes below, and get the abort as shown in the second table - seems like it isn't the abort commented out, but somehow asynchronous straight after it?

void NimBLEServer::start() {
    if(m_gattsStarted) {
        NIMBLE_LOGW(LOG_TAG, "Gatt server already started");
        return;
    }

    int rc = ble_gatts_start();
    if (rc != 0) {
        NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc,
                            NimBLEUtils::returnCodeToString(rc));
        // abort();
    }


NIMBLE_LOGE(LOG_TAG, "GOT HERE 1");

#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4)
NIMBLE_LOGE(LOG_TAG, "GOT HERE 1a");
    ble_gatts_show_local();
NIMBLE_LOGE(LOG_TAG, "GOT HERE 1b");

#endif
/*** Future use ***
  * TODO: implement service changed handling

NIMBLE_LOGE(LOG_TAG, "GOT HERE 2");

    ble_uuid16_t svc = {BLE_UUID_TYPE_16, 0x1801};
    ble_uuid16_t chr = {BLE_UUID_TYPE_16, 0x2a05};

NIMBLE_LOGE(LOG_TAG, "GOT HERE 3");
Found Spark - trying to connect....connected
Done Spark....
E NimBLEService: "ble_gatts_add_svcs, rc= 15, "
WAS OK TO HERE 8
E NimBLEServer: "ble_gatts_start; rc=15, "
E NimBLEServer: "GOT HERE 1"
abort() was called at PC 0x400dd7fb on core 1

Backtrace: 0x4009419c:0x3ffc6f60 0x400943cd:0x3ffc6f80 0x400dd7fb:0x3ffc6fa0 0x400da15e:0x3ffc6ff0 0x400d25d2:0x3ffc7020 0x400f338b:0x3ffc70b0 0x400905b5:0x3ffc70d0

Rebooting...
ets Jul 29 2019 12:21:46

@paulhamsh
Copy link
Author

paulhamsh commented Oct 5, 2021

Actually I was instrumenting commented out code above - oops!

Now it seems to crash here - at this abort which shows no error log:

    for(auto &svc : m_svcVec) {
        if(svc->m_removed == 0) {
NIMBLE_LOGW(LOG_TAG, "3");
            rc = ble_gatts_find_svc(&svc->getUUID().getNative()->u, &svc->m_handle);
NIMBLE_LOGW(LOG_TAG, "4");
            if(rc != 0) {
NIMBLE_LOGW(LOG_TAG, "5");
                abort();
            }
        }
Name Sparky
Found Spark - trying to connect....connected
Done Spark....
E NimBLEService: "ble_gatts_add_svcs, rc= 15, "
E NimBLEServer: "ble_gatts_start; rc=15, "
W NimBLEServer: "1"
W NimBLEServer: "2"
W NimBLEServer: "3"
W NimBLEServer: "4"
W NimBLEServer: "5"
abort() was called at PC 0x400dda10 on core 1

Backtrace: 0x4009419c:0x3ffc6eb0 0x400943cd:0x3ffc6ed0 0x400dda10:0x3ffc6ef0 0x400da2de:0x3ffc6f40 0x400d2629:0x3ffc6f70 0x400f3663:0x3ffc7000 0x400905b5:0x3ffc7020

Rebooting...
ets Jul 29 2019 12:21:46

I also changed my code to use a different service ID and characteristic IDs but the same happens - so it doesn't seem to be because I am using the same IDs in server and client.

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

Sorry I had stated the wrong error code. 15 == host busy. Which is strange, I wonder what it's doing at that time.

For a test, try deleting the client instead of disconnecting.

@paulhamsh
Copy link
Author

pClient_sp->deleteServices(); ?

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

At line 165 in your code change pClient_sp->disconnect(); to NimBLEDevice::deleteClient(pClient_sp);

@paulhamsh
Copy link
Author

Thanks, but the same result - my code never gets there. I added a Serial.println() to say if it ever reached that bit, but it doesn't.

@paulhamsh
Copy link
Author

paulhamsh commented Oct 5, 2021

Removing parts from the code, the server works even if after the scan.
But as soon as ->connect(&device) is included in the code, then it fails.
It I remove all the client code after that, it still fails.
If I remove that line and the client code after it, the server part works.

This is the failing version with the connect() still in

D NimBLEUUID: "Comparing UUIDs; type 16 to 16; UUID 0xffc0 to 0xffc0"
Found Spark - trying to connect....D NimBLEClient: ">> connect(f7:eb:ed:4e:47:07)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 11, MaxInterval: 19, Latency: 0, Timeout: 600"
D NimBLEClientCallbacks: "onConnParamsUpdateRequest: default"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=200"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
D NimBLEClientCallbacks: "onConnect: default"
D NimBLEClient: "<< connect()"
connected
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
Done Spark....
D NimBLEServer: ">> createService - 0xffc0"
D NimBLEServer: "<< createService"
D NimBLEUUID: "Comparing UUIDs; type 16 to 16; UUID 0xffc1 to 0xffc2"
D NimBLEService: ">> start(): Starting service: UUID: 0xffc0, handle: 0xffff"
D NimBLEService: "Adding 2 characteristics for service UUID: 0xffc0, handle: 0xffff"
E NimBLEService: "ble_gatts_add_svcs, rc= 15, "
D NimBLEAdvertising: ">> Advertising start: customAdvData: 0, customScanResponseData: 0"
E NimBLEServer: "ble_gatts_start; rc=15, "
abort() was called at PC 0x400dd46b on core 1

Backtrace: 0x40094198:0x3ffc6f10 0x400943c9:0x3ffc6f30 0x400dd46b:0x3ffc6f50 0x400da422:0x3ffc6fa0 0x400d2761:0x3ffc6fe0 0x400f35b7:0x3ffc7070 0x400905b1:0x3ffc7090

Rebooting...

So this code (commenting out the ->connect() and leaving the rest of the client code in, to fail if it wants, but it seems to pass through it without 'error' but also without connecting - as expected) allows the server code to work.

connected_sp = false;
  while (!connected_sp) {
    pResults = pScan->start(4);
    NimBLEUUID SPserviceUuid(C_SERVICE);

    Serial.println("------------------------------");
    for(i = 0; i < pResults.getCount()  && !connected_sp; i++) {
      device = pResults.getDevice(i);

      // Print info
      Serial.print("Name ");
      Serial.println(device.getName().c_str());

      if (device.isAdvertisingService(SPserviceUuid)) {
        Serial.print("Found Spark - trying to connect....");
        //if(pClient_sp->connect(&device)) {
          connected_sp = true;
          Serial.println("connected");
        // }
      }
    }

    if (connected_sp) {
      pService_sp = pClient_sp->getService(SPserviceUuid);
      if (pService_sp != nullptr) {
        pSender_sp   = pService_sp->getCharacteristic(C_CHAR1);
        pReceiver_sp = pService_sp->getCharacteristic(C_CHAR2);
        if (pReceiver_sp && pReceiver_sp->canNotify()) {
          if (!pReceiver_sp->subscribe(true, notifyCB_sp, true)) {
            connected_sp = false;
            Serial.println("Spark not ok");
            //pClient_sp->disconnect();
            NimBLEDevice::deleteClient(pClient_sp);
          }
        }
      }
    }

  }

Gives this:

Started
I NimBLEDevice: "BLE Host Task Started"
I NimBLEDevice: "NimBle host synced."
D NimBLEScan: ">> start(duration=4)"
D NimBLEScan: "<< start()"
I NimBLEScan: "New advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "New advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "New advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "New advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "Updated advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "New advertiser: 5e:ed:cc:f4:2b:9b"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "Updated advertiser: 5e:ed:cc:f4:2b:9b"
I NimBLEScan: "Updated advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "New advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: 5e:ed:cc:f4:2b:9b"
I NimBLEScan: "Updated advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "New advertiser: c3:8b:d1:4b:33:c6"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: 5e:ed:cc:f4:2b:9b"
I NimBLEScan: "Updated advertiser: 41:e6:70:7c:80:c6"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "New advertiser: d8:0e:9b:28:a8:1d"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: 69:42:10:38:8a:d3"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
I NimBLEScan: "Updated advertiser: f7:eb:ed:4e:47:07"
I NimBLEScan: "Updated advertiser: 5e:ed:cc:f4:2b:9b"
I NimBLEScan: "Updated advertiser: 7f:23:75:5d:1c:9e"
I NimBLEScan: "Updated advertiser: 67:b7:a8:cb:9f:01"
D NimBLEScan: "discovery complete; reason=0"
------------------------------
Name 
Name 
Name 
D NimBLEUUID: "Comparing UUIDs; type 16 to 16; UUID 0xffc0 to 0xffc0"
Found Spark - trying to connect....connected
D NimBLEClient: ">> getService: uuid: 0xffc0"
D NimBLEClient: ">> retrieveServices"
E NimBLEClient: "Disconnected, could not retrieve services -aborting"
D NimBLEClient: "<< getService: not found"
Done Spark....
D NimBLEServer: ">> createService - 0xffc0"
D NimBLEServer: "<< createService"
D NimBLEUUID: "Comparing UUIDs; type 16 to 16; UUID 0xffc1 to 0xffc2"
D NimBLEService: ">> start(): Starting service: UUID: 0xffc0, handle: 0xffff"
D NimBLEService: "Adding 2 characteristics for service UUID: 0xffc0, handle: 0xffff"
D NimBLEService: "<< start()"
D NimBLEAdvertising: ">> Advertising start: customAdvData: 0, customScanResponseData: 0"
primary service
           uuid 0x1800
         handle 1
     end_handle 5
characteristic
           uuid 0x2a00
     def_handle 2
     val_handle 3
   min_key_size 0
          flags [READ]
characteristic
           uuid 0x2a01
     def_handle 4
     val_handle 5
   min_key_size 0
          flags [READ]
primary service
           uuid 0x1801
         handle 6
     end_handle 9
characteristic
           uuid 0x2a05
     def_handle 7
     val_handle 8
   min_key_size 0
          flags [INDICATE]
ccc descriptor
           uuid 0x2902
         handle 9
   min_key_size 0
          flags [READ|WRITE]
primary service
           uuid 0xffc0
         handle 10
     end_handle 15
characteristic
           uuid 0xffc1
     def_handle 11
     val_handle 12
   min_key_size 0
          flags [READ|WRITE_NO_RSP|WRITE]
characteristic
           uuid 0xffc2
     def_handle 13
     val_handle 14
   min_key_size 0
          flags [READ|NOTIFY]
ccc descriptor
           uuid 0x2902
         handle 15
   min_key_size 0
          flags [READ|WRITE]
D NimBLEAdvertising: "<< Advertising start"

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

Sorry, it's not easy to see things from my phone sometimes. Now that you said that I can see the issue.

In order to set the server attributes and start it you need to close all connections / scanning / advertising because the NimBLE stack needs to reset the GATT structure.

So the fix would be to simply setup all the server things before starting the scan. Also add a call to NimBLEServer::start() after that.

From there you can start scanning and connecting and just start advertising after the scan stop.

@paulhamsh
Copy link
Author

Like this? Still same abort, though, so I must have got something wrong.


  // Create server to act as Spark
  NimBLEDevice::init("Spark 40 BLE");
  
  // Set up server
  pServer = NimBLEDevice::createServer();
  pService = pServer->createService(S_SERVICE);
  pCharacteristic_receive = pService->createCharacteristic(S_CHAR1, 
                  NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
  pCharacteristic_send = pService->createCharacteristic(S_CHAR2, 
                  NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);  
  pCharacteristic_receive->setCallbacks(&chrCallbacks_r);
  pCharacteristic_send->setCallbacks(&chrCallbacks_s);


  pAdvertising = NimBLEDevice::getAdvertising(); // create advertising instance
  pAdvertising->addServiceUUID(pService->getUUID()); // tell advertising the UUID of our service
  pAdvertising->setScanResponse(true);  


  pClient_sp = NimBLEDevice::createClient();
  pScan      = NimBLEDevice::getScan();
  
  // Connect to Spark
  connected_sp = false;
  while (!connected_sp) {
    pResults = pScan->start(4);
    NimBLEUUID SPserviceUuid(C_SERVICE);

    Serial.println("------------------------------");
    for(i = 0; i < pResults.getCount()  && !connected_sp; i++) {
      device = pResults.getDevice(i);

      // Print info
      Serial.print("Name ");
      Serial.println(device.getName().c_str());

      if (device.isAdvertisingService(SPserviceUuid)) {
        Serial.print("Found Spark - trying to connect....");
        if(pClient_sp->connect(&device)) {
          connected_sp = true;
          Serial.println("connected");
         }
      }
    }

    // Set up client
    if (connected_sp) {
      pService_sp = pClient_sp->getService(SPserviceUuid);
      if (pService_sp != nullptr) {
        pSender_sp   = pService_sp->getCharacteristic(C_CHAR1);
        pReceiver_sp = pService_sp->getCharacteristic(C_CHAR2);
        if (pReceiver_sp && pReceiver_sp->canNotify()) {
          if (!pReceiver_sp->subscribe(true, notifyCB_sp, true)) {
            connected_sp = false;
            Serial.println("Spark not ok");
            //pClient_sp->disconnect();
            NimBLEDevice::deleteClient(pClient_sp);
          }
        }
      }
    }

  }

  Serial.println("Done Spark....");
  
  pServer->start();
  pService->start();
  pAdvertising->start(); // start advertising

}

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

You'll also need to move these

  pService->start();   // IMPORTANT note: this needs to come before server start.
  pServer->start();

to a point before you start the scan, probably right after pCharacteristic_send->setCallbacks(&chrCallbacks_s);

That bit isn't well documented as this is not a case I've encountered before, I'll need to update the docs for this as well, sorry for the frustration.

@paulhamsh
Copy link
Author

Thank you!!
This works now.
I'm not sure any of the examples I copied had pServer->start() - or perhaps I just missed that. The code with just the server seemed to work without it!
I wish I understood more BLE - I'm glad you do!!

  // Create server to act as Spark
  NimBLEDevice::init("Spark 40 BLE");
  pClient_sp = NimBLEDevice::createClient();
  pScan      = NimBLEDevice::getScan();
    
  // Set up server
  pServer = NimBLEDevice::createServer();
  pService = pServer->createService(S_SERVICE);
  pCharacteristic_receive = pService->createCharacteristic(S_CHAR1, 
                  NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_NR);
  pCharacteristic_send = pService->createCharacteristic(S_CHAR2, 
                  NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY);  
  pCharacteristic_receive->setCallbacks(&chrCallbacks_r);
  pCharacteristic_send->setCallbacks(&chrCallbacks_s);

  pService->start();
  pServer->start();

  pAdvertising = NimBLEDevice::getAdvertising(); // create advertising instance
  pAdvertising->addServiceUUID(pService->getUUID()); // tell advertising the UUID of our service
  pAdvertising->setScanResponse(true);  

  Serial.println("Service set up");

  
  // Connect to Spark
  connected_sp = false;
  while (!connected_sp) {
    pResults = pScan->start(4);
    NimBLEUUID SPserviceUuid(C_SERVICE);

    Serial.println("------------------------------");
    for(i = 0; i < pResults.getCount()  && !connected_sp; i++) {
      device = pResults.getDevice(i);

      // Print info
      Serial.print("Name ");
      Serial.println(device.getName().c_str());

      if (device.isAdvertisingService(SPserviceUuid)) {
        Serial.print("Found Spark - trying to connect....");
        if(pClient_sp->connect(&device)) {
          connected_sp = true;
          Serial.println("connected");
        }
      }
    }

    // Set up client
    if (connected_sp) {
      pService_sp = pClient_sp->getService(SPserviceUuid);
      if (pService_sp != nullptr) {
        pSender_sp   = pService_sp->getCharacteristic(C_CHAR1);
        pReceiver_sp = pService_sp->getCharacteristic(C_CHAR2);
        if (pReceiver_sp && pReceiver_sp->canNotify()) {
          if (!pReceiver_sp->subscribe(true, notifyCB_sp, true)) {
            connected_sp = false;
            Serial.println("Spark not ok");
            //pClient_sp->disconnect();
            NimBLEDevice::deleteClient(pClient_sp);
          }
        }
      }
    }

  }

  Serial.println("Done Spark....");
  

  pAdvertising->start(); 

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

It's not documented because it's not needed in 99% of cases lol.

Advertising start calls it for you but in this case you needed to have the server started before advertising to fix the issue.

@paulhamsh
Copy link
Author

Thank you for all your help!! I've just managed to get my code fully working - it now can connect to my amp, accept a connection from an app on an iphone, and pass data between the two! Exactly what I needed. Thank you!!!

@h2zero
Copy link
Owner

h2zero commented Oct 5, 2021

You're very welcome, glad to hear all is working!

@paulhamsh
Copy link
Author

Hi - I have another question - can NimBLE work with BluetoothSerial? I'd like to have two varieties of the server - one NimBLE and one BluetoothSerial (for an Android app that doesn't seem to want to use BLE) - and keep the client part as NimBLE.
This is probably another edge case!!
So - basically, the server would be BluetoothSerial and the client connections use NimBLE.

@h2zero
Copy link
Owner

h2zero commented Oct 13, 2021

This is not possible with NimBLE as you would need the bluedroid stack to use classic Bluetooth.

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