This commit is contained in:
DTTerastar 2021-09-15 12:11:32 -04:00
parent 5e1f327020
commit a4fe08d8ee
11 changed files with 102 additions and 83 deletions

View File

@ -1,11 +1,6 @@
#include "BleFingerprint.h"
#include "util.h"
BleFingerprint::~BleFingerprint()
{
Serial.printf("%d Del | MAC: %s, ID: %s\n", xPortGetCoreID(), SMacf(address).c_str(), id.c_str());
}
BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff) : oneEuro{one_euro_filter<double, unsigned long>(1, fcmin, beta, dcutoff)}
{
if (advertisedDevice->getAddressType() == BLE_ADDR_PUBLIC)
@ -15,53 +10,49 @@ BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmi
address = advertisedDevice->getAddress();
newest = recent = oldest = rssi = advertisedDevice->getRSSI();
String mac_address = SMacf(address);
calRssi = advertisedDevice->haveTXPower() ? (-advertisedDevice->getTXPower()) - 41 : 0;
Serial.printf("%d New | MAC: %s", xPortGetCoreID(), mac_address.c_str());
fingerprint(advertisedDevice);
if (calRssi > 0) calRssi = defaultTxPower;
}
void BleFingerprint::fingerprint(BLEAdvertisedDevice *advertisedDevice)
{
if (advertisedDevice->haveName())
name = String(advertisedDevice->getName().c_str());
calRssi = advertisedDevice->haveTXPower() ? (-advertisedDevice->getTXPower()) - 41 : 0;
std::string strServiceData = advertisedDevice->getServiceData();
uint8_t cServiceData[100];
strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);
if (advertisedDevice->haveServiceUUID())
{
if (advertisedDevice->getServiceDataUUID().equals(BLEUUID(tileUUID)) == true)
{
id = "tile:" + mac_address;
Serial.printf(", ID: %s", id.c_str());
pid = "tile:" + getMac();
}
else if (advertisedDevice->getServiceDataUUID().equals(BLEUUID(exposureUUID)) == true)
{ // found covid exposure tracker
id = "exp:" + String(strServiceData.length());
Serial.printf(", ID: %s", id.c_str());
//char *sdHex = NimBLEUtils::buildHexData(nullptr, (uint8_t *)strServiceData.data(), strServiceData.length());
//doc["tek"] = String(sdHex).substring(4, 20);
//free(sdHex);
std::string strServiceData = advertisedDevice->getServiceData(BLEUUID(exposureUUID));
pid = "exp:" + String(strServiceData.length());
}
else if (advertisedDevice->getServiceDataUUID().equals(BLEUUID(beaconUUID)) == true)
{ // found Eddystone UUID
Serial.print(", Eddystone");
if (cServiceData[0] == 0x10)
std::string strServiceData = advertisedDevice->getServiceData(BLEUUID(beaconUUID));
if (strServiceData[0] == EDDYSTONE_URL_FRAME_TYPE && strServiceData.length() <= 18)
{
BLEEddystoneURL oBeacon = BLEEddystoneURL();
oBeacon.setData(strServiceData);
// Serial.printf("Eddystone Frame Type (Eddystone-URL) ");
url = String(oBeacon.getDecodedURL().c_str());
Serial.print(" URL: ");
Serial.print(url.c_str());
calRssi = oBeacon.getPower();
}
else if (cServiceData[0] == 0x20)
else if (strServiceData[0] == EDDYSTONE_TLM_FRAME_TYPE)
{
BLEEddystoneTLM oBeacon = BLEEddystoneTLM();
oBeacon.setData(strServiceData);
Serial.printf(" TLM: ");
Serial.printf(oBeacon.toString().c_str());
temp = oBeacon.getTemp();
volts = oBeacon.getVolt();
#ifdef VERBOSE
Serial.println(oBeacon.toString().c_str());
#endif
}
}
else
@ -70,12 +61,11 @@ BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmi
for (int i = 0; i < advertisedDevice->getServiceUUIDCount(); i++)
{
std::string sid = advertisedDevice->getServiceUUID(i).toString();
Serial.printf(", sID: %s", sid.c_str());
fingerprint = fingerprint + String(sid.c_str());
}
id = fingerprint;
if (advertisedDevice->haveTXPower())
fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
sid = fingerprint;
}
}
else if (advertisedDevice->haveManufacturerData())
@ -83,8 +73,7 @@ BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmi
std::string strManufacturerData = advertisedDevice->getManufacturerData();
if (strManufacturerData.length() > 2)
{
char *mdHex = NimBLEUtils::buildHexData(nullptr, (uint8_t *)strManufacturerData.data(), strManufacturerData.length());
String manuf = String(mdHex).substring(2, 4) + String(mdHex).substring(0, 2);
String manuf = Sprintf("%02x%02x", strManufacturerData[1], strManufacturerData[0]);
if (manuf == "004c") // Apple
{
@ -98,52 +87,42 @@ BleFingerprint::BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmi
int major = ENDIAN_CHANGE_U16(oBeacon.getMajor());
int minor = ENDIAN_CHANGE_U16(oBeacon.getMinor());
id = "iBeacon:" + proximityUUID + "-" + major + "-" + minor;
Serial.printf(", ID: %s", id.c_str());
pid = "iBeacon:" + proximityUUID + "-" + major + "-" + minor;
calRssi = oBeacon.getSignalPower();
}
else
{
String fingerprint = "apple:" + String(mdHex).substring(4, 8) + ":" + String(strManufacturerData.length());
if (advertisedDevice->haveTXPower())
fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
id = fingerprint;
Serial.printf(", ID: %s", id.c_str());
pid = Sprintf("apple:%02x%02x:%d%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length(), -advertisedDevice->getTXPower());
else
pid = Sprintf("apple:%02x%02x:%d", strManufacturerData[2], strManufacturerData[3], strManufacturerData.length());
}
}
else if (manuf == "05a7") //Sonos
{
id = "sonos:" + mac_address;
Serial.printf(", ID: %s", id.c_str());
pid = "sonos:" + getMac();
}
else if (manuf == "0006" && strManufacturerData.length() == 29) //microsoft
{
id = "microsoft:" + String(mdHex).substring(12, 59);
Serial.printf(", ID: %s", id.c_str());
pid = Sprintf("microsoft:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
strManufacturerData[6], strManufacturerData[7], strManufacturerData[8], strManufacturerData[9], strManufacturerData[10], strManufacturerData[11],
strManufacturerData[12], strManufacturerData[13], strManufacturerData[14], strManufacturerData[15], strManufacturerData[16], strManufacturerData[17],
strManufacturerData[18], strManufacturerData[19], strManufacturerData[20], strManufacturerData[21], strManufacturerData[22], strManufacturerData[23],
strManufacturerData[24], strManufacturerData[25], strManufacturerData[26], strManufacturerData[27], strManufacturerData[28]);
}
else if (manuf == "0075") //samsung
{
id = "samsung:" + mac_address;
Serial.printf(", ID: %s", id.c_str());
pid = "samsung:" + getMac();
}
else
{
String fingerprint = "md:" + String(mdHex).substring(2, 4) + String(mdHex).substring(0, 2) + ":" + String(strManufacturerData.length());
String fingerprint = Sprintf("md:%s:%d", manuf.c_str(), strManufacturerData.length());
if (advertisedDevice->haveTXPower())
fingerprint = fingerprint + String(-advertisedDevice->getTXPower());
id = macPublic ? mac_address : fingerprint;
Serial.printf(", ID: %s, MD: %s", id.c_str(), mdHex);
sid = fingerprint;
}
free(mdHex);
}
}
if (calRssi > 0) calRssi = defaultTxPower;
if (id.isEmpty() && macPublic)
id = mac_address;
Serial.println();
}
bool BleFingerprint::filter()
@ -169,6 +148,7 @@ void BleFingerprint::seen(BLEAdvertisedDevice *advertisedDevice)
newest = advertisedDevice->getRSSI();
rssi = median_of_3(oldest, recent, newest);
fingerprint(advertisedDevice);
if (!calRssi) calRssi = defaultTxPower;
float ratio = (calRssi - rssi) / 35.0f;
@ -190,7 +170,7 @@ void BleFingerprint::setInitial(int initalRssi, float initalDistance)
bool BleFingerprint::report(JsonDocument *doc, int maxDistance)
{
if (id.isEmpty())
if (pid.isEmpty() && sid.isEmpty() && !macPublic)
return false;
if (!hasValue)
@ -216,17 +196,17 @@ bool BleFingerprint::report(JsonDocument *doc, int maxDistance)
{
if (!close)
{
Display.close(mac.c_str(), id.c_str());
//Display.close(mac.c_str(), id.c_str());
close = true;
}
}
else if (close && output.value.position > 1.5)
{
Display.left(mac.c_str(), id.c_str());
//Display.left(mac.c_str(), id.c_str());
close = false;
}
if (!id.isEmpty()) (*doc)[F("id")] = id;
(*doc)[F("id")] = getId();
if (!name.isEmpty()) (*doc)[F("name")] = name;
(*doc)[F("rssi@1m")] = calRssi;
@ -237,5 +217,8 @@ bool BleFingerprint::report(JsonDocument *doc, int maxDistance)
(*doc)[F("distance")] = round(output.value.position * 100.0f) / 100.0f;
(*doc)[F("speed")] = round(output.value.speed * 1e7f) / 10.0f;
if (volts) (*doc)[F("volts")] = volts;
if (temp) (*doc)[F("temp")] = temp;
return true;
}

