Merge pull request #11212 from btsimonh/BLEUpdates

Updates to BLE
This commit is contained in:
Theo Arends 2021-03-03 20:19:23 +01:00 committed by GitHub
commit db215311b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 90 additions and 45 deletions

View File

@ -347,6 +347,10 @@ TaskHandle_t TasmotaMainTask;
static int BLEMasterEnable = 0; static int BLEMasterEnable = 0;
static uint8_t BLEEnableUnsaved = 0;
static uint8_t BLEEnableMask = 1;
static int BLEInitState = 0; static int BLEInitState = 0;
static int BLERunningScan = 0; static int BLERunningScan = 0;
static uint32_t BLEScanCount = 0; static uint32_t BLEScanCount = 0;
@ -391,8 +395,10 @@ BLE_ESP32::generic_sensor_t* prepOperation = nullptr;
std::deque<BLE_ESP32::generic_sensor_t*> queuedOperations; std::deque<BLE_ESP32::generic_sensor_t*> queuedOperations;
// operations in progress (at the moment, only one) // operations in progress (at the moment, only one)
std::deque<BLE_ESP32::generic_sensor_t*> currentOperations; std::deque<BLE_ESP32::generic_sensor_t*> currentOperations;
// operations which have completed or failed, ready to send to MQTT // operations which have completed or failed
std::deque<BLE_ESP32::generic_sensor_t*> completedOperations; std::deque<BLE_ESP32::generic_sensor_t*> completedOperations;
// operations which are ready to send to MQTT
std::deque<BLE_ESP32::generic_sensor_t*> mqttOperations;
// seen devices // seen devices
#define MAX_BLE_DEVICES_LOGGED 80 #define MAX_BLE_DEVICES_LOGGED 80
@ -422,7 +428,7 @@ std::deque<BLE_ESP32::ble_alias_t*> aliases;
#define D_CMND_BLE "BLE" #define D_CMND_BLE "BLE"
const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|" const char kBLE_Commands[] PROGMEM = D_CMND_BLE "|"
"Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter"; "Period|Adv|Op|Mode|Details|Scan|Alias|Name|Debug|Devices|MaxAge|AddrFilter|EnableUnsaved";
static void CmndBLEPeriod(void); static void CmndBLEPeriod(void);
static void CmndBLEAdv(void); static void CmndBLEAdv(void);
@ -436,6 +442,7 @@ static void CmndBLEDebug(void);
static void CmndBLEDevices(void); static void CmndBLEDevices(void);
static void CmndBLEMaxAge(void); static void CmndBLEMaxAge(void);
static void CmndBLEAddrFilter(void); static void CmndBLEAddrFilter(void);
static void CmndBLEEnableUnsaved(void);
void (*const BLE_Commands[])(void) PROGMEM = { void (*const BLE_Commands[])(void) PROGMEM = {
&BLE_ESP32::CmndBLEPeriod, &BLE_ESP32::CmndBLEPeriod,
@ -449,7 +456,8 @@ void (*const BLE_Commands[])(void) PROGMEM = {
&BLE_ESP32::CmndBLEDebug, &BLE_ESP32::CmndBLEDebug,
&BLE_ESP32::CmndBLEDevices, &BLE_ESP32::CmndBLEDevices,
&BLE_ESP32::CmndBLEMaxAge, &BLE_ESP32::CmndBLEMaxAge,
&BLE_ESP32::CmndBLEAddrFilter &BLE_ESP32::CmndBLEAddrFilter,
&BLE_ESP32::CmndBLEEnableUnsaved
}; };
const char *successStates[] PROGMEM = { const char *successStates[] PROGMEM = {
@ -1412,8 +1420,12 @@ static void BLEGenNotifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, ui
#endif #endif
} else { } else {
if (devaddr == op->addr){ if (devaddr == op->addr){
thisop = op; if (op->notifytimer){
break; thisop = op;
break;
} else {
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: notify: op addr match but op found which is not waiting."));
}
} }
} }
} }
@ -1511,13 +1523,6 @@ static void BLEInit(void) {
BLEInitState = 1; BLEInitState = 1;
// dont start of disabled
BLEMasterEnable = Settings.flag5.mi32_enable;
if (!BLEMasterEnable) return;
StartBLE();
return; return;
} }
@ -1807,12 +1812,12 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
#endif #endif
op->notifylen = 0; op->notifylen = 0;
if(pNCharacteristic->canNotify()) { if(pNCharacteristic->canNotify()) {
uint64_t now = esp_timer_get_time();
op->notifytimer = now;
if(pNCharacteristic->subscribe(true, BLE_ESP32::BLEGenNotifyCB)) { if(pNCharacteristic->subscribe(true, BLE_ESP32::BLEGenNotifyCB)) {
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for notify")); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for notify"));
#endif #endif
uint64_t now = esp_timer_get_time();
op->notifytimer = now;
// this will get changed to read or write, // this will get changed to read or write,
// but here in case it's notify only (can that happen?) // but here in case it's notify only (can that happen?)
notifystate = GEN_STATE_WAITNOTIFY; notifystate = GEN_STATE_WAITNOTIFY;
@ -1822,22 +1827,24 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for notify")); AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for notify"));
#endif #endif
newstate = GEN_STATE_FAILED_NOTIFY; newstate = GEN_STATE_FAILED_NOTIFY;
op->notifytimer = 0L;
} }
} else { } else {
if(pNCharacteristic->canIndicate()) { if(pNCharacteristic->canIndicate()) {
uint64_t now = esp_timer_get_time();
op->notifytimer = now;
if(pNCharacteristic->subscribe(false, BLE_ESP32::BLEGenNotifyCB)) { if(pNCharacteristic->subscribe(false, BLE_ESP32::BLEGenNotifyCB)) {
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for indicate")); AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: subscribe for indicate"));
#endif #endif
notifystate = GEN_STATE_WAITINDICATE; notifystate = GEN_STATE_WAITINDICATE;
uint64_t now = esp_timer_get_time();
op->notifytimer = now;
waitNotify = true; waitNotify = true;
} else { } else {
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for indicate")); AddLog(LOG_LEVEL_ERROR,PSTR("BLE: failed subscribe for indicate"));
#endif #endif
newstate = GEN_STATE_FAILED_INDICATE; newstate = GEN_STATE_FAILED_INDICATE;
op->notifytimer = 0L;
} }
} else { } else {
newstate = GEN_STATE_FAILED_CANTNOTIFYORINDICATE; newstate = GEN_STATE_FAILED_CANTNOTIFYORINDICATE;
@ -2147,6 +2154,23 @@ void BLEEvery50mSecond(){
} }
static void stopStartBLE(){
// dont start of disabled
uint8_t enable = (Settings.flag5.mi32_enable || BLEEnableUnsaved) && BLEEnableMask;
if (enable != BLEMasterEnable){
if (enable){
if (StartBLE()){
BLEMasterEnable = enable;
}
} else {
if (StopBLE()){
BLEMasterEnable = enable;
}
}
AddLog(LOG_LEVEL_INFO,PSTR("BLE: MasterEnable->%d"), BLEMasterEnable);
}
}
/** /**
* @brief Main loop of the driver, "high level"-loop * @brief Main loop of the driver, "high level"-loop
@ -2159,27 +2183,14 @@ static void BLEEverySecond(bool restart){
checkDeviceTimouts(); checkDeviceTimouts();
stopStartBLE();
if (Settings.flag5.mi32_enable != BLEMasterEnable){
if (Settings.flag5.mi32_enable){
if (StartBLE()){
BLEMasterEnable = Settings.flag5.mi32_enable;
}
} else {
if (StopBLE()){
BLEMasterEnable = Settings.flag5.mi32_enable;
}
}
AddLog(LOG_LEVEL_INFO,PSTR("BLE: MasterEnable->%d"), BLEMasterEnable);
}
// check for application callbacks here. // check for application callbacks here.
// this may remove complete items. // this may remove complete items.
BLE_ESP32::mainThreadOpCallbacks(); BLE_ESP32::mainThreadOpCallbacks();
// post any MQTT data if we completed anything in the last second // post any MQTT data if we completed anything in the last second
if (completedOperations.size()){ if (mqttOperations.size()){
BLE_ESP32::BLEPostMQTT(true); // send only completed BLE_ESP32::BLEPostMQTT(true); // send only completed
} }
@ -2314,12 +2325,18 @@ int extQueueOperation(BLE_ESP32::generic_sensor_t** op){
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: op invalid")); AddLog(LOG_LEVEL_ERROR,PSTR("BLE: op invalid"));
return 0; return 0;
} }
if (!BLEMasterEnable){
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: extQueueOperation: BLE is deiabled"));
return 0;
}
(*op)->state = GEN_STATE_START; // trigger request later (*op)->state = GEN_STATE_START; // trigger request later
(*op)->opid = lastopid++; (*op)->opid = lastopid++;
int res = addOperation(&queuedOperations, op); int res = addOperation(&queuedOperations, op);
if (!res){ if (!res){
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: extQueueOperation: op added id %d failed"), (lastopid-1)); AddLog(LOG_LEVEL_ERROR,PSTR("BLE: extQueueOperation: op adding id %d failed"), (lastopid-1));
} }
return res; return res;
} }
@ -2451,7 +2468,7 @@ static int StopBLE(void){
AddLog(LOG_LEVEL_INFO,PSTR("BLE: StopBLE - BLEStop->1")); AddLog(LOG_LEVEL_INFO,PSTR("BLE: StopBLE - BLEStop->1"));
BLEStopAt = esp_timer_get_time(); BLEStopAt = esp_timer_get_time();
// give a little time for it to stop. // give a little time for it to stop.
vTaskDelay(1000/ portTICK_PERIOD_MS); vTaskDelay(100/ portTICK_PERIOD_MS);
return 1; return 1;
} }
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: StopBLE - wait as BLEStop==1")); AddLog(LOG_LEVEL_ERROR,PSTR("BLE: StopBLE - wait as BLEStop==1"));
@ -2654,6 +2671,21 @@ void CmndBLEMode(void){
} }
} }
//////////////////////////////////////////////////////////////
// Enables BLE even if master enable is unset
// use to temporarily enable after boot - e.g. at the end of autoexec
void CmndBLEEnableUnsaved(void){
int val = -1;
if (XdrvMailbox.data_len > 0) {
val = XdrvMailbox.payload;
}
if (val >= 0){
BLEEnableUnsaved = val;
}
ResponseCmndNumber(BLEEnableUnsaved);
}
////////////////////////////////////////// //////////////////////////////////////////
// get more drtails for a single MAC address // get more drtails for a single MAC address
@ -3036,7 +3068,7 @@ static void BLEPostMQTT(bool onlycompleted) {
// if (TasmotaGlobal.ota_state_flag) return; // if (TasmotaGlobal.ota_state_flag) return;
if (prepOperation || completedOperations.size() || queuedOperations.size() || currentOperations.size()){ if (prepOperation || mqttOperations.size() || queuedOperations.size() || currentOperations.size()){
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_INFO,PSTR("BLE: some to show")); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_INFO,PSTR("BLE: some to show"));
#endif #endif
@ -3094,17 +3126,17 @@ static void BLEPostMQTT(bool onlycompleted) {
} }
} }
if (completedOperations.size()){ if (mqttOperations.size()){
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_INFO,PSTR("BLE: completed %d"), completedOperations.size()); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_INFO,PSTR("BLE: completed %d"), mqttOperations.size());
#endif #endif
do { do {
generic_sensor_t *toSend = nextOperation(&completedOperations); generic_sensor_t *toSend = nextOperation(&mqttOperations);
if (!toSend) { if (!toSend) {
break; // break from while loop break; // break from while loop
} else { } else {
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: completedOperation removed")); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: mqttOperation removed opid %d"), toSend->opid);
#endif #endif
std::string out = BLETriggerResponse(toSend); std::string out = BLETriggerResponse(toSend);
snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("%s"), out.c_str()); snprintf_P(TasmotaGlobal.mqtt_data, sizeof(TasmotaGlobal.mqtt_data), PSTR("%s"), out.c_str());
@ -3176,12 +3208,13 @@ static void mainThreadOpCallbacks() {
bool callbackres = false; bool callbackres = false;
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback is %u opid %d"), op->completecallback, op->opid);
if (op->completecallback){ if (op->completecallback){
try { try {
OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback); OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback);
callbackres = pFn(op); callbackres = pFn(op);
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d"), callbackres); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d opid %d"), callbackres, op->opid);
#endif #endif
} catch(const std::exception& e){ } catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
@ -3193,6 +3226,7 @@ static void mainThreadOpCallbacks() {
if (!callbackres){ if (!callbackres){
for (int i = 0; i < operationsCallbacks.size(); i++){ for (int i = 0; i < operationsCallbacks.size(); i++){
try { try {
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d is %u"), i, operationsCallbacks[i]);
OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i]; OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i];
callbackres = pFn(op); callbackres = pFn(op);
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
@ -3209,12 +3243,16 @@ static void mainThreadOpCallbacks() {
} }
} }
// if some callback told us not to send on MQTT, then remove from completed and delete the data // always remove from here
if (callbackres){ completedOperations.erase(completedOperations.begin() + i);
// unless some callback told us not to send on MQTT, then remove from completed and
// add to mqtt list
if (!callbackres){
addOperation(&mqttOperations, &op);
} else {
#ifdef BLE_ESP32_DEBUG #ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: callbackres true -> delete op")); if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: callbackres true -> delete op opid %d"), op->opid);
#endif #endif
completedOperations.erase(completedOperations.begin() + i);
delete op; delete op;
} }
} }
@ -3462,8 +3500,15 @@ void HandleBleConfiguration(void)
int ExtStopBLE(){ int ExtStopBLE(){
AddLog(LOG_LEVEL_INFO, PSTR("BLE: Stopping if active")); AddLog(LOG_LEVEL_INFO, PSTR("BLE: Stopping if active"));
BLE_ESP32::BLEMode = BLE_ESP32::BLEModeDisabled; BLE_ESP32::BLEEnableMask = 0;
BLE_ESP32::StopBLE(); BLE_ESP32::stopStartBLE();
return 0;
}
int ExtRestartBLEIfEnabled(){
AddLog(LOG_LEVEL_INFO, PSTR("BLE: Starting if active"));
BLE_ESP32::BLEEnableMask = 1;
BLE_ESP32::stopStartBLE();
return 0; return 0;
} }