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

Ble add blescan mode #22544

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 114 additions & 5 deletions tasmota/tasmota_xdrv_driver/xdrv_79_esp32_ble.ino
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
performs a manual scan or set passive/active
*BLEScan0 0 - set passive scan
BLEScan0 1 - set active scan (you may get names)
BLEScan1 nn - start a manula scan for nn seconds
BLEScan1 nn - start a manual scan for nn seconds
BLEScan2 nn - start a manual scan for nn seconds and publish on tele when at least one device is found
BLEAlias
<mac>=<name> <mac>=<name> - set one or more aliases for addresses
BLEName
Expand All @@ -108,6 +109,9 @@
BLEEnableUnsaved
*0/1 - if BLE is disabled, this can be used to enable BLE without
it being saved - useful as the last command in autoexec.bat
BLEFilterNames
BLEFilterNames0 - clear filter list
BLEFilterNames1 - <name1>,<name2> - set one or more device names

Other drivers can add callbacks to receive advertisements
Other drivers can add 'operations' to be performed and receive callbacks from the operation's success or failure
Expand All @@ -134,6 +138,8 @@ i.e. the Bluetooth of the ESP can be shared without conflict.
*/

#define BLE_ESP32_ALIASES
#define BLE_ESP32_FILTER_BY_NAME
#define BLE_ESP32_FILTER_BY_RSSI

// uncomment for more diagnostic/information messages - + more flash use.
//#define BLE_ESP32_DEBUG
Expand Down Expand Up @@ -472,6 +478,12 @@ std::deque<BLE_ESP32::SCANCOMPLETE_CALLBACK*> scancompleteCallbacks;
std::deque<BLE_ESP32::ble_alias_t*> aliases;
#endif

#ifdef BLE_ESP32_FILTER_BY_NAME
std::vector<String> bleFilterNames;
#endif
#ifdef BLE_ESP32_FILTER_BY_RSSI
int minRSSI = -100;
#endif

/*********************************************************************************************\
* constants
Expand All @@ -480,7 +492,7 @@ std::deque<BLE_ESP32::ble_alias_t*> aliases;
#define D_CMND_BLE "BLE"

const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|"
"Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved";
"Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved|FilterNames|MinRssiLevel";

static void CmndBLEPeriod(void);
static void CmndBLEAdv(void);
Expand All @@ -495,6 +507,8 @@ static void CmndBLEDevices(void);
static void CmndBLEMaxAge(void);
static void CmndBLEAddrFilter(void);
static void CmndBLEEnableUnsaved(void);
static void CmndBleFilterNames(void);
static void CmndSetMinRSSI(void);

void (*const BLE_Commands[])(void) PROGMEM = {
&BLE_ESP32::CmndBLEPeriod,
Expand All @@ -509,7 +523,9 @@ void (*const BLE_Commands[])(void) PROGMEM = {
&BLE_ESP32::CmndBLEDevices,
&BLE_ESP32::CmndBLEMaxAge,
&BLE_ESP32::CmndBLEAddrFilter,
&BLE_ESP32::CmndBLEEnableUnsaved
&BLE_ESP32::CmndBLEEnableUnsaved,
&BLE_ESP32::CmndBleFilterNames,
&BLE_ESP32::CmndSetMinRSSI
};

const char *successStates[] PROGMEM = {
Expand Down Expand Up @@ -588,6 +604,7 @@ uint8_t BLEMode = BLEModeRegularScan;
uint8_t BLETriggerScan = 0;
uint8_t BLEAdvertMode = BLE_ADV_TELE;
uint8_t BLEdeviceLimitReached = 0;
uint8_t BLEpostWhenFound = 0;

uint8_t BLEStop = 0;
uint64_t BLEStopAt = 0;
Expand Down Expand Up @@ -1128,7 +1145,24 @@ void ReverseMAC(uint8_t _mac[]){
}



/**
* @brief Search for device name in filer list
*
* @param deviceName device name string
*/
#ifdef BLE_ESP32_FILTER_BY_NAME
bool isDeviceInFilter(const String& deviceName) {
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Device chcked in filter %s"), deviceName);
#endif
for (const auto& filterName : bleFilterNames) {
if (deviceName == filterName) {
return true;
}
}
return false;
}
#endif