View File

@ -2,7 +2,6 @@
#define _BLEFINGERPRINT_
#include <ArduinoJson.h>
#include <GUI.h>
#include <NimBLEAdvertisedDevice.h>
#include <NimBLEBeacon.h>
#include <NimBLEDevice.h>
@ -10,17 +9,37 @@
#include <NimBLEEddystoneURL.h>
#include <SoftFilters.h>
#define Sprintf(f, ...) ( \
{ \
char *s; \
asprintf(&s, f, __VA_ARGS__); \
String r = s; \
free(s); \
r; \
})
#define SMacf(f) ( \
{ \
auto nativeAddress = f.getNative(); \
Sprintf("%02x%02x%02x%02x%02x%02x", nativeAddress[5], nativeAddress[4], nativeAddress[3], nativeAddress[2], nativeAddress[1], nativeAddress[0]); \
})
class BleFingerprint
{
public:
BleFingerprint(BLEAdvertisedDevice *advertisedDevice, float fcmin, float beta, float dcutoff);
~BleFingerprint();
void seen(BLEAdvertisedDevice *advertisedDevice);
bool report(JsonDocument *doc, int maxDistance);
String getId() { return id; }
String getId()
{
if (!pid.isEmpty()) return pid;
if (macPublic) return getMac();
if (!sid.isEmpty()) return sid;
return getMac();
}
String getMac() { return SMacf(address); }
float getDistance() { return output.value.position; }
int getRSSI() { return rssi; }
@ -31,15 +50,18 @@ public:
long getLastSeen() { return lastSeenMicros; };
private:
void fingerprint(BLEAdvertisedDevice *advertisedDevice);
bool hasValue = false, close = false, reported = false, macPublic = false;
NimBLEAddress address;
String id, name, url;
String pid, sid, name, url;
int rssi = -100, calRssi = 0;
int newest = -100;
int recent = -100;
int oldest = -100;
float raw, lastReported = 0;
float raw, lastReported, temp = 0;
long firstSeenMicros, lastSeenMicros = 0, lastReportedMicros = 0;
uint16_t volts;
Reading<Differential<float>> output;

View File

@ -18,6 +18,7 @@ void BleFingerprintCollection::cleanupOldFingerprints()
}
if (oldest == nullptr) return;
Display.removed(oldest);
fingerprints.remove(oldest);
delete oldest;
}
@ -34,6 +35,7 @@ BleFingerprint *BleFingerprintCollection::getFingerprintInternal(BLEAdvertisedDe
}
auto created = new BleFingerprint(advertisedDevice, ONE_EURO_FCMIN, ONE_EURO_BETA, ONE_EURO_DCUTOFF);
Display.added(created);
auto it2 = std::find_if(fingerprints.begin(), fingerprints.end(), [created](BleFingerprint *f)
{ return f->getId() == created->getId(); });
if (it2 != fingerprints.end())

