Add "mac_type" parameter to BLE connection commands. (#1146)

This allows for connecting to devices that do not use the MAC address type 0.
This also adds the logging of the "mac_type" so it is visible to users trying to connect to broadcasting devices.

Additionally this will allow for future connectable devices using a MAC address type other than 0 to be automatically connected to
when support is added for them, similar to LYWSD03MMC etc..
This commit is contained in:
h2zero authored and GitHub committed 2022-01-25 06:19:50 -06:00
1 parent e838d3cee0
commit f8b4b3ca21
3 files changed
+23 -8

No files matched your search

+3
View File
@@ -166,6 +166,9 @@ The gateway can read and write BLE characteristics from devices and provide the
::: tip ::: tip
These actions will be taken on the next BLE connection, which occurs after scanning and after the scan count is reached, [see above to set this.](#setting-the-number-of-scans-between-connection-attempts) These actions will be taken on the next BLE connection, which occurs after scanning and after the scan count is reached, [see above to set this.](#setting-the-number-of-scans-between-connection-attempts)
This can be overridden by providing an (optional) parameter `"immediate": true` within the command. This will cause the BLE scan to stop if currently in progress, allowing the command to be immediately processed. All other connection commands in queue will also be processed for the same device, commands for other devices will be deferred until the next normally scheduled connection. This can be overridden by providing an (optional) parameter `"immediate": true` within the command. This will cause the BLE scan to stop if currently in progress, allowing the command to be immediately processed. All other connection commands in queue will also be processed for the same device, commands for other devices will be deferred until the next normally scheduled connection.
**Note** Some devices need to have the mac address type specified. You can find this type by checking the log/mqtt data and looking for "mac_type". By default the type is 0 but some devices use different type values. You must specify the correct type to connect successfully.
To specify the MAC address type add the parameter `"mac_type"` to the command. For example `"mac_type": 1` to connect with a device with the MAC address type of 1.
::: :::
### Example write command ### Example write command
+18 -8
View File
@@ -201,7 +201,7 @@ void pubBT(JsonObject& data) {
bool ProcessLock = false; // Process lock when we want to use a critical function like OTA for example bool ProcessLock = false; // Process lock when we want to use a critical function like OTA for example
BLEdevice* getDeviceByMac(const char* mac); BLEdevice* getDeviceByMac(const char* mac);
void createOrUpdateDevice(const char* mac, uint8_t flags, int model); void createOrUpdateDevice(const char* mac, uint8_t flags, int model, int mac_type = 0);
BLEdevice* getDeviceByMac(const char* mac) { BLEdevice* getDeviceByMac(const char* mac) {
Log.trace(F("getDeviceByMac %s" CR), mac); Log.trace(F("getDeviceByMac %s" CR), mac);
@@ -231,7 +231,7 @@ bool updateWorB(JsonObject& BTdata, bool isWhite) {
return true; return true;
} }
void createOrUpdateDevice(const char* mac, uint8_t flags, int model) { void createOrUpdateDevice(const char* mac, uint8_t flags, int model, int mac_type) {
# ifdef ESP32 # ifdef ESP32
if (xSemaphoreTake(semaphoreCreateOrUpdateDevice, pdMS_TO_TICKS(30000)) == pdFALSE) { if (xSemaphoreTake(semaphoreCreateOrUpdateDevice, pdMS_TO_TICKS(30000)) == pdFALSE) {
Log.error(F("Semaphore NOT taken" CR)); Log.error(F("Semaphore NOT taken" CR));
@@ -249,21 +249,26 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, int model) {
device->isWhtL = flags & device_flags_isWhiteL; device->isWhtL = flags & device_flags_isWhiteL;
device->isBlkL = flags & device_flags_isBlackL; device->isBlkL = flags & device_flags_isBlackL;
device->connect = flags & device_flags_connect; device->connect = flags & device_flags_connect;
device->macType = mac_type;
device->sensorModel_id = model; device->sensorModel_id = model;
devices.push_back(device); devices.push_back(device);
newDevices++; newDevices++;
} else { } else {
Log.trace(F("update %s" CR), mac); Log.trace(F("update %s" CR), mac);
device->macType = mac_type;
if (flags & device_flags_isDisc) { if (flags & device_flags_isDisc) {
device->isDisc = true; device->isDisc = true;
} }
if (flags & device_flags_connect) { if (flags & device_flags_connect) {
device->connect = true; device->connect = true;
} }
if (model != TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL) if (model != TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL) {
device->sensorModel_id = model; device->sensorModel_id = model;
}
if (flags & device_flags_isWhiteL || flags & device_flags_isBlackL) { if (flags & device_flags_isWhiteL || flags & device_flags_isBlackL) {
device->isWhtL = flags & device_flags_isWhiteL; device->isWhtL = flags & device_flags_isWhiteL;
@@ -287,6 +292,7 @@ void dumpDevices() {
for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) { for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) {
BLEdevice* p = *it; BLEdevice* p = *it;
Log.trace(F("macAdr %s" CR), p->macAdr); Log.trace(F("macAdr %s" CR), p->macAdr);
Log.trace(F("macType %d" CR), p->macType);
Log.trace(F("isDisc %d" CR), p->isDisc); Log.trace(F("isDisc %d" CR), p->isDisc);
Log.trace(F("isWhtL %d" CR), p->isWhtL); Log.trace(F("isWhtL %d" CR), p->isWhtL);
Log.trace(F("isBlkL %d" CR), p->isBlkL); Log.trace(F("isBlkL %d" CR), p->isBlkL);
@@ -390,6 +396,7 @@ void procBLETask(void* pvParameters) {
String mac_adress = advertisedDevice->getAddress().toString().c_str(); String mac_adress = advertisedDevice->getAddress().toString().c_str();
mac_adress.toUpperCase(); mac_adress.toUpperCase();
BLEdata["id"] = (char*)mac_adress.c_str(); BLEdata["id"] = (char*)mac_adress.c_str();
BLEdata["mac_type"] = advertisedDevice->getAddress().getType();
Log.notice(F("Device detected: %s" CR), (char*)mac_adress.c_str()); Log.notice(F("Device detected: %s" CR), (char*)mac_adress.c_str());
BLEdevice* device = getDeviceByMac(BLEdata["id"].as<const char*>()); BLEdevice* device = getDeviceByMac(BLEdata["id"].as<const char*>());
@@ -473,7 +480,7 @@ void BLEconnect() {
BLEdevice* p = *it; BLEdevice* p = *it;
if (p->connect) { if (p->connect) {
Log.trace(F("Model to connect found: %s" CR), p->macAdr); Log.trace(F("Model to connect found: %s" CR), p->macAdr);
NimBLEAddress addr(std::string(p->macAdr)); NimBLEAddress addr((const char*)p->macAdr, p->macType);
if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC || if (p->sensorModel_id == BLEconectable::id::LYWSD03MMC ||
p->sensorModel_id == BLEconectable::id::MHO_C401) { p->sensorModel_id == BLEconectable::id::MHO_C401) {
LYWSD03MMC_connect BLEclient(addr); LYWSD03MMC_connect BLEclient(addr);
@@ -908,12 +915,13 @@ void PublishDeviceData(JsonObject& BLEdata, bool processBLEData) {
void process_bledata(JsonObject& BLEdata) { void process_bledata(JsonObject& BLEdata) {
const char* mac = BLEdata["id"].as<const char*>(); const char* mac = BLEdata["id"].as<const char*>();
int model_id = decoder.decodeBLEJson(BLEdata); int model_id = decoder.decodeBLEJson(BLEdata);
int mac_type = BLEdata["mac_type"].as<int>();
if (model_id >= 0) { // Broadcaster devices if (model_id >= 0) { // Broadcaster devices
Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>()); Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>());
if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) { if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC) {
createOrUpdateDevice(mac, device_flags_connect, model_id); // Device that broadcast and can be connected createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type); // Device that broadcast and can be connected
} else { } else {
createOrUpdateDevice(mac, device_flags_init, model_id); createOrUpdateDevice(mac, device_flags_init, model_id, mac_type);
} }
} else if (BLEdata.containsKey("name")) { // Connectable devices } else if (BLEdata.containsKey("name")) { // Connectable devices
std::string name = BLEdata["name"]; std::string name = BLEdata["name"];
@@ -926,7 +934,7 @@ void process_bledata(JsonObject& BLEdata) {
if (model_id > 0) { if (model_id > 0) {
Log.trace(F("Connectable device found: %s" CR), name.c_str()); Log.trace(F("Connectable device found: %s" CR), name.c_str());
createOrUpdateDevice(mac, device_flags_connect, model_id); createOrUpdateDevice(mac, device_flags_connect, model_id, mac_type);
} }
} else { } else {
Log.trace(F("No device found " CR)); Log.trace(F("No device found " CR));
@@ -968,6 +976,7 @@ void MQTTtoBTAction(JsonObject& BTdata) {
# ifdef ESP32 # ifdef ESP32
BLEAction action; BLEAction action;
action.ttl = BTdata.containsKey("ttl") ? (uint8_t)BTdata["ttl"] : 1; action.ttl = BTdata.containsKey("ttl") ? (uint8_t)BTdata["ttl"] : 1;
action.addr_type = BTdata.containsKey("mac_type") ? BTdata["mac_type"].as<int>() : 0;
action.value_type = BLE_VAL_STRING; action.value_type = BLE_VAL_STRING;
if (BTdata.containsKey("value_type")) { if (BTdata.containsKey("value_type")) {
String vt = BTdata["value_type"]; String vt = BTdata["value_type"];
@@ -1009,7 +1018,8 @@ void MQTTtoBTAction(JsonObject& BTdata) {
} }
createOrUpdateDevice(action.addr, device_flags_connect, createOrUpdateDevice(action.addr, device_flags_connect,
TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL); TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL,
action.addr_type);
if (BTdata.containsKey("immediate") && BTdata["immediate"].as<bool>()) { if (BTdata.containsKey("immediate") && BTdata["immediate"].as<bool>()) {
// Immediate action; we need to prevent the normal connection action and stop scanning // Immediate action; we need to prevent the normal connection action and stop scanning
+2
View File
@@ -153,6 +153,7 @@ enum ble_val_type {
struct BLEAction { struct BLEAction {
std::string value; std::string value;
char addr[18]; char addr[18];
int addr_type;
NimBLEUUID service; NimBLEUUID service;
NimBLEUUID characteristic; NimBLEUUID characteristic;
bool write; bool write;
@@ -164,6 +165,7 @@ struct BLEAction {
struct BLEdevice { struct BLEdevice {
char macAdr[18]; char macAdr[18];
int macType;
bool isDisc; bool isDisc;
bool isWhtL; bool isWhtL;
bool isBlkL; bool isBlkL;