Skip to content

Bluetooth onWrite callback uses the wrong characteristic #3153

Closed
@JasXSL

Description

@JasXSL

Hardware:

Board: ESP32 Dev Module
Core Installation/update date: 29/aug/2019
IDE name: Arduino IDE
Flash Frequency: 80Mhz
PSRAM enabled: no
Upload Speed: 921600
Computer OS: Windows 10

Description:

Not sure if this issue was created recently, but for some reason the BLECharacteristic in the onWrite event is always the first one added to the service.

For an instance. Writing a value to "ba5edca7-face-d00d-c0de-000000000001" using nrf connect causes onWrite to fire with pCharacteristic as "ba5edca7-face-d00d-c0de-0000000000".

The value does get set though, because if I disconnect in nrf connect and reconnect, the updated value is set. But if I need to be able to get which characteristic was changed in the application.

Edit: Looking closer at what I pasted. It looks like pCharacteristic->getUUID() is shifting off the last 2 characters of the UUID. Is this a bug or by design?

Header

class MySecurity : public BLESecurityCallbacks {
	private:
		uint32_t onPassKeyRequest();
		void onPassKeyNotify(uint32_t pass_key);
		bool onConfirmPIN(uint32_t pass_key);
		bool onSecurityRequest();
		void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl);
};

class MyServer : public BLEServerCallbacks {
	private:
		void onConnect(BLEServer* pServer);
		//void onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param);
		void onDisconnect(BLEServer* pServer);
};

class bleCharacteristicCallback: public BLECharacteristicCallbacks{
	public:
		static constexpr char SERVICE_MAIN[37] = "ba5edca7-face-d00d-c0de-000000001337";
		
		static constexpr char C_PHOTO_THRESH_VAL[37] = "ba5edca7-face-d00d-c0de-000000000000";
		static constexpr char C_PHOTO_TOGGLE_ENABLED[37] = "ba5edca7-face-d00d-c0de-000000000001";

	private:
		void onWrite(BLECharacteristic* pCharacteristic);
		void onRead(BLECharacteristic* pCharacteristic);
};

class MainBLEServer: public Task{

	public:
		bool initialized = false;
		bool pairing_enabled = false;
		long last_disconnect = 1;				// 0 = we're actively connected
		void toggleBonding(bool on = false);
	private:
		void run(void *data);
};


extern MainBLEServer* bBluetooth;
extern BLESecurity* bSecurity;

CPP File

MainBLEServer* bBluetooth;
BLESecurity *bSecurity;
BLEScan* pBLEScan;
BLEService* pService;

uint32_t MySecurity::onPassKeyRequest(){
	Serial.println("PassKeyRequest");
	return 123456;
}
void MySecurity::onPassKeyNotify(uint32_t pass_key){
	Serial.printf("The passkey Notify number:%d\n", pass_key);
}
bool MySecurity::onConfirmPIN(uint32_t pass_key){
	Serial.printf("The passkey YES/NO number:%d\n", pass_key);
	vTaskDelay(5000);
	return true;
}
bool MySecurity::onSecurityRequest(){
	Serial.println("SecurityRequest");
	return true;
}

void MySecurity::onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){

	// A device connected here
	Serial.println("onAuthenticationComplete");
	if(cmpl.success){

		uint16_t length;
		esp_ble_gap_get_whitelist_size(&length);
		Serial.printf("size: %d\n", length);
		bConfig.bonded = true;
		bConfig.save();
		bBluetooth->toggleBonding(false);

	}
	
}

// only one device can be connected at a time
void MyServer::onConnect(BLEServer* pServer){
	Serial.println("Client connected");
	bBluetooth->last_disconnect = 0;
}

void MyServer::onDisconnect(BLEServer* pServer){
	Serial.println("Client disconnected");
	bBluetooth->last_disconnect = 1;		// Turn it off immediately or within 60 sec of boot
}

