parent
5e1f327020
commit
a4fe08d8ee
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ...)
|
|
@ -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();
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue