Open MehmetCagriK opened 6 years ago
Second method of making a device kinda not connectable is setting advertisement filter policy to prevent non-whitelisted devices from connecting to the advertiser. To achieve it, simply add the code below before starting advertisement;
// Passing second parameter as true prevents connection from devices out of whitelist
BLEAdvertising *pAdvertising;
pAdvertising->setScanFilter(false, true);
But the behavior is different with this method.
Both method, in the end, prevents connection to advertiser devices but only the first method is true non-connectable method and if you are trying to create low power broadcaster/advertiser device that only wants to transmit(not to handle energy loss from rejecting-dealing connection requests), you better pick first method.
Thank you for your methods @MehmetCagriK, it helps me a lot for my project !
But i still have a problem with whitelist : when i set setScanFilter(true,true), to only advertise and accept connection to the whitelist, even my whitelisted device can't find the server. And when i set the filter to ( false,true ), my whitelisted device can see the server, but the advertiser reject the connection request. Do you know where that problem may come from ?
For the moment, i let the the scanfilter to ( true, false ) so only the device who knows the server address can connect.
Looks like your whitelisted device is not whitelisted or we have bug in whitelist options (this library or esp-idf). If you have some code i could test this and you can share would be nice.
@vuanh-minh Glad i could help. Can you send me smallest subset of code that still provides same faults, so I can try myself. If both server and client devices are esp32, send me simplified codes both. Because some smartphone bluetooth apps do not have enough configuration, they might not be correct tools for debugging ble servers.
I think i have found where the problem came from : In my program, the ESP32 is both server and client, and the device too.
ESP32 side : when a non-paired device connects to the ESP32 Server, the ESP32 scan for specific device UUID, and create a Task MyClient which connects back to the device's server.
class MyClient: public Task {
void run(void* data) {
//If device is not paired yet, pDeviceAddress = the address's device which just connected, then we store the address in nvs, and add to the whitelist
if (!isPaired){
pDeviceAddress = (BLEAddress*)data;
esp_err_t err = nvs_set_str(my_handle,myKey,pDeviceAddress->toString().c_str());
ESP_LOGI(TAG,"Device's address '%s' stored in NVS for key %s", pDeviceAddress->toString().c_str(),myKey );
BLEDevice::whiteListAdd(*pDeviceAddress);
ESP_LOGI(TAG,"Device's address '%s' stored in whitelist", pDeviceAddress->toString().c_str() );
}
BLEClient* pClient = BLEDevice::createClient();
// Connect to the remote BLE Server.
pClient->connect(*pDeviceAddress);
AppConnected=true;
ESP_LOGI(TAG, "ESP32 Client is now connected to application Server");
ESP_LOGI(TAG, "Application address is : %s",pDeviceAddress->toString().c_str());
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(app_serviceUUID);
if (pRemoteService == nullptr) {
ESP_LOGI(TAG, "Failed to find our service UUID: %s", app_serviceUUID.toString().c_str());
return;
}
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(app_charUUID);
if (pRemoteCharacteristic == nullptr) {
ESP_LOGI(TAG, "Failed to find our characteristic UUID: %s", app_charUUID.toString().c_str());
return;
}
} // run
}; // MyClientTask
When i put *BLEDevice::whiteListAdd(pDeviceAddress);** in that task, the server doesn't seems to add the client into the whitelist, and so, the client can't connect even if there is no errors message and the log "Device's address '%s' stored in whitelist" appears correctly.
So i tried to move this line in the BLE Server configuration task :
`class MainBLEServer: public Task { void run(void *data) { BLEDevice::init("ESP32");
if (isPaired){
BLEDevice::whiteListAdd(*pDeviceAddress);
scanRequestWhitelistOnly = true;
connectWhitelistOnly = true;
}
else {
scanRequestWhitelistOnly = false;
connectWhitelistOnly = false;
}
BLEServer* pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
......Service & Characteristics configuration....
...
pService->start();`
And now, i test it and it seems to work for the whitelist, and the client can reconnect to the server after initial bonding. The only thing is that the ESP32 add the address to the whitelist at every boot, is that ok ?
Its hard to say. There is limited space for whitelisted devices and you need to ask espressif devs how devices are added (duplicates stored or not). I dont see too much of your code but for some reason it seems to look odd (or maybe im just tired).
@MehmetCagriK I think there is some bug in esp-idf ble stack because im getting very strange results: https://github.com/nkolban/esp32-snippets/issues/613#issuecomment-412311395
I was trying to create a low power temperature broadcaster BLE device. Naturally, you don' t want it to be connectable and you would share data only with advertisements anyways.
So I realized libraries did not allow me to modify m_advParams.adv_type of BLEAdvertising object. So, I added necessary function and its signature both to BLEAdvertising.h and BLEAdvertising.cpp. Source code changes are added below;
I prepared a sample code to test it and I saw setting advertisement type only does not change advertisement behavior. When I was setting it to ADV_TYPE_NONCONN_IND, I could connect to the device with both NRFConnect and LightBlue apps.
However, while tinkering with other parameters, I realized setting min and max advertisement intervals with setting advertisement type was giving me what I want, the device is no longer connectable. Thus, it fulfills broadcaster role.
Here is the smallest working piece of code;
I am reminding you that default minimum adv. interval is 0x20 and maximum adv. interval is 0x40, given in initialization. I do not know correlation between advertisement intervals and connectability behavior but if we solve this abd test it throughly, we may add nice feature.