MI32 legacy: add optional argument to BLE.run() (#20431)

* add optional argument to BLE.run()

* set default of scan response to NO
This commit is contained in:
Christian Baars 2024-01-09 09:10:45 +01:00 committed by GitHub
parent 2f6ab10146
commit 81fac80859
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 94 additions and 35 deletions

View File

@ -64,8 +64,8 @@ BE_FUNC_CTYPE_DECLARE(be_BLE_set_MAC, "", "@(bytes)~[i]");
extern void be_BLE_set_characteristic(struct bvm *vm, const char *Chr);
BE_FUNC_CTYPE_DECLARE(be_BLE_set_characteristic, "", "@s");
extern void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response);
BE_FUNC_CTYPE_DECLARE(be_BLE_run, "", "@i[b]");
extern void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response, int32_t arg1);
BE_FUNC_CTYPE_DECLARE(be_BLE_run, "", "@i[bi]");
extern void be_BLE_set_service(struct bvm *vm, const char *Svc, bbool discoverAttributes);
BE_FUNC_CTYPE_DECLARE(be_BLE_set_service, "", "@s[b]");

View File

@ -67,7 +67,7 @@ void NimBLEAdvertising::reset() {
m_advParams.disc_mode = BLE_GAP_DISC_MODE_GEN;
m_customAdvData = false;
m_customScanResponseData = false;
m_scanResp = true;
m_scanResp = false;
m_advDataSet = false;
// Set this to non-zero to prevent auto start if host reset before started by app.
m_duration = BLE_HS_FOREVER;

View File

@ -156,11 +156,13 @@ struct MI32connectionContextBerry_t{
NimBLEUUID charUUID;
uint16_t returnCharUUID;
uint16_t handle;
uint8_t MAC[6];
uint8_t * buffer;
uint8_t MAC[6];
uint8_t operation;
uint8_t addrType;
int error;
int32_t arg1;
bool hasArg1;
bool oneOp;
bool response;
};

View File

@ -80,7 +80,7 @@ extern "C" {
extern void MI32setBerryAdvCB(void* function, uint8_t *buffer);
extern void MI32setBerryConnCB(void* function, uint8_t *buffer);
extern void MI32setBerryServerCB(void* function, uint8_t *buffer);
extern bool MI32runBerryConnection(uint8_t operation, bbool response);
extern bool MI32runBerryConnection(uint8_t operation, bbool response, int32_t *arg1);
extern bool MI32setBerryCtxSvc(const char *Svc, bbool discoverAttributes);
extern bool MI32setBerryCtxChr(const char *Chr);
extern bool MI32setBerryCtxMAC(uint8_t *MAC, uint8_t type);
@ -161,13 +161,19 @@ extern "C" {
be_raisef(vm, "ble_error", "BLE: could not set characteristic");
}
void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response);
void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response){
void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response, int32_t arg1);
void be_BLE_run(struct bvm *vm, uint8_t operation, bbool response, int32_t arg1){
int32_t argc = be_top(vm); // Get the number of arguments
bool _response = false;
if(response){
_response = response;
}
if (MI32runBerryConnection(operation,_response)) return;
int32_t *ptr_arg1 = nullptr;
int32_t _arg1 = arg1;
if(argc == 3){
ptr_arg1 = &_arg1;
}
if (MI32runBerryConnection(operation, _response, ptr_arg1)) return;
be_raisef(vm, "ble_error", "BLE: could not run operation");
}

View File

