From 95b749833c6d0f84f9c8b6220872b599b3075470 Mon Sep 17 00:00:00 2001 From: DigiH Date: Thu, 9 Mar 2023 16:35:16 +0100 Subject: [PATCH] [BT] Known Random MAC address filtering (#1514) * [BT] Random MAC address filtering Random MAC address filter with runtime boolean setting randommacs * APPLE_CONT added to discovery and data process --- docs/use/ble.md | 8 ++++++++ main/ZdisplaySSD1306.ino | 2 +- main/ZgatewayBT.ino | 13 ++++++++++++- main/config_BT.h | 5 +++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/use/ble.md b/docs/use/ble.md index d88e739..eb2ff84 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -134,6 +134,14 @@ With Home Assistant, this command is directly available through MQTT auto discov The gateway will publish only the detected sensors like Mi Flora, Mi jia, LYWSD03MMC... and not the other BLE devices. This is useful if you don't use the gateway for presence detection but only to retrieve sensors data. +## Setting if the gateway publishes known devices which randomly change their MAC address + +The default is false, as such changing MAC addresses cannot be related to specific devices. + +If you want to change this characteristic: + +`mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"randommacs":true}'` + ## Setting if the gateway use adaptive scanning Adaptive scanning lets the gateway decide for you the best passive `interval` and active `intervalacts` scan interval, depending on the characteristics of your devices. diff --git a/main/ZdisplaySSD1306.ino b/main/ZdisplaySSD1306.ino index bd96dfc..833fc2d 100644 --- a/main/ZdisplaySSD1306.ino +++ b/main/ZdisplaySSD1306.ino @@ -458,7 +458,7 @@ void ssd1306PubPrint(const char* topicori, JsonObject& data) { case hash("BTtoMQTT"): { // {"id":"AA:BB:CC:DD:EE:FF","mac_type":0,"adv_type":0,"name":"sps","manufacturerdata":"de071f1000b1612908","rssi":-70,"brand":"Inkbird","model":"T(H) Sensor","model_id":"IBS-TH1/TH2/P01B","type":"THBX","cidc":false,"acts":true,"tempc":20.14,"tempf":68.252,"hum":41.27,"batt":41} - if (data["model_id"] != "MS-CDP" && data["model_id"] != "GAEN" && data["model_id"] != "IBEACON") { + if (data["model_id"] != "MS-CDP" && data["model_id"] != "GAEN" && data["model_id"] != "APPLE_CONT" && data["model_id"] != "IBEACON") { // Line 2, 3, 4 String line2 = ""; String line3 = ""; diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index af51079..b57f6b1 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -86,6 +86,7 @@ void BTConfig_init() { BTConfig.intervalActiveScan = TimeBtwActive; BTConfig.intervalConnect = TimeBtwConnect; BTConfig.pubOnlySensors = PublishOnlySensors; + BTConfig.pubRandomMACs = PublishRandomMACs; BTConfig.presenceEnable = HassPresence; BTConfig.presenceTopic = subjectHomePresence; BTConfig.presenceUseBeaconUuid = useBeaconUuidForPresence; @@ -110,6 +111,7 @@ void stateBTMeasures(bool start) { jo["intervalacts"] = BTConfig.intervalActiveScan; jo["intervalcnct"] = BTConfig.intervalConnect; jo["onlysensors"] = BTConfig.pubOnlySensors; + jo["randommacs"] = BTConfig.pubRandomMACs; jo["hasspresence"] = BTConfig.presenceEnable; jo["presenceTopic"] = BTConfig.presenceTopic; jo["presenceUseBeaconUuid"] = BTConfig.presenceUseBeaconUuid; @@ -167,6 +169,8 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { Config_update(BTdata, "intervalcnct", BTConfig.intervalConnect); // publish all BLE devices discovered or only the identified sensors (like temperature sensors) Config_update(BTdata, "onlysensors", BTConfig.pubOnlySensors); + // publish devices which randomly change their MAC addresses + Config_update(BTdata, "randommacs", BTConfig.pubRandomMACs); // Home Assistant presence message Config_update(BTdata, "hasspresence", BTConfig.presenceEnable); // Home Assistant presence message topic @@ -208,6 +212,7 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) { jo["intervalacts"] = BTConfig.intervalActiveScan; jo["intervalcnct"] = BTConfig.intervalConnect; jo["onlysensors"] = BTConfig.pubOnlySensors; + jo["randommac"] = BTConfig.pubRandomMACs; jo["hasspresence"] = BTConfig.presenceEnable; jo["presenceTopic"] = BTConfig.presenceTopic; jo["presenceUseBeaconUuid"] = BTConfig.presenceUseBeaconUuid; @@ -839,6 +844,7 @@ void setupBT() { Log.notice(F("BLE scans interval: %d" CR), BTConfig.BLEinterval); Log.notice(F("BLE connects interval: %d" CR), BTConfig.intervalConnect); Log.notice(F("Publishing only BLE sensors: %T" CR), BTConfig.pubOnlySensors); + Log.notice(F("Publishing random MAC devices: %T" CR), BTConfig.pubRandomMACs); Log.notice(F("Adaptive BLE scan: %T" CR), BTConfig.adaptiveScan); Log.notice(F("Active BLE scan interval: %d" CR), BTConfig.intervalActiveScan); Log.notice(F("minrssi: %d" CR), -abs(BTConfig.minRssi)); @@ -909,10 +915,11 @@ void launchBTDiscovery(bool overrideDiscovery) { for (vector::iterator it = localDevices.begin(); it != localDevices.end(); ++it) { BLEdevice* p = *it; Log.trace(F("Device mac %s" CR), p->macAdr); - // Do not launch discovery for the devices already discovered (unless we have overrideDiscovery) or that are not unique by their MAC Address (Ibeacon, GAEN and Microsoft Cdp) + // Do not launch discovery for the devices already discovered (unless we have overrideDiscovery) or that are not unique by their MAC Address (iBeacon, GAEN and Microsoft CDP) if ((overrideDiscovery || !isDiscovered(p)) && p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::IBEACON && p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::MS_CDP && + p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::APPLE_CONT && p->sensorModel_id != TheengsDecoder::BLE_ID_NUM::GAEN) { String macWOdots = String(p->macAdr); macWOdots.replace(":", ""); @@ -1000,6 +1007,9 @@ void launchBTDiscovery(bool overrideDiscovery) { void PublishDeviceData(JsonObject& BLEdata, bool processBLEData) { if (abs((int)BLEdata["rssi"] | 0) < abs(BTConfig.minRssi)) { // process only the devices close enough if (processBLEData) process_bledata(BLEdata); + if (!BTConfig.pubRandomMACs && (BLEdata["type"].as()).compare("RMAC") == 0) { + return; + } if (BLEdata.containsKey("type") && (BLEdata.containsKey("model") || BLEdata.containsKey("distance"))) { // Only display sensor data with type pubOled(subjectBTtoMQTT, BLEdata); } @@ -1031,6 +1041,7 @@ void process_bledata(JsonObject& BLEdata) { int mac_type = BLEdata["mac_type"].as(); if (model_id >= 0 && model_id != TheengsDecoder::BLE_ID_NUM::IBEACON && model_id != TheengsDecoder::BLE_ID_NUM::MS_CDP && + model_id != TheengsDecoder::BLE_ID_NUM::APPLE_CONT && model_id != TheengsDecoder::BLE_ID_NUM::GAEN) { // Broadcaster devices Log.trace(F("Decoder found device: %s" CR), BLEdata["model_id"].as()); if (model_id == TheengsDecoder::BLE_ID_NUM::HHCCJCY01HHCC || model_id == TheengsDecoder::BLE_ID_NUM::BM2) { diff --git a/main/config_BT.h b/main/config_BT.h index 4fdeadb..04b01cc 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -98,6 +98,10 @@ extern int btQueueLengthCount; # define PublishOnlySensors false //false if we publish all BLE devices discovered or true only the identified sensors (like temperature sensors) #endif +#ifndef PublishRandomMACs +# define PublishRandomMACs false //false to not publish devices which randomly change their MAC addresses +#endif + #ifndef HassPresence # define HassPresence false //false if we publish into Home Assistant presence topic #endif @@ -141,6 +145,7 @@ struct BTConfig_s { unsigned long BLEinterval; // Time between 2 scans unsigned long intervalConnect; // Time between 2 connects bool pubOnlySensors; // Publish only the identified sensors (like temperature sensors) + bool pubRandomMACs; // Publish devices which randomly change their MAC address bool presenceEnable; // Publish into Home Assistant presence topic String presenceTopic; // Home Assistant presence topic to publish on bool presenceUseBeaconUuid; // Use iBeacon UUID as for presence, instead of sender MAC (random) address