NimBLE-Arduino icon indicating copy to clipboard operation
NimBLE-Arduino copied to clipboard

Failure on client->getService()?

Open paulhamsh opened this issue 3 years ago • 14 comments

Hi I have a BLE device (Spark Control - a BLE pedal to control a guitar amp) which seems to fail on getService in NimBLE. I have many other devices where this works perfectly. It is just this one!!

It works with standard Arduino BLE, though. Also an iPhone running LightBlue can connect and talk to the device.

Please see my code and the Debug log. The code has conditional #ifdef checking for NIM to use NimBLE, and not defined for normal BLE.

This is for an M5 Stick C but a A-Z Delivery ESP32 WROOM does the same thing. There are two SERVICE options because the pedal device can expose either - neither work with NimBLE

Using NimBLE 1.3.6 (although no version seems to work)

Any ideas?

#include <M5StickC.h>

#define NIM

#ifdef NIM
#include "NimBLEDevice.h"
#else
#include "BLEDevice.h"
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#endif


#define SERVICE     "7bdb8dc0-6c95-11e3-981f-0800200c9a66"
#define CHAR        "362f71a0-6c96-11e3-981f-0800200c9a66"

//#define SERVICE     "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
//#define CHAR        "7772e5db-3868-4112-a1a9-f2669d106bf3"

// BLE 
BLEAdvertisedDevice device;
BLEClient *pClient_bb;
BLERemoteService *pService_bb;
BLERemoteCharacteristic *pReceiver_bb;
BLERemoteDescriptor* p2902;
const uint8_t notifyOn[] = {0x1, 0x0};

