Merge pull request #15228 from Staars/MI32

MI32: refactoring conn task, bugfix, add response to op
This commit is contained in:
Theo Arends 2022-03-26 11:33:17 +01:00 committed by GitHub
commit d17cbdd6e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 144 additions and 88 deletions

View File

@ -118,7 +118,7 @@ extern "C" {
********************************************************************/ ********************************************************************/
extern void MI32setBerryAdvCB(void* function, uint8_t *buffer); extern void MI32setBerryAdvCB(void* function, uint8_t *buffer);
extern void MI32setBerryConnCB(void* function, uint8_t *buffer); extern void MI32setBerryConnCB(void* function, uint8_t *buffer);
extern bool MI32runBerryConnection(uint8_t operation); extern bool MI32runBerryConnection(uint8_t operation, bool response);
extern bool MI32setBerryCtxSvc(const char *Svc); extern bool MI32setBerryCtxSvc(const char *Svc);
extern bool MI32setBerryCtxChr(const char *Chr); extern bool MI32setBerryCtxChr(const char *Chr);
extern bool MI32setBerryCtxMAC(uint8_t *MAC, uint8_t type); extern bool MI32setBerryCtxMAC(uint8_t *MAC, uint8_t type);
@ -193,8 +193,12 @@ extern "C" {
int be_BLE_run(bvm *vm); int be_BLE_run(bvm *vm);
int be_BLE_run(bvm *vm){ int be_BLE_run(bvm *vm){
int32_t argc = be_top(vm); // Get the number of arguments int32_t argc = be_top(vm); // Get the number of arguments
if ((argc == 2) && be_isint(vm, 2)) { if ((argc > 1) && be_isint(vm, 2)) {
if (MI32runBerryConnection(be_toint(vm, 2))) be_return(vm); bool response = false;
if(argc == 3 && be_isint(vm, 3)){
response = be_toint(vm,3)>0;
}
if (MI32runBerryConnection(be_toint(vm, 2),response)) be_return(vm);
} }
be_raise(vm, kTypeError, nullptr); be_raise(vm, kTypeError, nullptr);
} }

View File

@ -154,6 +154,7 @@ struct MI32connectionContextBerry_t{
uint8_t addrType; uint8_t addrType;
int error; int error;
bool oneOp; bool oneOp;
bool response;
}; };
struct { struct {
@ -180,6 +181,8 @@ struct {
uint32_t didStartHAP:1; uint32_t didStartHAP:1;
uint32_t triggerBerryAdvCB:1; uint32_t triggerBerryAdvCB:1;
uint32_t triggerBerryConnCB:1; uint32_t triggerBerryConnCB:1;
uint32_t triggerNextConnJob:1;
uint32_t readyForNextConnJob:1;
}; };
uint32_t all = 0; uint32_t all = 0;
} mode; } mode;
@ -382,7 +385,7 @@ const char * kMI32DeviceType[] PROGMEM = {kMI32DeviceType1,kMI32DeviceType2,kMI3
kMI32DeviceType9,kMI32DeviceType10,kMI32DeviceType11,kMI32DeviceType12, kMI32DeviceType9,kMI32DeviceType10,kMI32DeviceType11,kMI32DeviceType12,
kMI32DeviceType13,kMI32DeviceType14,kMI32DeviceType15,kMI32DeviceType16}; kMI32DeviceType13,kMI32DeviceType14,kMI32DeviceType15,kMI32DeviceType16};
const char kMI32_ConnErrorMsg[] PROGMEM = "no Error|could not connect|got no service|got no characteristic|can not read|can not notify|can not write|did not write|notify time out"; const char kMI32_ConnErrorMsg[] PROGMEM = "no Error|could not connect|did disconnect|got no service|got no characteristic|can not read|can not notify|can not write|did not write|notify time out";
const char kMI32_BLEInfoMsg[] PROGMEM = "Scan ended|Got Notification|Did connect|Did disconnect|Still connected|Start scanning"; const char kMI32_BLEInfoMsg[] PROGMEM = "Scan ended|Got Notification|Did connect|Did disconnect|Still connected|Start scanning";
@ -407,6 +410,7 @@ enum MI32_TASK {
enum MI32_ConnErrorMsg { enum MI32_ConnErrorMsg {
MI32_CONN_NO_ERROR = 0, MI32_CONN_NO_ERROR = 0,
MI32_CONN_NO_CONNECT, MI32_CONN_NO_CONNECT,
MI32_CONN_DID_DISCCONNECT,
MI32_CONN_NO_SERVICE, MI32_CONN_NO_SERVICE,
MI32_CONN_NO_CHARACTERISTIC, MI32_CONN_NO_CHARACTERISTIC,
MI32_CONN_CAN_NOT_READ, MI32_CONN_CAN_NOT_READ,

View File

@ -22,6 +22,9 @@
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
Version yyyymmdd Action Description Version yyyymmdd Action Description
-------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------
0.9.5.5 20220326 changed - refactored connection task for asynchronous op, add response option,
fixed MI32Key command
-------
0.9.5.4 20220325 changed - add Berry adv_watch and adv_block to BLE class 0.9.5.4 20220325 changed - add Berry adv_watch and adv_block to BLE class
------- -------
0.9.5.3 20220315 changed - reworked Berry part, active scanning and holding active connections possible, new format of advertisement buffer 0.9.5.3 20220315 changed - reworked Berry part, active scanning and holding active connections possible, new format of advertisement buffer
@ -93,6 +96,8 @@ class MI32SensorCallback : public NimBLEClientCallbacks {
void onDisconnect(NimBLEClient* pclient) { void onDisconnect(NimBLEClient* pclient) {
MI32.mode.connected = 0; MI32.mode.connected = 0;
MI32.infoMsg = MI32_DID_DISCONNECT; MI32.infoMsg = MI32_DID_DISCONNECT;
MI32.conCtx->error = MI32_CONN_DID_DISCCONNECT;
MI32.mode.triggerBerryConnCB = 1; //mainly for unexpected or requested disconnects
//AddLog(LOG_LEVEL_DEBUG,PSTR("disconnected")); //AddLog(LOG_LEVEL_DEBUG,PSTR("disconnected"));
} }
bool onConnParamsUpdateRequest(NimBLEClient* MI32Client, const ble_gap_upd_params* params) { bool onConnParamsUpdateRequest(NimBLEClient* MI32Client, const ble_gap_upd_params* params) {
@ -169,12 +174,15 @@ void MI32scanEndedCB(NimBLEScanResults results){
void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){ void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){
if(MI32.mode.triggerBerryConnCB) return; //discard data, if we did not pass the old to Berry yet if(MI32.mode.triggerBerryConnCB) return; //discard data, if we did not pass the old to Berry yet
if(isNotify){
MI32.infoMsg = MI32_GOT_NOTIFICATION; MI32.infoMsg = MI32_GOT_NOTIFICATION;
MI32.conCtx->buffer[0] = (uint8_t)length; MI32.conCtx->buffer[0] = (uint8_t)length;
memcpy(MI32.conCtx->buffer + 1, pData, length); memcpy(MI32.conCtx->buffer + 1, pData, length);
MI32.conCtx->returnCharUUID = pRemoteCharacteristic->getUUID().getNative()->u16.value; MI32.conCtx->returnCharUUID = pRemoteCharacteristic->getUUID().getNative()->u16.value;
MI32.conCtx->operation = 103;
MI32.mode.triggerBerryConnCB = 1; MI32.mode.triggerBerryConnCB = 1;
MI32.mode.readingDone = 1; MI32.mode.readingDone = 1;
}
} }
/*********************************************************************************************\ /*********************************************************************************************\
* Helper functions * Helper functions
@ -238,15 +246,13 @@ void MI32_ReverseMAC(uint8_t _mac[]){
void MI32AddKey(mi_bindKey_t keyMAC){ void MI32AddKey(mi_bindKey_t keyMAC){
bool unknownMAC = true; bool unknownMAC = true;
for(auto _sensor : MIBLEsensors){ for(auto &_sensor : MIBLEsensors){
if(memcmp(keyMAC.MAC,_sensor.MAC,sizeof(keyMAC.MAC))==0){ if(memcmp(keyMAC.MAC,_sensor.MAC,sizeof(keyMAC.MAC))==0){
AddLog(LOG_LEVEL_DEBUG,PSTR("new key")); _sensor.key = new uint8_t[16];
uint8_t* _key = (uint8_t*) malloc(16); memcpy(_sensor.key,keyMAC.key,16);
memcpy(_key,keyMAC.key,16);
_sensor.key = _key;
unknownMAC=false; unknownMAC=false;
_sensor.status.hasWrongKey = 0; _sensor.status.hasWrongKey = 0;
AddLogBuffer(LOG_LEVEL_DEBUG,(uint8_t*) _sensor.key, 16); AddLog(LOG_LEVEL_INFO,PSTR("add key to %s"),kMI32DeviceType[_sensor.type-1]);
} }
} }
if(unknownMAC){ if(unknownMAC){
@ -638,6 +644,7 @@ void MI32Init(void) {
NimBLEDevice::init(""); NimBLEDevice::init("");
AddLog(LOG_LEVEL_INFO,PSTR("M32: Init BLE device")); AddLog(LOG_LEVEL_INFO,PSTR("M32: Init BLE device"));
MI32.mode.init = 1; MI32.mode.init = 1;
MI32.mode.readyForNextConnJob = 1;
MI32StartTask(MI32_TASK_SCAN); // Let's get started !! MI32StartTask(MI32_TASK_SCAN); // Let's get started !!
} }
#ifdef USE_MI_EXT_GUI #ifdef USE_MI_EXT_GUI
@ -653,12 +660,27 @@ void MI32Init(void) {
\*********************************************************************************************/ \*********************************************************************************************/
extern "C" { extern "C" {
bool MI32runBerryConnection(uint8_t operation){ bool MI32runBerryConnection(uint8_t operation, bool response){
if(MI32.conCtx != nullptr){ if(MI32.conCtx != nullptr){
MI32.conCtx->oneOp = (operation > 9); MI32.conCtx->oneOp = (operation > 9);
MI32.conCtx->operation = operation%10; MI32.conCtx->operation = operation%10;
AddLog(LOG_LEVEL_INFO,PSTR("M32: Berry connection op: %d, addrType: %d, oneOp: %u"),MI32.conCtx->operation, MI32.conCtx->addrType, MI32.conCtx->oneOp); MI32.conCtx->response = response;
AddLog(LOG_LEVEL_DEBUG,PSTR("M32: Berry connection op: %d, addrType: %d, oneOp: %u, response: %u"),MI32.conCtx->operation, MI32.conCtx->addrType, MI32.conCtx->oneOp, MI32.conCtx->response);
if(MI32.conCtx->oneOp || MI32.conCtx->operation == 5){ //...or disconnect is requested
MI32StartConnectionTask(); MI32StartConnectionTask();
}
else{
if(MI32.mode.connected){
AddLog(LOG_LEVEL_DEBUG,PSTR("M32: continue connection job"));
MI32.mode.triggerNextConnJob = 1;
if(!MI32.mode.readyForNextConnJob){
AddLog(LOG_LEVEL_DEBUG,PSTR("M32: old connection job not finished yet!!"));
}
}
else{
MI32StartConnectionTask(); //first job of many or unexpected disconnect
}
}
return true; return true;
} }
return false; return false;
@ -676,7 +698,7 @@ extern "C" {
bool MI32setBerryCtxSvc(const char *Svc){ bool MI32setBerryCtxSvc(const char *Svc){
if(MI32.conCtx != nullptr){ if(MI32.conCtx != nullptr){
MI32.conCtx->serviceUUID = NimBLEUUID(Svc); MI32.conCtx->serviceUUID = NimBLEUUID(Svc);
AddLog(LOG_LEVEL_INFO,PSTR("M32: SVC: %s"),MI32.conCtx->serviceUUID.toString().c_str()); AddLog(LOG_LEVEL_DEBUG,PSTR("M32: SVC: %s"),MI32.conCtx->serviceUUID.toString().c_str());
return true; return true;
} }
return false; return false;
@ -685,10 +707,10 @@ extern "C" {
bool MI32setBerryCtxChr(const char *Chr){ bool MI32setBerryCtxChr(const char *Chr){
if(MI32.conCtx != nullptr){ if(MI32.conCtx != nullptr){
MI32.conCtx->charUUID = NimBLEUUID(Chr); MI32.conCtx->charUUID = NimBLEUUID(Chr);
AddLog(LOG_LEVEL_INFO,PSTR("M32: CHR: %s"),MI32.conCtx->charUUID.toString().c_str()); AddLog(LOG_LEVEL_DEBUG,PSTR("M32: CHR: %s"),MI32.conCtx->charUUID.toString().c_str());
uint16_t _uuid = MI32.conCtx->charUUID.getNative()->u16.value; //if not "notify op" -> present requested characteristic as return UUID uint16_t _uuid = MI32.conCtx->charUUID.getNative()->u16.value; //if not "notify op" -> present requested characteristic as return UUID
MI32.conCtx->returnCharUUID = _uuid; MI32.conCtx->returnCharUUID = _uuid;
AddLog(LOG_LEVEL_INFO,PSTR("M32: return UUID: %04x"),MI32.conCtx->returnCharUUID); AddLog(LOG_LEVEL_DEBUG,PSTR("M32: return UUID: %04x"),MI32.conCtx->returnCharUUID);
return true; return true;
} }
return false; return false;
@ -732,7 +754,7 @@ extern "C" {
return false; return false;
} }
} }
AddLog(LOG_LEVEL_INFO,PSTR("M32: add %s to watchlist of size: %u"),_newAddress.toString().c_str(),NimBLEDevice::getWhiteListCount()); AddLog(LOG_LEVEL_DEBUG,PSTR("M32: add %s to watchlist of size: %u"),_newAddress.toString().c_str(),NimBLEDevice::getWhiteListCount());
return true; return true;
} }
@ -1120,7 +1142,6 @@ bool MI32StartConnectionTask(){
void MI32ConnectionTask(void *pvParameters){ void MI32ConnectionTask(void *pvParameters){
NimBLEDevice::setOwnAddrType(BLE_OWN_ADDR_RANDOM,false); //seems to be important for i.e. xbox controller, hopefully not breaking other things NimBLEDevice::setOwnAddrType(BLE_OWN_ADDR_RANDOM,false); //seems to be important for i.e. xbox controller, hopefully not breaking other things
NimBLEDevice::setSecurityAuth(true, true, true); NimBLEDevice::setSecurityAuth(true, true, true);
MI32.conCtx->error = MI32_CONN_NO_ERROR; MI32.conCtx->error = MI32_CONN_NO_ERROR;
if (MI32ConnectActiveSensor()){ if (MI32ConnectActiveSensor()){
MI32.mode.readingDone = 0; MI32.mode.readingDone = 0;
@ -1139,9 +1160,25 @@ void MI32ConnectionTask(void *pvParameters){
timer++; timer++;
vTaskDelay(10/ portTICK_PERIOD_MS); vTaskDelay(10/ portTICK_PERIOD_MS);
} }
MI32Client->discoverAttributes(); // solves connection problems on i.e. yeelight dimmer
NimBLERemoteService* pSvc = nullptr; NimBLERemoteService* pSvc = nullptr;
NimBLERemoteCharacteristic* pChr = nullptr; NimBLERemoteCharacteristic* pChr = nullptr;
// AddLog(LOG_LEVEL_INFO,PSTR("M32: start connection loop"));
bool keepConnectionAlive = true;
MI32.mode.triggerNextConnJob = 1;
while(keepConnectionAlive){
while(MI32.mode.triggerNextConnJob == 0){
vTaskDelay(50/ portTICK_PERIOD_MS);
if(MI32.mode.connected == 0){
MI32StartTask(MI32_TASK_SCAN);
vTaskDelete( NULL );
}
// AddLog(LOG_LEVEL_INFO,PSTR("M32: wait ..."));
}
// AddLog(LOG_LEVEL_INFO,PSTR("M32: really start connection job now ..."));
MI32.mode.triggerNextConnJob = 0;
MI32.mode.readyForNextConnJob = 0;
pSvc = MI32Client->getService(MI32.conCtx->serviceUUID); pSvc = MI32Client->getService(MI32.conCtx->serviceUUID);
if(pSvc) { if(pSvc) {
pChr = pSvc->getCharacteristic(MI32.conCtx->charUUID); pChr = pSvc->getCharacteristic(MI32.conCtx->charUUID);
@ -1153,10 +1190,9 @@ void MI32ConnectionTask(void *pvParameters){
switch(MI32.conCtx->operation){ switch(MI32.conCtx->operation){
case 1: case 1:
if(pChr->canRead()) { if(pChr->canRead()) {
std::string _val = pChr->readValue(); NimBLEAttValue _val = pChr->readValue();
MI32.conCtx->buffer[0] = (uint8_t)_val.size(); MI32.conCtx->buffer[0] = _val.size();
const char *_c_val = _val.c_str(); memcpy( MI32.conCtx->buffer + 1,_val.data(),MI32.conCtx->buffer[0]);
memcpy( MI32.conCtx->buffer + 1,_c_val,MI32.conCtx->buffer[0]);
} }
else{ else{
MI32.conCtx->error = MI32_CONN_CAN_NOT_READ; MI32.conCtx->error = MI32_CONN_CAN_NOT_READ;
@ -1165,7 +1201,7 @@ void MI32ConnectionTask(void *pvParameters){
case 2: case 2:
if(pChr->canWrite()) { if(pChr->canWrite()) {
uint8_t len = MI32.conCtx->buffer[0]; uint8_t len = MI32.conCtx->buffer[0];
if(pChr->writeValue(MI32.conCtx->buffer + 1,len,true)) { // true is important ! if(pChr->writeValue(MI32.conCtx->buffer + 1,len,MI32.conCtx->response)) { // true is important !
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: write op done")); // AddLog(LOG_LEVEL_DEBUG,PSTR("M32: write op done"));
} }
else{ else{
@ -1179,7 +1215,9 @@ void MI32ConnectionTask(void *pvParameters){
break; break;
case 3: case 3:
if(pChr->canNotify()) { if(pChr->canNotify()) {
if(pChr->subscribe(true,MI32notifyCB,false)) AddLog(LOG_LEVEL_DEBUG,PSTR("M32: subscribe")); if(pChr->subscribe(true,MI32notifyCB, MI32.conCtx->response)){
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: subscribe"));
}
} }
else{ else{
MI32.conCtx->error = MI32_CONN_CAN_NOT_NOTIFY; MI32.conCtx->error = MI32_CONN_CAN_NOT_NOTIFY;
@ -1195,7 +1233,7 @@ void MI32ConnectionTask(void *pvParameters){
timer = 0; timer = 0;
while (timer<150){ while (timer<150){
if (MI32.mode.readingDone){ if (MI32.mode.readingDone || !MI32.conCtx->oneOp){
break; break;
} }
else{ else{
@ -1210,12 +1248,22 @@ void MI32ConnectionTask(void *pvParameters){
if(MI32.conCtx->oneOp){ if(MI32.conCtx->oneOp){
MI32Client->disconnect(); MI32Client->disconnect();
MI32.mode.connected = 0; MI32.mode.connected = 0;
DEBUG_SENSOR_LOG(PSTR("M32: requested disconnect")); keepConnectionAlive = false;
MI32StartTask(MI32_TASK_SCAN); MI32StartTask(MI32_TASK_SCAN);
} }
else{
MI32.mode.readyForNextConnJob = 1;
MI32.mode.triggerBerryConnCB = 1;
}
}
} }
else{ else{
MI32.conCtx->error = MI32_CONN_NO_CONNECT; // not connected if(MI32.conCtx->operation==5){
MI32.conCtx->error = MI32_CONN_DID_DISCCONNECT; // did succesfully disconnect
}
else{
MI32.conCtx->error = MI32_CONN_NO_CONNECT; // could not connect
}
MI32.mode.connected = 0; MI32.mode.connected = 0;
MI32StartTask(MI32_TASK_SCAN); MI32StartTask(MI32_TASK_SCAN);
} }