@ -93,6 +93,7 @@ class MI32SensorCallback : public NimBLEClientCallbacks {
MI32.infoMsg = MI32_DID_CONNECT;
MI32.mode.willConnect = 0;
MI32.mode.connected = 1;
pclient->updateConnParams(8,11,0,1000);
}
void onDisconnect(NimBLEClient* pclient) {
MI32.mode.connected = 0;
@ -250,7 +251,7 @@ void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pD
memcpy(item.buffer,pData,length);
item.header.returnCharUUID = pRemoteCharacteristic->getUUID().getNative()->u16.value;
item.header.handle = pRemoteCharacteristic->getHandle();
xRingbufferSend(BLERingBufferQueue, (const void*)&item, sizeof(BLERingBufferItem_t) + length , pdMS_TO_TICKS(1));
xRingbufferSend(BLERingBufferQueue, (const void*)&item, sizeof(BLERingBufferItem_t) + length , pdMS_TO_TICKS(5));
MI32.mode.readingDone = 1;
MI32.infoMsg = MI32_GOT_NOTIFICATION;
return;
@ -711,9 +712,8 @@ extern "C" {
MI32BLELoop();
}
bool MI32runBerryServer(uint16_t operation, bool response){
bool MI32runBerryServer(uint16_t operation){
MI32.conCtx->operation = operation;
MI32.conCtx->response = response;
AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Berry server op: %d, response: %u"),MI32.conCtx->operation, MI32.conCtx->response);
if(MI32.mode.readyForNextServerJob == 0){
MI32.mode.triggerNextServerJob = 0;
@ -724,14 +724,22 @@ extern "C" {
return true;
}
bool MI32runBerryConnection(uint8_t operation, bool response){
bool MI32runBerryConnection(uint8_t operation, bool response, int32_t* arg1){
if(MI32.conCtx != nullptr){
if(arg1 != nullptr){
MI32.conCtx->arg1 = *arg1;
MI32.conCtx->hasArg1 = true;
AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: arg1: %u"),MI32.conCtx->arg1);
}
else{
MI32.conCtx->hasArg1 = false;
}
MI32.conCtx->response = response;
if(operation > 200){
return MI32runBerryServer(operation,response);
return MI32runBerryServer(operation);
}
MI32.conCtx->oneOp = (operation > 9);
MI32.conCtx->operation = operation%10;
MI32.conCtx->response = response;
AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: 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){
MI32StartConnectionTask();
@ -1240,7 +1248,7 @@ void MI32ConnectionTask(void *pvParameters){
timer++;
vTaskDelay(10/ portTICK_PERIOD_MS);
}
if(MI32.mode.discoverAttributes){
if(MI32.mode.discoverAttributes || MI32.conCtx->hasArg1){ // explicit or in the first run with selection by handle
MI32Client->discoverAttributes(); // solves connection problems on i.e. yeelight dimmer
}
NimBLERemoteService* pSvc = nullptr;
@ -1270,9 +1278,14 @@ void MI32ConnectionTask(void *pvParameters){
if(MI32.conCtx->operation == 6){ // get remote services to Berry
MI32ConnectionGetServices();
}
else{
if(MI32.conCtx->hasArg1){
pSvc = nullptr; // invalidate possible dangling service from last operation
}
else{
pSvc = MI32Client->getService(MI32.conCtx->serviceUUID);
}
}
if(pSvc) {
if(MI32.conCtx->operation == 7){ // get remote characteristics to Berry
@ -1282,6 +1295,9 @@ void MI32ConnectionTask(void *pvParameters){
pChr = pSvc->getCharacteristic(MI32.conCtx->charUUID);
}
}
else if(MI32.conCtx->hasArg1){
pChr = MI32Client->getCharacteristic(MI32.conCtx->arg1); // get by handle, overriding svc and chr values
}
else{
if(MI32.conCtx->operation != 6){
MI32.conCtx->error = MI32_CONN_NO_SERVICE;
@ -1294,6 +1310,7 @@ void MI32ConnectionTask(void *pvParameters){
NimBLEAttValue _val = pChr->readValue();
MI32.conCtx->buffer[0] = _val.size();
memcpy( MI32.conCtx->buffer + 1,_val.data(),MI32.conCtx->buffer[0]);
MI32.conCtx->handle = pChr->getHandle();
}
else{
MI32.conCtx->error = MI32_CONN_CAN_NOT_READ;
@ -1304,6 +1321,7 @@ void MI32ConnectionTask(void *pvParameters){
uint8_t len = MI32.conCtx->buffer[0];
if(pChr->writeValue(MI32.conCtx->buffer + 1,len,MI32.conCtx->response & !pChr->canWriteNoResponse())) { // falls always back to "no response" if server provides both options
// AddLog(LOG_LEVEL_DEBUG,PSTR("M32: write op done"));
MI32.conCtx->handle = pChr->getHandle();
}
else{
MI32.conCtx->error = MI32_CONN_DID_NOT_WRITE;
@ -1322,16 +1340,32 @@ void MI32ConnectionTask(void *pvParameters){
break;
}
}
if(MI32.conCtx->hasArg1){ // characteristic selected by handle
if (pChr->canNotify()) {
if(!pChr->subscribe(true, MI32notifyCB, MI32.conCtx->response)) {
MI32.conCtx->error = MI32_CONN_CAN_NOT_NOTIFY; // will return the last result only ATM, maybe check differently
}
}
}
else { // characteristic selected by UUID
charvector = pSvc->getCharacteristics(true); // always try to subscribe to all characteristics with the same UUID
uint32_t position = 1;
for (auto &it: *charvector) {
if (it->getUUID() == MI32.conCtx->charUUID) {
if (it->canNotify()) {
if(!it->subscribe(true, MI32notifyCB, MI32.conCtx->response)) {
MI32.conCtx->error = MI32_CONN_CAN_NOT_NOTIFY; // will return the last result only ATM, maybe check differently
}
else{
MI32.conCtx->buffer[position++] = it->getHandle() >> 8;
MI32.conCtx->buffer[position++] = it->getHandle() & 0xff;
MI32.conCtx->handle = it->getHandle();
}
}
}
}
MI32.conCtx->buffer[0] = position - 1;
}
break;
default:
break;
@ -1416,6 +1450,15 @@ void MI32ServerSetAdv(NimBLEServer *pServer, std::vector<NimBLEService*>& servic
*/
void MI32ServerSetAdv(NimBLEServer *pServer, std::vector<NimBLEService*>& servicesToStart, bool &shallStartServices){
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
/** optional argument arg1
BLE_GAP_CONN_MODE_NON (0) - not connectable advertising
BLE_GAP_CONN_MODE_DIR (1) - directed connectable advertising
BLE_GAP_CONN_MODE_UND (2) - undirected connectable advertising
*/
if(MI32.conCtx->hasArg1){
pAdvertising->setAdvertisementType(MI32.conCtx->arg1);
// AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: AdvertisementType: %u"),MI32.conCtx->arg1);
}
struct{
BLERingBufferItem_t header;
uint8_t buffer[255];
@ -1447,7 +1490,10 @@ void MI32ServerSetAdv(NimBLEServer *pServer, std::vector<NimBLEService*>& servic
adv.addData((char *)&MI32.conCtx->buffer[1], MI32.conCtx->buffer[0]);
if(MI32.conCtx->operation == BLE_OP_SET_ADV){
pAdvertising->setAdvertisementData(adv); // replace whole advertisement with our custom data from the Berry side
if(pAdvertising->isAdvertising() == false && !shallStartServices){ // first advertisement
vTaskDelay(1000/ portTICK_PERIOD_MS); // work around to prevent crash on start
pAdvertising->start();
}
} else
{
pAdvertising->setScanResponseData(adv);
@ -1486,11 +1532,16 @@ void MI32ServerSetCharacteristic(NimBLEServer *pServer, std::vector<NimBLEServic
NimBLECharacteristic *pCharacteristic = pService->getCharacteristic(MI32.conCtx->charUUID); // again retrieve ...
if(pCharacteristic == nullptr){
uint32_t _writeRSP = MI32.conCtx->response ? NIMBLE_PROPERTY::WRITE : NIMBLE_PROPERTY::WRITE_NR;
pCharacteristic = pService->createCharacteristic(MI32.conCtx->charUUID,
NIMBLE_PROPERTY::READ |
uint32_t _property = NIMBLE_PROPERTY::READ |
_writeRSP |
NIMBLE_PROPERTY::NOTIFY |
NIMBLE_PROPERTY::INDICATE); //... or create characteristic.
NIMBLE_PROPERTY::INDICATE; // default to "all"
if(MI32.conCtx->hasArg1){
_property = MI32.conCtx->arg1; // override with optional argument
// AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: _property: %u"),_property);
}
pCharacteristic = pService->createCharacteristic(MI32.conCtx->charUUID,
_property); //... or create characteristic.
if(pCharacteristic == nullptr){
MI32.conCtx->error = MI32_CONN_NO_CHARACTERISTIC;
return;
@ -1499,7 +1550,7 @@ void MI32ServerSetCharacteristic(NimBLEServer *pServer, std::vector<NimBLEServic
MI32.infoMsg = MI32_SERV_CHARACTERISTIC_ADDED;
}
pCharacteristic->setValue(MI32.conCtx->buffer + 1, MI32.conCtx->buffer[0]); // set value
pCharacteristic->notify(true); // always notify .. for now
pCharacteristic->notify(true); // TODO: fallback to indication
struct{
BLERingBufferItem_t header;
} item;