void notifyCB_bb(BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
  int i;
  
  Serial.print("Spark Control: ");
  for (i = 0; i < length; i++) {
    Serial.print(pData[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

// Callbacks for client events
class ClientCallbacks : public BLEClientCallbacks {
  void onConnect(BLEClient* pClient) {
    ;
  }

  void onDisconnect(BLEClient* pClient) {
    ;
  }
};


bool connected_bb;

void setup() {
  int i;
  
  // put your setup code here, to run once:
  M5.begin();
  
  M5.Lcd.setRotation(-1);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.println("Spark Control");
  Serial.println("Started");
  
  connected_bb = false;
  BLEDevice::init("");

  while (!connected_bb) {
 
    BLEScan *pScan = BLEDevice::getScan();
    BLEScanResults results = pScan->start(4);

    BLEUUID BBserviceUuid(SERVICE); // service for LPD8 
 

    for(i = 0; i < results.getCount() && !connected_bb; i++) {
      device = results.getDevice(i);
      if (device.isAdvertisingService(BBserviceUuid)) {
        Serial.print("Found Spark Control - trying to connect....");
        pClient_bb = BLEDevice::createClient();
        pClient_bb->setClientCallbacks(new ClientCallbacks());
        if(pClient_bb->connect(&device)) {
#ifndef NIM
          pClient_bb->setMTU(517);  
#endif
          connected_bb = true;
          Serial.println("connected");
        }
      }
    }

    Serial.println();

    // Get the services
  
    if (connected_bb) {
      Serial.println(">>> CONNECTED");
      pService_bb = pClient_bb->getService(BBserviceUuid);
      if (pService_bb != nullptr) {
        Serial.println(">>>GOT SERVICE");
        pReceiver_bb = pService_bb->getCharacteristic(CHAR);
        if (pReceiver_bb && pReceiver_bb->canNotify()) {
          Serial.println(">>>GOT CAN NOTIFY");
#ifdef NIM
          if (!pReceiver_bb->subscribe(true, notifyCB_bb, true)) {
            Serial.println("NimBLE subscribe failed");
          }
#else          
          pReceiver_bb->registerForNotify(notifyCB_bb);
          p2902 = pReceiver_bb->getDescriptor(BLEUUID((uint16_t)0x2902));
          if(p2902 != nullptr)
            p2902->writeValue((uint8_t*)notifyOn, 2, true);
          else
            Serial.println("2902 no descriptor");
#endif          
        }
      }
    Serial.println("Connected to Spark Control");
    }
  }
}

void loop() {
  M5.update();
}

Log

OK
[  1011][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
Started
I NimBLEDevice: "BLE Host Task Started"
I NimBLEDevice: "NimBle host synced."
D NimBLEScan: ">> start(duration=4)"
D NimBLEScan: "<< start()"
I NimBLEScan: "New advertiser: 72:cb:40:d4:fe:9f"
I NimBLEScan: "New advertiser: 4c:50:8b:c2:37:07"
I NimBLEScan: "New advertiser: 67:47:cc:96:d3:44"
I NimBLEScan: "New advertiser: db:ab:7f:e0:2f:5c"
I NimBLEScan: "Updated advertiser: 4c:50:8b:c2:37:07"

<REMOVED LOTS OF SIMILAR LINES>

I NimBLEScan: "Updated advertiser: db:ab:7f:e0:2f:5c"
I NimBLEScan: "Updated advertiser: db:ab:7f:e0:2f:5c"
I NimBLEScan: "Updated advertiser: 4c:50:8b:c2:37:07"
D NimBLEScan: "discovery complete; reason=0"
Found Spark Control - trying to connect....D NimBLEClient: ">> connect(db:ab:7f:e0:2f:5c)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
D NimBLEClient: "<< connect()"
connected

>>> CONNECTED
D NimBLEClient: ">> getService: uuid: 7bdb8dc0-6c95-11e3-981f-0800200c9a66"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClientCallbacks: "onConnParamsUpdateRequest: default"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."

<SHORT PAUSE HERE - 3 seconds>

D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClientCallbacks: "onConnParamsUpdateRequest: default"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."

<LONG PAUSE HERE - 25 seconds>

D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 8, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClientCallbacks: "onConnParamsUpdateRequest: default"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Service Discovered >> status: 13 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=13 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
D NimBLEClient: "<< getService: not found"
Connected to Spark Control
D NimBLEClient: "Got Client event "
I NimBLEClient: "disconnect; reason=534, "

paulhamsh avatar Feb 09 '22 21:02 paulhamsh

Is this the complete log, nothing edited after Found Spark Control - trying to connect? I'm not familiar with the M5 calls so I don't know what M5.update() does in the loop, but the log suggests the device is looping on the connection parameter updates and I have no idea why that would occur. You might want to try rejecting connection parameter update in the callback.

It also appears that the device is forcefully disconnecting at the end of the log, very strange. I don't have many suggestions for you at this time but I'll think about it and update if I come up with anything.

h2zero avatar Feb 10 '22 01:02 h2zero

Hi - the only edits are in < > braces, where I removed a lot of the 'advertiser' lines plus to note the two pauses. I added in the callback and made it return false:

    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);
    };

    void onDisconnect(NimBLEClient* pClient) {
        Serial.print(pClient->getPeerAddress().toString().c_str());
        Serial.println(" Disconnected - Starting scan");
        //BLEScan *pScan = BLEDevice::getScan();
    };

    /** Called when the peripheral requests a change to the connection parameters.
     *  Return true to accept and apply them or false to reject and keep
     *  the currently used parameters. Default will return true.
     */
    bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
        if(params->itvl_min < 24) { /** 1.25ms units */
            return false;
        } else if(params->itvl_max > 40) { /** 1.25ms units */
            return false;
        } else if(params->latency > 2) { /** Number of intervals allowed to skip */
            return false;
        } else if(params->supervision_timeout > 100) { /** 10ms units */
            return false;
        }

//        return true;
        return false;
    };
};

But the log remains the same - it pauses in the same two places and fails at the end. I'll run it on the raw ESP32 and produce that log too

paulhamsh avatar Feb 10 '22 14:02 paulhamsh

Raw ESP32 shows the same

D NimBLEClient: ">> getService: uuid: 7bdb8dc0-6c95-11e3-981f-0800200c9a66"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Service Discovered >> status: 13 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=13 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
D NimBLEClient: "<< getService: not found"
Connected to Spark Control
D NimBLEClient: "Got Client event "
I NimBLEClient: "disconnect; reason=534, "
db:ab:7f:e0:2f:5c Disconnected - Starting scan

paulhamsh avatar Feb 10 '22 14:02 paulhamsh

Strange, I wonder what would happen if you called pClient->discoverAttributes() before the call the get the service?

Other than that it seems the device isn't getting the response it wants from the connection parameter update and requests it multiple times. I'm not sure why this would happen.

h2zero avatar Feb 11 '22 00:02 h2zero

The latest release should fix this error. Please try it and let me know.

h2zero avatar Feb 20 '22 14:02 h2zero

The same, I'm afraid (using 1.3.7). Thank you for trying!

I have added in pClient->discoverAttributes() like this:

      Serial.println(">>> CONNECTED");
      pClient->discoverAttributes(); 
      Serial.println(">>> ATTRIBUTES DISCOVERED");
      pService = pClient->getService(BBserviceUuid);

And get the same outcome - more info on the log though.

>>> CONNECTED
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Service Discovered >> status: 13 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=13 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
E NimBLEClient: "Error: Failed to get services"
>>> ATTRIBUTES DISCOVERED
D NimBLEClient: ">> getService: uuid: 7bdb8dc0-6c95-11e3-981f-0800200c9a66"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Service Discovered >> status: 7 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=7 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
D NimBLEClient: "Got Client event "
D NimBLEClient: "<< getService: not found"
I NimBLEClient: "disconnect; reason=534, "

paulhamsh avatar Feb 20 '22 20:02 paulhamsh

Interesting, could you try removing the code to get the services and just loop while connected and see what the logs show? Also try this while accepting the peer connection parameters.

h2zero avatar Feb 20 '22 21:02 h2zero

Hi In summary - not getting attributes allows the connection to stay and it loops on client event / requesting peer parameters, having getting attributes ends in a disconnect after a get client event. Does that help?

With no getting services but getting attributes and rejecting peer parameters I get:

D NimBLEScan: "discovery complete; reason=0"
Found Spark Control - trying to connect....D NimBLEClient: ">> connect(db:ab:7f:e0:2f:5c)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
Connected
D NimBLEClient: "<< connect()"
connected

>>> CONNECTED
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Service Discovered >> status: 13 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=13 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
E NimBLEClient: "Error: Failed to get services"
>>> ATTRIBUTES DISCOVERED
Done setup
D NimBLEClient: "Got Client event "
I NimBLEClient: "disconnect; reason=534, "
db:ab:7f:e0:2f:5cDisconnected

A long pause before ATTRIBUTES DISCOVERED.

With no getting services but getting attributes and accepting peer parameters I get:

D NimBLEScan: "discovery complete; reason=0"
Found Spark Control - trying to connect....D NimBLEClient: ">> connect(db:ab:7f:e0:2f:5c)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
Connected
D NimBLEClient: "<< connect()"
connected
Scanning again...
>>> CONNECTED
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
D NimBLEClient: ">> retrieveServices"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 8, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Service Discovered >> status: 13 handle: -1"
E NimBLEClient: "characteristicDiscCB() rc=13 "
D NimBLEClient: "<< << Service Discovered"
E NimBLEClient: "Could not retrieve services"
E NimBLEClient: "Error: Failed to get services"
>>> ATTRIBUTES DISCOVERED
Done setup
D NimBLEClient: "Got Client event "
I NimBLEClient: "disconnect; reason=534, "
db:ab:7f:e0:2f:5cDisconnected

And with no getting services or attributes and rejecting peer parameters I get:

D NimBLEScan: "discovery complete; reason=0"
Found Spark Control - trying to connect....D NimBLEClient: ">> connect(db:ab:7f:e0:2f:5c)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
Connected
D NimBLEClient: "<< connect()"
connected
Scanning again...
>>> CONNECTED
Done setup
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 8, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 8, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 8, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Rejected peer params"

And with no getting services or attributes and accepting peer parameters I get:

D NimBLEScan: "discovery complete; reason=0"
Found Spark Control - trying to connect....D NimBLEClient: ">> connect(db:ab:7f:e0:2f:5c)"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connected event"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
I NimBLEClient: "Connection established"
D NimBLEClient: ">> deleteServices"
D NimBLEClient: "<< deleteServices"
Connected
D NimBLEClient: "<< connect()"
connected
Scanning again...
>>> CONNECTED
Done setup
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "mtu update event; conn_handle=0 mtu=247"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."
D NimBLEClient: "Got Client event "
D NimBLEClient: "Peer requesting to update connection parameters"
D NimBLEClient: "MinInterval: 12, MaxInterval: 12, Latency: 2, Timeout: 200"
D NimBLEClient: "Accepted peer params"
D NimBLEClient: "Got Client event "
I NimBLEClient: "Connection parameters updated."

The code:

//#include <M5Core2.h>
#include <M5StickC.h>

#define NIM

#ifdef NIM
#include "NimBLEDevice.h"
#else
#include "BLEDevice.h"
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#endif

#ifdef NIM
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);
    };

    void onDisconnect(NimBLEClient* pClient) {
        Serial.print(pClient->getPeerAddress().toString().c_str());
        Serial.println("Disconnected");
        //BLEScan *pScan = BLEDevice::getScan();
    };

    /** Called when the peripheral requests a change to the connection parameters.
     *  Return true to accept and apply them or false to reject and keep
     *  the currently used parameters. Default will return true.
     */
    bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
