Skip to content

Commit

Permalink
Add "mac_type" parameter to BLE connection commands. (#1146)
Browse files Browse the repository at this point in the history
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..
  • Loading branch information
h2zero authored Jan 25, 2022
1 parent e838d3c commit f8b4b3c
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
3 changes: 3 additions & 0 deletions docs/use/ble.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ The gateway can read and write BLE characteristics from devices and provide the
::: 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)
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
Expand Down
26 changes: 18 additions & 8 deletions main/ZgatewayBT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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

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) {
Log.trace(F("getDeviceByMac %s" CR), mac);
Expand Down Expand Up @@ -231,7 +231,7 @@ bool updateWorB(JsonObject& BTdata, bool isWhite) {
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
if (xSemaphoreTake(semaphoreCreateOrUpdateDevice, pdMS_TO_TICKS(30000)) == pdFALSE) {
Log.error(F("Semaphore NOT taken" CR));
Expand All @@ -249,21 +249,26 @@ void createOrUpdateDevice(const char* mac, uint8_t flags, int model) {
device->isWhtL = flags & device_flags_isWhiteL;
device->isBlkL = flags & device_flags_isBlackL;
device->connect = flags & device_flags_connect;
device->macType = mac_type;
device->sensorModel_id = model;
devices.push_back(device);
newDevices++;
} else {
Log.trace(F("update %s" CR), mac);

device->macType = mac_type;

if (flags & device_flags_isDisc) {
device->isDisc = true;
}

if (flags & device_flags_connect) {
device->connect = true;
}

if (model != TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL)
if (model != TheengsDecoder::BLE_ID_NUM::UNKNOWN_MODEL) {
device->sensorModel_id = model;
}

if (flags & device_flags_isWhiteL || flags & device_flags_isBlackL) {
device->isWhtL = flags & device_flags_isWhiteL;
Expand All @@ -287,6 +292,7 @@ void dumpDevices() {
for (vector<BLEdevice*>::iterator it = devices.begin(); it != devices.end(); ++it) {
BLEdevice* p = *it;
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("isWhtL %d" CR), p->isWhtL);
Log.trace(F("isBlkL %d" CR), p->isBlkL);
Expand Down Expand Up @@ -390,6 +396,7 @@ void procBLETask(void* pvParameters) {
String mac_adress = advertisedDevice->getAddress().toString().c_str();
mac_adress.toUpperCase();
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());
BLEdevice* device = getDeviceByMac(BLEdata["id"].as<const char*>());

Expand Down Expand Up @@ -473,7 +480,7 @@ void BLEconnect() {
BLEdevice* p = *it;
if (p->connect) {
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 ||
p->sensorModel_id == BLEconectable::id::MHO_C401) {
LYWSD03MMC_connect BLEclient(addr);
Expand Down Expand Up @@ -908,12 +915,13 @@ void PublishDeviceData(JsonObject& BLEdata, bool processBLEData) {
void process_bledata(JsonObject& BLEdata) {
const char* mac = BLEdata["id"].as<const char*>();
int model_id = decoder.decodeBLEJson(BLEdata);
int mac_type = BLEdata["mac_type"].as<int>();
if (model_id >= 0) { // Broadcaster devices
Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as<const char*>());
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 {
createOrUpdateDevice(mac, device_flags_init, model_id);
createOrUpdateDevice(mac, device_flags_init, model_id, mac_type);
}
} else if (BLEdata.containsKey("name")) { // Connectable devices
std::string name = BLEdata["name"];
Expand All @@ -926,7 +934,7 @@ void process_bledata(JsonObject& BLEdata) {

if (model_id > 0) {
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 {
Log.trace(F("No device found " CR));
Expand Down Expand Up @@ -968,6 +976,7 @@ void MQTTtoBTAction(JsonObject& BTdata) {
# ifdef ESP32
BLEAction action;
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;
if (BTdata.containsKey("value_type")) {
String vt = BTdata["value_type"];
Expand Down Expand Up @@ -1009,7 +1018,8 @@ void MQTTtoBTAction(JsonObject& BTdata) {
}

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>()) {
// Immediate action; we need to prevent the normal connection action and stop scanning
Expand Down
2 changes: 2 additions & 0 deletions main/config_BT.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ enum ble_val_type {
struct BLEAction {
std::string value;
char addr[18];
int addr_type;
NimBLEUUID service;
NimBLEUUID characteristic;
bool write;
Expand All @@ -164,6 +165,7 @@ struct BLEAction {

struct BLEdevice {
char macAdr[18];
int macType;
bool isDisc;
bool isWhtL;
bool isBlkL;
Expand Down

0 comments on commit f8b4b3c

Please sign in to comment.