View File

@ -2,11 +2,8 @@
#define _BLEFINGERPRINTCOLLECTION_
#include "BleFingerprint.h"
#include "GUI.h"
#include <ArduinoJson.h>
#include <GUI.h>
#include <NimBLEAdvertisedDevice.h>
#include <NimBLEBeacon.h>
#include <NimBLEDevice.h>
#define ONE_EURO_FCMIN 0.01
#define ONE_EURO_BETA 0.005

View File

@ -17,16 +17,26 @@ void GUI::connected(bool wifi = false, bool mqtt = false)
status("Wifi: %s Mqtt: %s", (wifi ? "no" : "yes"), (wifi ? "no" : "yes"));
}
void GUI::close(const char *mac, const char *id)
void GUI::close(BleFingerprint *f)
{
Serial.printf("%d Close | MAC: %s, ID: %-50s\n", xPortGetCoreID(), mac, id);
status("C: %s", id);
Serial.printf("%d Close | MAC: %s, ID: %-50s\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str());
status("C: %s", f->getId());
}
void GUI::left(const char *mac, const char *id)
void GUI::added(BleFingerprint *f)
{
Serial.printf("%d Left | MAC: %s, ID: %-50s\n", xPortGetCoreID(), mac, id);
status("L: %s", id);
Serial.printf("%d New | MAC: %s, ID: %-50s\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str());
}
void GUI::removed(BleFingerprint *f)
{
Serial.printf("%d Del | MAC: %s, ID: %-50s\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str());
}
void GUI::left(BleFingerprint *f)
{
Serial.printf("%d Left | MAC: %s, ID: %-50s\n", xPortGetCoreID(), f->getMac().c_str(), f->getId().c_str());
status("L: %s", f->getId());
}
void GUI::status(const char *format, ...)

View File

@ -1,6 +1,7 @@
#ifndef GUI_h
#define GUI_h
#include "BleFingerprint.h"
#include <Arduino.h>
#ifdef M5STICK
@ -48,12 +49,16 @@
class GUI
{
public:
void added(BleFingerprint *f);
void removed(BleFingerprint *f);
void close(BleFingerprint *f);
void left(BleFingerprint *f);
void seenStart();
void seenEnd();
void updateProgress(unsigned int percent) { digitalWrite(LED_BUILTIN, percent % 2); }
void updateEnd() { digitalWrite(LED_BUILTIN, !LED_BUILTIN_ON); }
void close(const char *mac, const char *id);
void left(const char *mac, const char *id);
void status(const char *message, ...);
void connected(bool wifi, bool mqtt);
void update();

View File

@ -3,8 +3,6 @@
#include <NimBLEDevice.h>
#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))
#define Sprintf(f, ...) ({ char* s; asprintf(&s, f, __VA_ARGS__); String r = s; free(s); r; })
#define SMacf(f) ({ auto nativeAddress = f.getNative(); Sprintf("%02x%02x%02x%02x%02x%02x", nativeAddress[5], nativeAddress[4], nativeAddress[3], nativeAddress[2], nativeAddress[1], nativeAddress[0]); })
#ifdef TX_DEFAULT
static const int defaultTxPower = TX_DEFAULT;

View File

@ -52,8 +52,10 @@ board = esp32dev
lib_deps = ${common_env_data.lib_deps_external}
board_build.partitions = partitions_singleapp.csv
monitor_speed = 115200
upload_speed = 1500000
monitor_filters = esp32_exception_decoder
build_flags =
-D CORE_DEBUG_LEVEL=2
-D FIRMWARE='"esp32-verbose"'
-D VERBOSE
-Wall

View File

@ -1,7 +1,7 @@
#define Sprintf(f, ...) ({ char* s; asprintf(&s, f, __VA_ARGS__); String r = s; free(s); r; })
#define ESPMAC (Sprintf("%06" PRIx64, ESP.getEfuseMac() >> 24))
#if VERBOSE
#ifdef VERBOSE
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#endif

View File

@ -60,7 +60,7 @@ bool sendTelemetry(int totalSeen = -1, int totalReported = -1, int totalAdverts
}
teleFails++;
Serial.printf("Error after 10 tries sending telemetry (%d times since boot)\n", teleFails);
log_e("Error after 10 tries sending telemetry (%d times since boot)", teleFails);
return false;
}
@ -243,7 +243,7 @@ void setup()
Serial.begin(115200);
Serial.setDebugOutput(true);
#if VERBOSE
#ifdef VERBOSE
esp_log_level_set("*", ESP_LOG_DEBUG);
#endif
spiffsInit();

View File

@ -5,7 +5,6 @@
#include <AsyncTCP.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <NimBLEBeacon.h>
#include <NimBLEDevice.h>
#include <SPIFFS.h>
#include <WebServer.h>
@ -18,6 +17,7 @@
#include "BleFingerprint.h"
#include "BleFingerprintCollection.h"
#include "GUI.h"
#include "Settings.h"
AsyncMqttClient mqttClient;
@ -103,7 +103,7 @@ void setClock()
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
log_i(F("NTP synced, current time: %s"), asctime(&timeinfo));
log_i("NTP synced, current time: %s", asctime(&timeinfo));
}
void configureOTA()