//        if(params->itvl_min < 24) { /** 1.25ms units */
//            return false;
//        } else if(params->itvl_max > 40) { /** 1.25ms units */
//            return false;
//        } else if(params->latency > 2) { /** Number of intervals allowed to skip */
//            return false;
//        } else if(params->supervision_timeout > 100) { /** 10ms units */
//            return false;
//        }

        return true;
//        return false;
    };
};

#endif

#define SERVICE     "7bdb8dc0-6c95-11e3-981f-0800200c9a66"
#define CHAR        "362f71a0-6c96-11e3-981f-0800200c9a66"

//#define SERVICE     "03b80e5a-ede8-4b33-a751-6ce34ec4c700"
//#define CHAR        "7772e5db-3868-4112-a1a9-f2669d106bf3"

// BLE 
BLEAdvertisedDevice device;
BLEClient *pClient;
BLERemoteService *pService;
BLERemoteCharacteristic *pReceiver;
BLERemoteDescriptor* p2902;
const uint8_t notifyOn[] = {0x1, 0x0};

static ClientCallbacks clientCB;

void notifyCB(BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
  int i;
  
  Serial.print("Spark Control: ");
  for (i = 0; i < length; i++) {
    Serial.print(pData[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

bool connected;

void setup() {
  int i;
  
  // put your setup code here, to run once:

  M5.begin();
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.setTextSize(2);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.println("Spark Control");

//  Serial.begin (115200);
  Serial.println("Started");
  
  connected = false;
  BLEDevice::init("");

  while (!connected) {
 
    BLEScan *pScan = BLEDevice::getScan();
    BLEScanResults results = pScan->start(4);

    BLEUUID BBserviceUuid(SERVICE); // service for LPD8 
 

    for(i = 0; i < results.getCount() && !connected; i++) {
      device = results.getDevice(i);
      if (device.isAdvertisingService(BBserviceUuid)) {
        Serial.print("Found Spark Control - trying to connect....");
        pClient = BLEDevice::createClient();
        pClient->setClientCallbacks(&clientCB, false);

        if(pClient->connect(&device)) {
#ifndef NIM
          pClient->setMTU(517);  
#endif
          connected = true;
          Serial.println("connected");
        }
      }
    }

    Serial.println("Scanning again...");

    // Get the services
  
    if (connected) {
      Serial.println(">>> CONNECTED");
//      pClient->discoverAttributes(); 
//      Serial.println(">>> ATTRIBUTES DISCOVERED");
/*      
      pService = pClient->getService(BBserviceUuid);
      if (pService != nullptr) {
        Serial.println(">>>GOT SERVICE");
        pReceiver = pService->getCharacteristic(CHAR);
        if (pReceiver && pReceiver->canNotify()) {
          Serial.println(">>>GOT CAN NOTIFY");
#ifdef NIM
          if (!pReceiver->subscribe(true, notifyCB, true)) {
            Serial.println("NimBLE subscribe failed");
          }
#else          
          pReceiver->registerForNotify(notifyCB);
          p2902 = pReceiver->getDescriptor(BLEUUID((uint16_t)0x2902));
          if(p2902 != nullptr)
            p2902->writeValue((uint8_t*)notifyOn, 2, true);
          else
            Serial.println("2902 no descriptor");
#endif          
        }
      }
    Serial.println("Connected to Spark Control");
*/
    }
  }
  Serial.println("Done setup");
}

void loop() {
  M5.update();
}

paulhamsh avatar Feb 24 '22 23:02 paulhamsh

Perfect, thanks! That's the data I was hoping to see. Looks like something isn't communicating the peer parameter response, not sure why that would happen but I'll look into it.

h2zero avatar Feb 25 '22 01:02 h2zero

Was there ever any resolution on this? I get a core dump when calling c->getService() though calling c->getServices(true) works fine. Both after a successful connect(). A bit surprised to be running into something that seems so basic. This is on an esp32.

nicpottier avatar Oct 06 '22 21:10 nicpottier

I have not been able to reproduce this, I believe it requires certain conditions that I haven't had time to investigate.

h2zero avatar Oct 06 '22 22:10 h2zero

I have a similar problem with Alpicool K25 Fridge. Standard Arduino BLE works fine while NimBLE client->getService(service) fails. I'm using ESP32-WROOM-32D with NimBLE 1.4.1. Screenshot_2023-01-24-22-55-01-052_no nordicsemi android mcp

timokovanen avatar Jan 24 '23 20:01 timokovanen

It seems that if I force client->getServices(true); before client->getService(service); it works..

timokovanen avatar Jan 28 '23 16:01 timokovanen

Interesting, perhaps the device does not support getting the attributes by uuid.

h2zero avatar Jan 29 '23 14:01 h2zero