commit
6279589cda
@ -10,6 +10,7 @@
|
||||
#include "display.h"
|
||||
#include "sds011read.h"
|
||||
#include "sdcard.h"
|
||||
#include "macsniff.h"
|
||||
|
||||
extern Ticker cyclicTimer;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _HASH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <inttypes.h>
|
||||
#include <RokkitHash.h>
|
||||
|
||||
uint32_t IRAM_ATTR hash(const char *data, int len);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "corona.h"
|
||||
#endif
|
||||
|
||||
uint16_t get_salt(void);
|
||||
uint32_t renew_salt(void);
|
||||
uint64_t macConvert(uint8_t *paddr);
|
||||
esp_err_t macQueueInit(void);
|
||||
void mac_process(void *pvParameters);
|
||||
|
@ -6,16 +6,6 @@
|
||||
#include <MQTT.h>
|
||||
#include <ETH.h>
|
||||
|
||||
#define MQTT_ETHERNET 0 // select PHY: set 0 for Wifi, 1 for ethernet
|
||||
#define MQTT_INTOPIC "paxin"
|
||||
#define MQTT_OUTTOPIC "paxout"
|
||||
#define MQTT_PORT 1883
|
||||
#define MQTT_SERVER "paxcounter.cloud.shiftr.io"
|
||||
#define MQTT_USER "public"
|
||||
#define MQTT_PASSWD "public"
|
||||
#define MQTT_RETRYSEC 20 // retry reconnect every 20 seconds
|
||||
#define MQTT_KEEPALIVE 10 // keep alive interval in seconds
|
||||
|
||||
#ifndef MQTT_CLIENTNAME
|
||||
#define MQTT_CLIENTNAME clientId
|
||||
#endif
|
||||
|
@ -79,6 +79,7 @@ lib_deps_sensors =
|
||||
boschsensortec/BSEC Software Library @ 1.6.1480
|
||||
https://github.com/ricki-z/SDS011.git
|
||||
lib_deps_basic =
|
||||
https://github.com/SukkoPera/Arduino-Rokkit-Hash.git
|
||||
bblanchon/ArduinoJson @ ^6
|
||||
jchristensen/Timezone @ ^1.2.4
|
||||
makuna/RTC @ ^2.3.5
|
||||
|
@ -46,10 +46,10 @@ Adafruit_BMP085 bmp; // I2C
|
||||
void setBMEIRQ() { xTaskNotify(irqHandlerTask, BME_IRQ, eSetBits); }
|
||||
|
||||
// initialize MEMS sensor
|
||||
// return = 0 -> error / return = 1 -> success
|
||||
int bme_init(void) {
|
||||
|
||||
// return = 0 -> error / return = 1 -> success
|
||||
int rc = 1;
|
||||
int rc = 0;
|
||||
|
||||
#ifdef HAS_BME680
|
||||
// block i2c bus access
|
||||
@ -63,76 +63,33 @@ int bme_init(void) {
|
||||
iaqSensor.version.minor_bugfix);
|
||||
|
||||
iaqSensor.setConfig(bsec_config_iaq);
|
||||
|
||||
if (checkIaqSensorStatus())
|
||||
ESP_LOGI(TAG, "BME680 sensor found and initialized");
|
||||
else {
|
||||
ESP_LOGE(TAG, "BME680 sensor not found");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
loadState();
|
||||
|
||||
iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET);
|
||||
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
||||
|
||||
if (checkIaqSensorStatus())
|
||||
ESP_LOGI(TAG, "BSEC subscription succesful");
|
||||
else {
|
||||
ESP_LOGE(TAG, "BSEC subscription error");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
rc = checkIaqSensorStatus();
|
||||
|
||||
} else
|
||||
ESP_LOGE(TAG, "I2c bus busy - BME680 initialization error");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#elif defined HAS_BME280
|
||||
|
||||
bool status;
|
||||
|
||||
// block i2c bus access
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
|
||||
status = bme.begin(BME280_ADDR);
|
||||
if (!status) {
|
||||
ESP_LOGE(TAG, "BME280 sensor not found");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
ESP_LOGI(TAG, "BME280 sensor found and initialized");
|
||||
} else {
|
||||
rc = bme.begin(BME280_ADDR);
|
||||
} else
|
||||
ESP_LOGE(TAG, "I2c bus busy - BME280 initialization error");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#elif defined HAS_BMP180
|
||||
bool status;
|
||||
// block i2c bus access
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
// Wire.begin(21, 22);
|
||||
status = bmp.begin();
|
||||
if (!status) {
|
||||
ESP_LOGE(TAG, "BMP180 sensor not found");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
ESP_LOGI(TAG, "BMP180 sensor found and initialized");
|
||||
} else {
|
||||
rc = bmp.begin();
|
||||
} else
|
||||
ESP_LOGE(TAG, "I2c bus busy - BMP180 initialization error");
|
||||
rc = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
finish:
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
if (rc)
|
||||
bmecycler.attach(BMECYCLE, setBMEIRQ);
|
||||
bmecycler.attach(BMECYCLE, setBMEIRQ); // start cyclic data transmit
|
||||
return rc;
|
||||
|
||||
} // bme_init()
|
||||
|
@ -97,7 +97,6 @@ void doHousekeeping() {
|
||||
"free heap = %d bytes)",
|
||||
ESP.getMinFreeHeap(), ESP.getFreeHeap());
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
|
||||
if (ESP.getMinFreeHeap() <= MEM_LOW) // check again
|
||||
do_reset(true); // memory leak, reset device
|
||||
@ -108,7 +107,6 @@ void doHousekeeping() {
|
||||
if (ESP.getMinFreePsram() <= MEM_LOW) {
|
||||
ESP_LOGI(TAG, "PSRAM full, counter cleared");
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
|
||||
if (ESP.getMinFreePsram() <= MEM_LOW) // check again
|
||||
do_reset(true); // memory leak, reset device
|
||||
@ -140,6 +138,7 @@ void reset_counters() {
|
||||
macs.clear(); // clear all macs container
|
||||
macs_wifi = 0;
|
||||
macs_ble = 0;
|
||||
renew_salt(); // get new salt
|
||||
#ifdef HAS_DISPLAY
|
||||
dp_plotCurve(0, true);
|
||||
#endif
|
||||
|
52
src/hash.cpp
52
src/hash.cpp
@ -36,55 +36,9 @@
|
||||
|
||||
#include "hash.h"
|
||||
|
||||
uint32_t IRAM_ATTR rokkit(const char *data, int len) {
|
||||
uint32_t hash, tmp;
|
||||
int rem;
|
||||
|
||||
if (len <= 0 || data == 0)
|
||||
return 0;
|
||||
hash = len;
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
while (len > 0) {
|
||||
hash += *((uint16_t *)data);
|
||||
tmp = (*((uint16_t *)(data + 2)) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2 * 2;
|
||||
hash += hash >> 11;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3:
|
||||
hash += *((uint16_t *)data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= ((signed char)data[2]) << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2:
|
||||
hash += *((uint16_t *)data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1:
|
||||
hash += (signed char)*data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
#ifdef ROKKIT_ENABLE_8BIT_OPTIMIZATIONS
|
||||
#undef ROKKIT_ENABLE_8BIT_OPTIMIZATIONS
|
||||
#endif
|
||||
|
||||
uint32_t IRAM_ATTR hash(const char *data, int len) {
|
||||
return rokkit(data, len);
|
||||
|
@ -284,14 +284,10 @@ esp_err_t lmic_init(void) {
|
||||
// Pass OTA parameters to LMIC_setSession
|
||||
#else
|
||||
// load saved session from RTC, if we have one
|
||||
if (RTC_runmode == RUNMODE_WAKEUP) {
|
||||
if (RTC_runmode == RUNMODE_WAKEUP)
|
||||
LoadLMICFromRTC();
|
||||
}
|
||||
// otherwise start join procedure if not already joined
|
||||
else {
|
||||
if (!LMIC_startJoining())
|
||||
ESP_LOGI(TAG, "Already joined");
|
||||
}
|
||||
if (!LMIC_startJoining())
|
||||
ESP_LOGI(TAG, "Already joined");
|
||||
#endif
|
||||
|
||||
// start lmic loop task
|
||||
|
@ -9,10 +9,11 @@ static const char TAG[] = __FILE__;
|
||||
QueueHandle_t MacQueue;
|
||||
TaskHandle_t macProcessTask;
|
||||
|
||||
uint16_t salt = 0;
|
||||
static uint32_t salt = renew_salt();
|
||||
|
||||
uint16_t get_salt(void) {
|
||||
salt = (uint16_t)random(65536); // get new 16bit random for salting hashes
|
||||
uint32_t renew_salt(void) {
|
||||
salt = esp_random();
|
||||
ESP_LOGV(TAG, "new salt = %04X", salt);
|
||||
return salt;
|
||||
}
|
||||
|
||||
@ -101,9 +102,6 @@ void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) {
|
||||
|
||||
uint16_t mac_analyze(MacBuffer_t MacBuffer) {
|
||||
|
||||
if (salt == 0) // ensure we have salt (appears after radio is turned on)
|
||||
return 0;
|
||||
|
||||
if ((cfg.rssilimit) &&
|
||||
(MacBuffer.rssi < cfg.rssilimit)) { // rssi is negative value
|
||||
ESP_LOGI(TAG, "%s RSSI %d -> ignoring (limit: %d)",
|
||||
@ -126,8 +124,7 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) {
|
||||
}
|
||||
};
|
||||
|
||||
char buff[10]; // temporary buffer for printf
|
||||
uint32_t *mac; // temporary buffer for shortened MAC
|
||||
uint32_t *mac; // pointer to shortened 4 byte MAC
|
||||
|
||||
// only last 3 MAC Address bytes are used for MAC address anonymization
|
||||
// but since it's uint32 we take 4 bytes to avoid 1st value to be 0.
|
||||
@ -138,11 +135,15 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) {
|
||||
// and increment counter on display
|
||||
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
|
||||
|
||||
snprintf(buff, sizeof(buff), "%08X",
|
||||
*mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC
|
||||
// to 8 digit hex string
|
||||
uint16_t hashedmac = hash(&buff[3], 5); // hash MAC 8 digit -> 5 digit
|
||||
auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique
|
||||
// reversed 4 byte MAC added to current salt
|
||||
const uint32_t saltedmac = *mac + salt;
|
||||
|
||||
// hashed 4 byte MAC
|
||||
// to save RAM, we use only lower 2 bytes of hash, since collisions don't
|
||||
// matter in our use case
|
||||
const uint16_t hashedmac = hash((const char *)&saltedmac, 4);
|
||||
|
||||
auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique
|
||||
bool added =
|
||||
newmac.second ? true : false; // true if hashed MAC is unique in container
|
||||
|
||||
@ -183,7 +184,8 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) {
|
||||
|
||||
// Log scan result
|
||||
ESP_LOGV(TAG,
|
||||
"%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d "
|
||||
"%s %s RSSI %ddBi -> MAC %0x:%0x:%0x:%0x:%0x:%0x -> salted %04X"
|
||||
" -> hashed %04X -> WiFi:%d "
|
||||
"BLTH:%d "
|
||||
#if (COUNT_ENS)
|
||||
"(CWA:%d)"
|
||||
@ -191,7 +193,9 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) {
|
||||
"-> %d Bytes left",
|
||||
added ? "new " : "known",
|
||||
MacBuffer.sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH",
|
||||
MacBuffer.rssi, buff, hashedmac, macs_wifi, macs_ble,
|
||||
MacBuffer.rssi, MacBuffer.mac[0], MacBuffer.mac[1], MacBuffer.mac[2],
|
||||
MacBuffer.mac[3], MacBuffer.mac[4], MacBuffer.mac[5], saltedmac,
|
||||
hashedmac, macs_wifi, macs_ble,
|
||||
#if (COUNT_ENS)
|
||||
cwa_report(),
|
||||
#endif
|
||||
|
@ -428,7 +428,7 @@ void setup() {
|
||||
// initialize salt value using esp_random() called by random() in
|
||||
// arduino-esp32 core. Note: do this *after* wifi has started, since
|
||||
// function gets it's seed from RF noise
|
||||
get_salt(); // get new 16bit for salting hashes
|
||||
reset_counters();
|
||||
|
||||
// start state machine
|
||||
ESP_LOGI(TAG, "Starting Interrupt Handler...");
|
||||
@ -451,8 +451,10 @@ void setup() {
|
||||
#endif
|
||||
if (bme_init())
|
||||
ESP_LOGI(TAG, "BME sensor initialized");
|
||||
else
|
||||
else {
|
||||
ESP_LOGE(TAG, "BME sensor could not be initialized");
|
||||
cfg.payloadmask &= ~MEMS_DATA; // switch off transmit of BME data
|
||||
}
|
||||
#endif
|
||||
|
||||
// starting timers and interrupts
|
||||
|
@ -41,9 +41,13 @@ esp_err_t mqtt_init(void) {
|
||||
|
||||
int mqtt_connect(const char *my_host, const uint16_t my_port) {
|
||||
IPAddress mqtt_server_ip;
|
||||
const uint16_t hashed = hash(Ð.macAddress()[0], 4); // hash MAC to 4 digits
|
||||
char clientId[16];
|
||||
snprintf(clientId, 16, "paxcounter_%d", hashed);
|
||||
uint8_t mac[6];
|
||||
char clientId[20];
|
||||
|
||||
// hash 6 byte MAC to 4 byte hash
|
||||
esp_eth_get_mac(mac);
|
||||
const uint32_t hashedmac = hash((const char *)mac, 6);
|
||||
snprintf(clientId, 20, "paxcounter_%08x", hashedmac);
|
||||
|
||||
ESP_LOGI(TAG, "MQTT name is %s", MQTT_CLIENTNAME);
|
||||
|
||||
|
@ -121,3 +121,15 @@
|
||||
#define CAYENNE_DEVICECONFIG 11 // device period configuration
|
||||
#define CAYENNE_SENSORREAD 13 // sensor period configuration
|
||||
#define CAYENNE_SENSORENABLE 14 // sensor enable configuration
|
||||
|
||||
// MQTT settings, only needed if MQTT is used (#define HAS_MQTT in board hal file)
|
||||
#define MQTT_ETHERNET 0 // select PHY: set 0 for Wifi, 1 for ethernet
|
||||
#define MQTT_INTOPIC "paxin"
|
||||
#define MQTT_OUTTOPIC "paxout"
|
||||
#define MQTT_PORT 1883
|
||||
#define MQTT_SERVER "public.cloud.shiftr.io"
|
||||
#define MQTT_USER "public"
|
||||
#define MQTT_PASSWD "public"
|
||||
#define MQTT_RETRYSEC 20 // retry reconnect every 20 seconds
|
||||
#define MQTT_KEEPALIVE 10 // keep alive interval in seconds
|
||||
//#define MQTT_CLIENTNAME "my_paxcounter" // generated by default
|
||||
|
@ -18,7 +18,6 @@ void set_reset(uint8_t val[]) {
|
||||
case 1: // reset MAC counter
|
||||
ESP_LOGI(TAG, "Remote command: reset MAC counter");
|
||||
reset_counters(); // clear macs
|
||||
get_salt(); // get new salt
|
||||
break;
|
||||
case 2: // reset device to factory settings
|
||||
ESP_LOGI(TAG, "Remote command: reset device to factory settings");
|
||||
@ -119,7 +118,6 @@ void set_countmode(uint8_t val[]) {
|
||||
return;
|
||||
}
|
||||
reset_counters(); // clear macs
|
||||
get_salt(); // get new salt
|
||||
}
|
||||
|
||||
void set_screensaver(uint8_t val[]) {
|
||||
|
@ -84,24 +84,15 @@ void do_after_reset(void) {
|
||||
void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
||||
gpio_num_t wakeup_gpio = GPIO_NUM_MAX) {
|
||||
|
||||
// don't go to sleep while unjoined
|
||||
#if (HAS_LORA)
|
||||
if (!LMIC.devaddr) {
|
||||
ESP_LOGI(TAG, "Can't go to sleep while joining");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ESP_LOGI(TAG, "Preparing to sleep...");
|
||||
|
||||
RTC_runmode = RUNMODE_SLEEP;
|
||||
int i;
|
||||
|
||||
// validate wake up pin, if we have
|
||||
if (!GPIO_IS_VALID_GPIO(wakeup_gpio))
|
||||
wakeup_gpio = GPIO_NUM_MAX;
|
||||
|
||||
ESP_LOGI(TAG, "Preparing to sleep...");
|
||||
|
||||
RTC_runmode = RUNMODE_SLEEP;
|
||||
|
||||
// stop further enqueuing of senddata and MAC processing
|
||||
sendTimer.detach();
|
||||
|
||||
@ -125,27 +116,22 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
||||
|
||||
// wait a while (max 100 sec) to clear send queues
|
||||
ESP_LOGI(TAG, "Waiting until send queues are empty...");
|
||||
for (i = 10; i > 0; i--) {
|
||||
if (!allQueuesEmtpy())
|
||||
vTaskDelay(pdMS_TO_TICKS(10000));
|
||||
else
|
||||
for (i = 100; i > 0; i--) {
|
||||
if (allQueuesEmtpy())
|
||||
break;
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
if (i == 0)
|
||||
goto Error;
|
||||
|
||||
// shutdown LMIC safely, waiting max 100 sec
|
||||
// shutdown LMIC safely, waiting max 100 sec
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGI(TAG, "Waiting until LMIC is idle...");
|
||||
for (i = 10; i > 0; i--) {
|
||||
for (i = 100; i > 0; i--) {
|
||||
if ((LMIC.opmode & OP_TXRXPEND) ||
|
||||
os_queryTimeCriticalJobs(sec2osticks(wakeup_sec)))
|
||||
vTaskDelay(pdMS_TO_TICKS(10000));
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
goto Error;
|
||||
#endif // (HAS_LORA)
|
||||
|
||||
// shutdown MQTT safely
|
||||
@ -165,10 +151,8 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
goto Error;
|
||||
|
||||
// save LMIC state to RTC RAM
|
||||
// save LMIC state to RTC RAM
|
||||
#if (HAS_LORA)
|
||||
SaveLMICToRTC(wakeup_sec);
|
||||
#endif // (HAS_LORA)
|
||||
@ -207,10 +191,6 @@ void enter_deepsleep(const uint64_t wakeup_sec = 60,
|
||||
RTC_millis += millis();
|
||||
ESP_LOGI(TAG, "Going to sleep, good bye.");
|
||||
esp_deep_sleep_start();
|
||||
|
||||
Error:
|
||||
ESP_LOGE(TAG, "Can't go to sleep. Resetting.");
|
||||
do_reset(true);
|
||||
}
|
||||
|
||||
unsigned long long uptime() { return (RTC_millis + millis()); }
|
@ -115,7 +115,6 @@ void sendData() {
|
||||
// clear counter if not in cumulative counter mode
|
||||
if (cfg.countermode != 1) {
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
ESP_LOGI(TAG, "Counter cleared");
|
||||
}
|
||||
#ifdef HAS_DISPLAY
|
||||
|
Loading…
Reference in New Issue
Block a user