/*********************************************************************************************\
* Advertisment details
Expand Down Expand Up @@ -1372,9 +1406,24 @@ class BLEAdvCallbacks: public NimBLEScanCallbacks {
BLEAdvertisment.name[sizeof(BLEAdvertisment.name)-1] = 0;
}

int filter = 0;
#ifdef BLE_ESP32_FILTER_BY_NAME
if (!bleFilterNames.empty()) {
if (!advertisedDevice->haveName() || !isDeviceInFilter(namestr))
{
filter = 1;
}
}
#endif

#ifdef BLE_ESP32_FILTER_BY_RSSI
if (advertisedDevice->getRSSI() < minRSSI) {
filter = 1;
}
#endif

// log this device safely
if (BLEAdvertisment.addrtype <= BLEAddressFilter){
if ((BLEAdvertisment.addrtype <= BLEAddressFilter) && (0 == filter) ){
addSeenDevice(BLEAdvertisment.addr, BLEAdvertisment.addrtype, BLEAdvertisment.name, BLEAdvertisment.RSSI);
}

Expand Down Expand Up @@ -2300,6 +2349,12 @@ static void BLEEverySecond(bool restart){
BLE_ESP32::BLEPostMQTT(false); // show all operations, not just completed
}

if ((BLEpostWhenFound == 1) && (seenDevices.size() > 0))
{
BLEPublishDevices = 2; // mqtt publish as 'STAT'
BLEpostWhenFound = 0;
}

if (BLEPublishDevices){
BLEPostMQTTSeenDevices(BLEPublishDevices);
BLEShowStats();
Expand Down Expand Up @@ -2678,6 +2733,8 @@ void CmndBLEScan(void){
}
} break;

case 2: // post on tele when at leat one device is found
BLEpostWhenFound = 1;
case 1: // do a manual scan now
switch (BLEMode){
case BLEModeScanByCommand: {
Expand Down Expand Up @@ -2833,6 +2890,58 @@ void CmndBLEDetails(void){
}


void CmndBleFilterNames(void) {
#ifdef BLE_ESP32_FILTER_BY_NAME
int op = XdrvMailbox.index;
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Name %d %s"), op, XdrvMailbox.data);
#endif

switch(op){
case 0:{
bleFilterNames.clear();
ResponseCmndDone();
} break;
case 1:{
if (XdrvMailbox.data_len) {
String filters = XdrvMailbox.data;
bleFilterNames.clear();

int start = 0;
int end = filters.indexOf(',');
while (end != -1) {
bleFilterNames.push_back(filters.substring(start, end));
start = end + 1;
end = filters.indexOf(',', start);
}
bleFilterNames.push_back(filters.substring(start));

Response_P(PSTR("{\"BLEFilterNames\":\"%s\"}"), filters.c_str());
} else {
String filterList;
for (const auto& name : bleFilterNames) {
if (!filterList.isEmpty()) {
filterList += ", ";
}
filterList += name;
}

Response_P(PSTR("{\"BLEFilterNames\":\"%s\"}"), filterList.c_str());
}
} break;
}
#endif
}

void CmndSetMinRSSI(void) {
#ifdef BLE_ESP32_FILTER_BY_RSSI
if (XdrvMailbox.data_len) {
minRSSI = atoi(XdrvMailbox.data);
}
Response_P(PSTR("{\"MinRSSI\":\"%d\"}"), minRSSI);
#endif
}

void CmndBLEAlias(void){
#ifdef BLE_ESP32_ALIASES
int op = XdrvMailbox.index;
Expand Down