Defining two different callbacks for BLE on ESP32

1

I'm developing a joint work Android app/ESP32 application to communicate via BLE. The goal is to be able to advertise, and to manage connections to exchange specific data for each android phone. On my ESP32, I want to be able to have a callback for GATT characteristic, and another one for the server. The first one for advertising data, the second for managing indicate feature and communicate though a connection. If a set one just for the characteristic, it works fine but I cannot access the state of the connection (whether a device is connected or not), if a set just one just for the server I get a guru meditation error, probably because I'm advertising at the same time ...

As a result, in my Android code, I never get into the method onCharacteristicChanged().

Is it possible to achieve my goal? If yes, how?

I mainly follow this example : https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_notify/BLE_notify.ino

ESP32

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE_Carousel.h>
#include <BLE2902.h>
#include <iostream>
#include <algorithm>
#include <ArduinoJson.h>
using namespace std;

#define PACKET_SIZE 24
#define HEADER_SIZE 3 // Object ID 1 byte, Object size 1 byte  Packet Number 1 byte

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b" // UUID dedicated to consent transmission
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" // Characterisitic that will receive the consent
int idx = 0;
BLEAdvertising *pAdvertising;
BLEServer *pServer = NULL;
BLE_Carousel carousel = BLE_Carousel(PACKET_SIZE, HEADER_SIZE);
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
uint32_t value = 0;

class MyServerCallbacks: public BLEServerCallbacks {
   void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      std::cout << "1" << "\n";
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      std::cout << "0" << "\n";
    } 
};


class MyCallBack: public BLECharacteristicCallbacks {

    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      std::cout << "1" << "\n";
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      std::cout << "0" << "\n";
    } 

    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();
      if ((rxValue.length() > 0) && (rxValue.find ('&') == std::string::npos)) {
        Serial.println("*********");
      }
    }

}; //end of callback


void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");


  BLEDevice::init("InCon_Beacon");
  pServer = BLEDevice::createServer();
  //pServer->setCallbacks(new MyServerCallbacks());


  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                       );

  pCharacteristic->addDescriptor(new BLE2902());
  // Configure the characteristic
  // The maximum length of an attribute value shall be 512 octets.
  pCharacteristic->setValue("Value");
  pCharacteristic->setCallbacks(new MyCallBack());
  Serial.println("Characteristic defined!");

  // Allocate the buffer that will contain the privacy policy

  byte pp[pp_size] = { ... };

  // Initialize the Carousel
  carousel.set_Data(pp, pp_size);

  // Configure the payload of advertising packets
  byte*  packet = (byte*)carousel.get_Packet( 0);
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  BLEAdvertisementData oScanResponseData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04

  //std::string strServiceData = "";
  std::string strServiceData = "";

  strServiceData += (char)11;     // Len
  strServiceData += (char)0xFF;   // Type
  strServiceData += "0123456789";
  oAdvertisementData.addData(strServiceData);


  pAdvertising = pServer->getAdvertising();
  //Serial.println("Payload:");
  //Serial.println(oAdvertisementData.getPayload().c_str());
  //pAdvertising->setAdvertisementData(oAdvertisementData);
  pAdvertising->setScanResponseData(oScanResponseData);
  set_new_adv_payload(idx);

  // Start service and advertising
  pService->start();
  pAdvertising->start();


}

void set_new_adv_payload(int idx) {

  //Serial.println(idx);
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04
  std::string strServiceData = "";
  //Serial.println(carousel.get_Nb_Packets());
  strServiceData += (char)(PACKET_SIZE + 1);   // Len
  strServiceData += (char)0xFF;   // Type

  byte*  packet = (byte*)carousel.get_Packet( idx);
  for (int i = 0; i < PACKET_SIZE; i++) {
    strServiceData += (char) packet[i];
  }
  free(packet);
  //Serial.println(idx);
  oAdvertisementData.addData(strServiceData);
  pAdvertising->setAdvertisementData(oAdvertisementData);
}

void loop() {
  delay(200);
  //Serial.println(idx);

  set_new_adv_payload(idx);


  idx = (idx + 1) % carousel.get_Nb_Packets();

  if (deviceConnected) {
    pCharacteristic->setValue((uint8_t*)&value, 4);
    pCharacteristic->notify();
    value++;
    std::cout << value << "\n";
    delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
  }
}

Dealing with notify/indicate

 BluetoothGatt bleGatt;
        BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
            @Override
            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                BluetoothGattCharacteristic characteristic =
                        gatt.getService(UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"))
                                .getCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"));
                characteristic.setValue(new byte[]{1, 1});
                gatt.writeCharacteristic(characteristic);
//                String test = "test";
//                characteristic.setValue(test);
//                gatt.writeCharacteristic(characteristic);

                gatt.disconnect();
            }

            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                if (newState == STATE_CONNECTED){
                    gatt.discoverServices();
                }
            }


            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status){
                BluetoothGattCharacteristic characteristic =
                        gatt.getService(UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"))
                        .getCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"));
                gatt.setCharacteristicNotification(characteristic, true);
                BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));//enable gattcharac to have indication
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                gatt.writeDescriptor(descriptor);

            }

            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {

                characteristic.getValue();
                Log.i("ohyes",characteristic.getValue().toString());
            }

        };

        bleGatt = mDeviceStore.getDeviceList().get(0).getDevice().connectGatt(this, true, gattCallback);

When dealing with regular GATT

BGS = mBluetoothLeService.getSupportedGattServices();
                for (BluetoothGattService gattService : BGS) {
                    if (gattService.getUuid().toString().equals("4fafc201-1fb5-459e-8fcc-c5c9c331914b")) {
                        List<BluetoothGattCharacteristic> BGC = gattService.getCharacteristics();
                        for (BluetoothGattCharacteristic gattCharac : BGC) {
                            if (gattCharac.getUuid().toString().equals("beb5483e-36e1-4688-b7f5-ea07361b26a8")) {
                                //String s = PolicyEngine.policyModelToProto(intersection).toString();
                                PilotPolicyProto.PilotPolicy.Builder pol = PolicyEngine.policyModelToBuilder(DSP);
                                try {
                                    String s = JsonFormat.printer().print(pol);
//                                    s = s.substring(s.indexOf('\n')+1);
//                                    s = s+"{";
                                    Log.i("dede", s);
                                    gattCharac.setValue("&" + s);
                                    boolean consent = mBluetoothLeService.mBluetoothGatt.writeCharacteristic(gattCharac);
                                } catch (InvalidProtocolBufferException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
Core 1 register dump:
PC      : 0x40166dc5  PS      : 0x00060330  A0      : 0x800d6ae5  A1      : 0x3ffc9af0  
A2      : 0x00000074  A3      : 0x3ffc9b24  A4      : 0x3ffc4e70  A5      : 0x00000000  
A6      : 0x00000001  A7      : 0x3ffe05e4  A8      : 0x3ffc9b30  A9      : 0x3ffc9ad0  
A10     : 0x3ffc9b2c  A11     : 0x3ffc4e6c  A12     : 0x3ffc4e70  A13     : 0x3f401c72  
A14     : 0x00000002  A15     : 0x00000001  SAR     : 0x00000008  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000074  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
android
bluetooth-lowenergy
esp32
asked on Stack Overflow Jun 27, 2019 by vmorel

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0