constexpr char bleCharacteristicCallback::SERVICE_MAIN[37];
constexpr char bleCharacteristicCallback::C_PHOTO_THRESH_VAL[37];
constexpr char bleCharacteristicCallback::C_PHOTO_TOGGLE_ENABLED[37];

void bleCharacteristicCallback::onWrite(BLECharacteristic* pCharacteristic) {

	String uuid = pCharacteristic->getUUID().toString().c_str();
	
	// Front light colors, expecting a 3x byte array
	Serial.printf("BT UUID write received %s\n", uuid.c_str());
	std::string value = pCharacteristic->getValue();
	if( uuid == bleCharacteristicCallback::C_PHOTO_THRESH_VAL ){ 
		unsigned int val = (value[0]<<8)|value[1];
		bPhotoresistor.thresh_val = val;
		bConfig.save();
	}

	if( uuid == bleCharacteristicCallback::C_PHOTO_TOGGLE_ENABLED ){ 
		bPhotoresistor.photo_toggle_enabled = value[0];
		bConfig.save();
	}

}

void bleCharacteristicCallback::onRead(BLECharacteristic* pCharacteristic) {
	std::string msg = pCharacteristic->getValue();
	Serial.printf("BLE received: %s, %i\n", msg.c_str(), msg.length());
}

void MainBLEServer::toggleBonding( bool on ){

	pairing_enabled = on;
	if( on ){
		bSecurity->setCapability(ESP_IO_CAP_NONE);
		//statusLED.setBluetoothPairable( true );
		Serial.println("Enabling bluetooth bonding");
	}
	else{
		Serial.println("Turning off bonding");
		bSecurity->setCapability(ESP_IO_CAP_IN);
		//statusLED.setBluetoothPairable( false );
	}
}


void MainBLEServer::run(void *data) {
			
	Serial.println("Starting BLE work!");
	BLEDevice::init("Bike");
	BLEServer* pServer = BLEDevice::createServer();
	pServer->setCallbacks(new MyServer());

	BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
	BLEDevice::setSecurityCallbacks(new MySecurity());

	pService = pServer->createService(bleCharacteristicCallback::SERVICE_MAIN);

	
	Serial.println("Creating callback");
	bleCharacteristicCallback *callback = new bleCharacteristicCallback();

	Serial.println("Setting up");
	byte out[] = {0};
	

	// RW Characteristics
	Serial.println();
	Serial.printf("Adding PHOTO_THRESH_VAL\n");
	BLECharacteristic* pCharacteristic = pService->createCharacteristic(
		BLEUUID(bleCharacteristicCallback::C_PHOTO_THRESH_VAL),
		BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
	);
	pCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
	pCharacteristic->setCallbacks(callback);
	out[1] = bPhotoresistor.thresh_val&0xFF;
	out[0] = (bPhotoresistor.thresh_val>>8)&0xFF;
	pCharacteristic->setValue(out, 2);


	Serial.printf("Adding C_PHOTO_TOGGLE_ENABLED\n");
	pCharacteristic = pService->createCharacteristic(
		BLEUUID(bleCharacteristicCallback::C_PHOTO_TOGGLE_ENABLED),
		BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE
	);
	pCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
	pCharacteristic->setCallbacks(callback);
	out[0] = bPhotoresistor.photo_toggle_enabled;
	pCharacteristic->setValue(out, 1);


	Serial.println("Starting");

	pService->start();
	BLEAdvertising* pAdvertising = pServer->getAdvertising();
	pAdvertising->addServiceUUID(BLEUUID(pService->getUUID()));
	pAdvertising->setScanResponse(true);

	bSecurity = new BLESecurity();
	bSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
	//bSecurity->setCapability(ESP_IO_CAP_OUT);
	//bSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
	bSecurity->setCapability(ESP_IO_CAP_IN);
	pAdvertising->start();
	Serial.println("Advertising started!");
	delay(portMAX_DELAY);
}

ino setup

   bBluetooth = new MainBLEServer();
    bBluetooth->setStackSize(20000);
    bBluetooth->start();

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: StaleIssue is stale stage (outdated/stuck)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions