diff --git a/LICENSE b/LICENSE index aa52acab..9288a85b 100644 --- a/LICENSE +++ b/LICENSE @@ -20,9 +20,9 @@ Parts of the source files in this repository are made available under different listed below. Refer to each individual source file for more details. ------------------------------------------------------------------------------------------------ -wifisniffer.cpp +wifiscan.cpp -Parts of wifisniffer.cpp were derived or taken from +Prior art was used for wifiscan.cpp and taken from * Copyright (c) 2017, Ɓukasz Marcin Podkalicki * ESP32/016 WiFi Sniffer diff --git a/build.py b/build.py index ed222a04..7f2c3a28 100644 --- a/build.py +++ b/build.py @@ -90,5 +90,4 @@ def publish_bintray(source, target, env): # put build file name and upload command to platformio environment env.Replace( PROGNAME="firmware_" + package + "_v%s" % version, - UPLOADCMD=publish_bintray -) \ No newline at end of file + UPLOADCMD=publish_bintray) \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 518aaf2b..8e3d7397 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,7 +26,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.5.3 +release_version = 1.5.7 ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose debug_level = 0 diff --git a/src/button.cpp b/src/button.cpp index 3f75674a..1cca9f4e 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -6,10 +6,13 @@ // Local logging tag static const char TAG[] = "main"; -void IRAM_ATTR ButtonIRQ() { ButtonPressedIRQ++; } +void IRAM_ATTR ButtonIRQ() { + portENTER_CRITICAL(&timerMux); + ButtonPressedIRQ++; + portEXIT_CRITICAL(&timerMux); +} void readButton() { - if (ButtonPressedIRQ) { portENTER_CRITICAL(&timerMux); ButtonPressedIRQ = 0; portEXIT_CRITICAL(&timerMux); @@ -17,6 +20,5 @@ void readButton() { payload.reset(); payload.addButton(0x01); SendData(BUTTONPORT); - } } #endif \ No newline at end of file diff --git a/src/cyclic.cpp b/src/cyclic.cpp index b0c1a0b5..756c1a42 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -23,6 +23,19 @@ void doHousekeeping() { if (cfg.runmode == 1) ESP.restart(); +// task storage debugging // +#ifdef HAS_LORA + ESP_LOGD(TAG, "Loraloop %d bytes left", + uxTaskGetStackHighWaterMark(LoraTask)); +#endif + ESP_LOGD(TAG, "Wifiloop %d bytes left", + uxTaskGetStackHighWaterMark(wifiSwitchTask)); + ESP_LOGD(TAG, "Statemachine %d bytes left", + uxTaskGetStackHighWaterMark(stateMachineTask)); +#ifdef HAS_GPS + ESP_LOGD(TAG, "Gpsloop %d bytes left", uxTaskGetStackHighWaterMark(GpsTask)); +#endif + // read battery voltage into global variable #ifdef HAS_BATTERY_PROBE batt_voltage = read_voltage(); @@ -48,7 +61,7 @@ void doHousekeeping() { esp_get_minimum_free_heap_size(), ESP.getFreeHeap()); SendData(COUNTERPORT); // send data before clearing counters reset_counters(); // clear macs container and reset all counters - reset_salt(); // get new salt for salting hashes + get_salt(); // get new salt for salting hashes if (esp_get_minimum_free_heap_size() <= MEM_LOW) // check again esp_restart(); // memory leak, reset device diff --git a/src/display.cpp b/src/display.cpp index ba71a544..e7c168bb 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -13,7 +13,7 @@ const char lora_datarate[] = {"1211100908077BFSNA"}; const char lora_datarate[] = {"100908078CNA121110090807"}; #endif -uint8_t DisplayState = 0; +uint8_t volatile DisplayState = 0; // helper function, prints a hex key on display void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { @@ -91,6 +91,10 @@ void init_display(const char *Productname, const char *Version) { void refreshtheDisplay() { + portENTER_CRITICAL(&timerMux); + DisplayTimerIRQ = 0; + portEXIT_CRITICAL(&timerMux); + // set display on/off according to current device configuration if (DisplayState != cfg.screenon) { DisplayState = cfg.screenon; @@ -114,7 +118,8 @@ void refreshtheDisplay() { // update Battery status (line 2) #ifdef HAS_BATTERY_PROBE u8x8.setCursor(0, 2); - u8x8.printf(batt_voltage > 4000 ? "B:USB " : "B:%.1fV", batt_voltage / 1000.0); + u8x8.printf(batt_voltage > 4000 ? "B:USB " : "B:%.1fV", + batt_voltage / 1000.0); #endif // update GPS status (line 2) @@ -191,13 +196,4 @@ void IRAM_ATTR DisplayIRQ() { portEXIT_CRITICAL_ISR(&timerMux); } -void updateDisplay() { - if (DisplayTimerIRQ) { - portENTER_CRITICAL(&timerMux); - DisplayTimerIRQ = 0; - portEXIT_CRITICAL(&timerMux); - refreshtheDisplay(); - } -} - #endif // HAS_DISPLAY \ No newline at end of file diff --git a/src/display.h b/src/display.h index e85b9ee1..39a3128a 100644 --- a/src/display.h +++ b/src/display.h @@ -3,13 +3,12 @@ #include -extern uint8_t DisplayState; +extern uint8_t volatile DisplayState; extern HAS_DISPLAY u8x8; void init_display(const char *Productname, const char *Version); void refreshtheDisplay(void); void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); -void updateDisplay(void); void DisplayIRQ(void); #endif \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index 9d79575d..a63859e1 100644 --- a/src/globals.h +++ b/src/globals.h @@ -39,19 +39,23 @@ typedef struct { } MessageBuffer_t; // global variables -extern configData_t cfg; // current device configuration +extern configData_t cfg; // current device configuration extern char display_line6[], display_line7[]; // screen buffers -extern uint8_t channel; // wifi channel rotation counter -extern uint16_t macs_total, macs_wifi, macs_ble, batt_voltage; // display values +extern uint8_t volatile channel; // wifi channel rotation counter +extern uint16_t volatile macs_total, macs_wifi, macs_ble, + batt_voltage; // display values extern std::set macs; // temp storage for MACs extern hw_timer_t *channelSwitch, *sendCycle; extern portMUX_TYPE timerMux; -extern volatile int SendCycleTimerIRQ, HomeCycleIRQ, DisplayTimerIRQ, +extern volatile uint8_t SendCycleTimerIRQ, HomeCycleIRQ, DisplayTimerIRQ, ChannelTimerIRQ, ButtonPressedIRQ; extern std::array::iterator it; extern std::array beacons; +extern SemaphoreHandle_t xWifiChannelSwitchSemaphore; +extern TaskHandle_t stateMachineTask, wifiSwitchTask; + #ifdef HAS_GPS extern TaskHandle_t GpsTask; #include "gps.h" diff --git a/src/hal/lopy.h b/src/hal/lopy.h index 2caeb308..d8d678cb 100644 --- a/src/hal/lopy.h +++ b/src/hal/lopy.h @@ -3,7 +3,9 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define HAS_SPI 1 // comment out if device shall not send data via SPI #define CFG_sx1272_radio 1 -#define HAS_LED NOT_A_PIN // LoPy has no on board LED, so we use RGB LED on LoPy +//#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED +#define HAS_LED GPIO_NUM_12 // use if LoPy is on Expansion Board, this has a user LED +#define LED_ACTIVE_LOW 1 // use if LoPy is on Expansion Board, this has a user LED #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 // Hardware pin definitions for Pycom LoPy board @@ -28,7 +30,7 @@ // uncomment this only if your LoPy runs on a expansion board 3.0 //#define HAS_BATTERY_PROBE ADC1_GPIO39_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 //#define BATT_FACTOR 2 // voltage divider 1MOhm/1MOhm on board -//#define HAS_BUTTON GPIO_NUM_37 // (P14) +//#define HAS_BUTTON GPIO_NUM_13 // (P14) //#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown // uncomment this only if your LoPy runs on a expansion board 2.0 diff --git a/src/hal/lopy4.h b/src/hal/lopy4.h index cf988324..47f37f7f 100644 --- a/src/hal/lopy4.h +++ b/src/hal/lopy4.h @@ -3,7 +3,9 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define HAS_SPI 1 // comment out if device shall not send data via SPI #define CFG_sx1276_radio 1 -#define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4 +//#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED +#define HAS_LED GPIO_NUM_12 // use if LoPy is on Expansion Board, this has a user LED +#define LED_ACTIVE_LOW 1 // use if LoPy is on Expansion Board, this has a user LED #define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0 #define BOARD_HAS_PSRAM // use extra 4MB extern RAM @@ -29,7 +31,7 @@ // uncomment this only if your LoPy runs on a expansion board 3.0 #define HAS_BATTERY_PROBE ADC1_GPIO39_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BATT_FACTOR 2 // voltage divider 1MOhm/1MOhm on board -#define HAS_BUTTON GPIO_NUM_37 // (P14) +#define HAS_BUTTON GPIO_NUM_13 // (P14) #define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown // uncomment this only if your LoPy runs on a expansion board 2.0 diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 95babc37..26ef93a3 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -247,7 +247,9 @@ void lorawan_loop(void *pvParameters) { configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check while (1) { - os_runloop_once(); // execute LMIC jobs + //vTaskSuspendAll(); + os_runloop_once(); // execute LMIC jobs + //xTaskResumeAll(); vTaskDelay(2 / portTICK_PERIOD_MS); // yield to CPU } } diff --git a/src/macsniff.cpp b/src/macsniff.cpp index ac037e28..52056753 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -11,8 +11,8 @@ static const char TAG[] = "main"; uint16_t salt; -uint16_t reset_salt(void) { - salt = random(65536); // get new 16bit random for salting hashes +uint16_t get_salt(void) { + salt = (uint16_t)random(65536); // get new 16bit random for salting hashes return salt; } @@ -71,8 +71,8 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { // https://en.wikipedia.org/wiki/MAC_Address_Anonymization snprintf(buff, sizeof(buff), "%08X", - addr2int + (uint32_t)salt); // convert usigned 32-bit salted MAC to - // 8 digit hex string + addr2int + (uint32_t)salt); // convert usigned 32-bit salted MAC + // to 8 digit hex string hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars // to fit hash in uint16_t container auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique @@ -81,7 +81,6 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { // Count only if MAC was not yet seen if (added) { - // increment counter and one blink led if (sniff_type == MAC_SNIFF_WIFI) { macs_wifi++; // increment Wifi MACs counter diff --git a/src/macsniff.h b/src/macsniff.h index 40adb6cf..81e5a2ed 100644 --- a/src/macsniff.h +++ b/src/macsniff.h @@ -12,7 +12,7 @@ #define MAC_SNIFF_WIFI 0 #define MAC_SNIFF_BLE 1 -uint16_t reset_salt(void); +uint16_t get_salt(void); uint64_t macConvert(uint8_t *paddr); bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type); void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb); diff --git a/src/main.cpp b/src/main.cpp index 8f4bd99c..15363f54 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,6 +32,7 @@ gpsloop 0 2 read data from GPS over serial or i2c IDLE 1 0 Arduino loop() -> used for LED switching loraloop 1 1 runs the LMIC stack statemachine 1 3 switches application process logic +wifiloop 0 4 rotates wifi channels ESP32 hardware timers ========================== @@ -47,18 +48,20 @@ ESP32 hardware timers configData_t cfg; // struct holds current device configuration char display_line6[16], display_line7[16]; // display buffers -uint8_t channel = 0; // channel rotation counter -uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0, - batt_voltage = 0; // globals for display +uint8_t volatile channel = 0; // channel rotation counter +uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0, + batt_voltage = 0; // globals for display // hardware timer for cyclic tasks hw_timer_t *channelSwitch, *displaytimer, *sendCycle, *homeCycle; // this variables will be changed in the ISR, and read in main loop -volatile int ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, SendCycleTimerIRQ = 0, - DisplayTimerIRQ = 0, HomeCycleIRQ = 0; +uint8_t volatile ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, + SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0, HomeCycleIRQ = 0; -TaskHandle_t StateTask = NULL; +TaskHandle_t stateMachineTask, wifiSwitchTask; + +SemaphoreHandle_t xWifiChannelSwitchSemaphore; // RTos send queues for payload transmit #ifdef HAS_LORA @@ -96,7 +99,7 @@ void setup() { // disable brownout detection #ifdef DISABLE_BROWNOUT // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 - (*((volatile uint32_t *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; + (*((uint32_t volatile *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; #endif // setup debug output or silence device @@ -143,12 +146,15 @@ void setup() { batt_voltage = read_voltage(); #endif +#ifdef USE_OTA + strcat_P(features, " OTA"); // reboot to firmware update mode if ota trigger switch is set if (cfg.runmode == 1) { cfg.runmode = 0; saveConfig(); start_ota_update(); } +#endif // initialize button #ifdef HAS_BUTTON @@ -242,11 +248,6 @@ void setup() { timerAlarmEnable(displaytimer); #endif - // setup channel rotation trigger IRQ using esp32 hardware timer 1 - channelSwitch = timerBegin(1, 800, true); - timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); - timerAlarmWrite(channelSwitch, cfg.wifichancycle * 1000, true); - // setup send cycle trigger IRQ using esp32 hardware timer 2 sendCycle = timerBegin(2, 8000, true); timerAttachInterrupt(sendCycle, &SendCycleIRQ, true); @@ -257,6 +258,12 @@ void setup() { timerAttachInterrupt(homeCycle, &homeCycleIRQ, true); timerAlarmWrite(homeCycle, HOMECYCLE * 10000, true); + // setup channel rotation trigger IRQ using esp32 hardware timer 1 + xWifiChannelSwitchSemaphore = xSemaphoreCreateBinary(); + channelSwitch = timerBegin(1, 800, true); + timerAttachInterrupt(channelSwitch, &ChannelSwitchIRQ, true); + timerAlarmWrite(channelSwitch, cfg.wifichancycle * 1000, true); + // enable timers // caution, see: https://github.com/espressif/arduino-esp32/issues/1313 yield(); @@ -301,8 +308,13 @@ void setup() { // https://techtutorialsx.com/2017/05/09/esp32-get-task-execution-core/ ESP_LOGI(TAG, "Starting Lora..."); - xTaskCreatePinnedToCore(lorawan_loop, "loraloop", 2048, (void *)1, 1, - &LoraTask, 1); + xTaskCreatePinnedToCore(lorawan_loop, /* task function */ + "loraloop", /* name of task */ + 2560, /* stack size of task */ + (void *)1, /* parameter of the task */ + 1, /* priority of the task */ + &LoraTask, /* task handle*/ + 1); /* CPU core */ #endif // if device has GPS and it is enabled, start GPS reader task on core 0 with @@ -310,7 +322,13 @@ void setup() { // streaming NMEA data #ifdef HAS_GPS ESP_LOGI(TAG, "Starting GPS..."); - xTaskCreatePinnedToCore(gps_loop, "gpsloop", 2048, (void *)1, 2, &GpsTask, 0); + xTaskCreatePinnedToCore(gps_loop, /* task function */ + "gpsloop", /* name of task */ + 1024, /* stack size of task */ + (void *)1, /* parameter of the task */ + 2, /* priority of the task */ + &GpsTask, /* task handle*/ + 0); /* CPU core */ #endif // start BLE scan callback if BLE function is enabled in NVRAM configuration @@ -323,18 +341,30 @@ void setup() { // start wifi in monitor mode and start channel rotation task on core 0 ESP_LOGI(TAG, "Starting Wifi..."); - // esp_event_loop_init(NULL, NULL); - // ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); wifi_sniffer_init(); // 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 - reset_salt(); // get new 16bit for salting hashes + get_salt(); // get new 16bit for salting hashes + + // start wifi channel rotation task + xTaskCreatePinnedToCore(switchWifiChannel, /* task function */ + "wifiloop", /* name of task */ + 1024, /* stack size of task */ + NULL, /* parameter of the task */ + 4, /* priority of the task */ + &wifiSwitchTask, /* task handle*/ + 0); /* CPU core */ // start state machine ESP_LOGI(TAG, "Starting Statemachine..."); - xTaskCreatePinnedToCore(stateMachine, "stateloop", 2048, (void *)1, 3, - &StateTask, 1); + xTaskCreatePinnedToCore(stateMachine, /* task function */ + "stateloop", /* name of task */ + 2048, /* stack size of task */ + (void *)1, /* parameter of the task */ + 3, /* priority of the task */ + &stateMachineTask, /* task handle */ + 1); /* CPU core */ } // setup() @@ -347,4 +377,4 @@ void loop() { // give yield to CPU vTaskDelay(2 / portTICK_PERIOD_MS); -} +} \ No newline at end of file diff --git a/src/ota.cpp b/src/ota.cpp index c4f64c90..15ef87b5 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -1,3 +1,5 @@ +#ifdef USE_OTA + /* Parts of this code: Copyright (c) 2014-present PlatformIO @@ -17,7 +19,6 @@ #include "ota.h" -#include using namespace std; const BintrayClient bintray(BINTRAY_USER, BINTRAY_REPO, BINTRAY_PACKAGE); @@ -29,33 +30,27 @@ const int port = 443; const uint32_t RESPONSE_TIMEOUT_MS = 5000; // Variables to validate firmware content -volatile int contentLength = 0; -volatile bool isValidContentType = false; +int volatile contentLength = 0; +bool volatile isValidContentType = false; // Local logging tag static const char TAG[] = "main"; -void display(const uint8_t row, std::string status, std::string msg) { -#ifdef HAS_DISPLAY - u8x8.setCursor(14, row); - u8x8.print((status.substr(0, 2)).c_str()); - if (!msg.empty()) { - u8x8.clearLine(7); - u8x8.setCursor(0, 7); - u8x8.print(msg.substr(0, 16).c_str()); - } -#endif -} - -// callback function to show download progress while streaming data -void show_progress(size_t current, size_t size) { - char buf[17]; - snprintf(buf, 17, "%-9lu (%3lu%%)", current, current*100 / size); - display(4, "**", buf); +// helper function to extract header value from header +inline String getHeaderValue(String header, String headerName) { + return header.substring(strlen(headerName.c_str())); } void start_ota_update() { +// check battery status if we can before doing ota +#ifdef HAS_BATTERY_PROBE + if (batt_voltage < OTA_MIN_BATT) { + ESP_LOGW(TAG, "Battery voltage %dmV too low for OTA", batt_voltage); + return; + } +#endif + // turn on LED #if (HAS_LED != NOT_A_PIN) #ifdef LED_ACTIVE_LOW @@ -99,7 +94,7 @@ void start_ota_update() { if (i >= 0) { ESP_LOGI(TAG, "Connected to %s", WIFI_SSID); display(1, "OK", "WiFi connected"); - checkFirmwareUpdates(); // gets and flashes new firmware + do_ota_update(); // gets and flashes new firmware } else { ESP_LOGI(TAG, "Could not connect to %s, rebooting.", WIFI_SSID); display(1, " E", "no WiFi connect"); @@ -121,7 +116,9 @@ void start_ota_update() { } // start_ota_update -void checkFirmwareUpdates() { +void do_ota_update() { + char buf[17]; + // Fetch the latest firmware version ESP_LOGI(TAG, "Checking latest firmware version on server..."); display(2, "**", "checking version"); @@ -140,24 +137,10 @@ void checkFirmwareUpdates() { } ESP_LOGI(TAG, "New firmware version v%s available. Downloading...", latest.c_str()); - display(2, "OK", ""); + display(2, "OK", latest.c_str()); - processOTAUpdate(latest); -} - -// helper function to extract header value from header -inline String getHeaderValue(String header, String headerName) { - return header.substring(strlen(headerName.c_str())); -} - -/** - * OTA update processing - */ -void processOTAUpdate(const String &version) { - - char buf[17]; - display(3, "**", "requesting file"); - String firmwarePath = bintray.getBinaryPath(version); + display(3, "**", ""); + String firmwarePath = bintray.getBinaryPath(latest); if (!firmwarePath.endsWith(".bin")) { ESP_LOGI(TAG, "Unsupported binary format, OTA update cancelled."); display(3, " E", "file type error"); @@ -268,10 +251,10 @@ void processOTAUpdate(const String &version) { size_t written, current, size; if (Update.begin(contentLength)) { - +#ifdef HAS_DISPLAY // register callback function for showing progress while streaming data Update.onProgress(&show_progress); - +#endif int i = FLASH_MAX_TRY; while ((i--) && (written != contentLength)) { @@ -327,6 +310,25 @@ void processOTAUpdate(const String &version) { ESP_LOGI(TAG, "OTA update failed. Rebooting to runmode with current version."); client.stop(); +} // do_ota_update + +void display(const uint8_t row, const std::string status, const std::string msg) { +#ifdef HAS_DISPLAY + u8x8.setCursor(14, row); + u8x8.print((status.substr(0, 2)).c_str()); + if (!msg.empty()) { + u8x8.clearLine(7); + u8x8.setCursor(0, 7); + u8x8.print(msg.substr(0, 16).c_str()); + } +} + +// callback function to show download progress while streaming data +void show_progress(size_t current, size_t size) { + char buf[17]; + snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size); + display(4, "**", buf); +#endif } // helper function to compare two versions. Returns 1 if v2 is @@ -363,3 +365,4 @@ int version_compare(const String v1, const String v2) { } return 0; } +#endif // USE_OTA \ No newline at end of file diff --git a/src/ota.h b/src/ota.h index 25ccbb11..59c1e464 100644 --- a/src/ota.h +++ b/src/ota.h @@ -1,18 +1,21 @@ #ifndef OTA_H #define OTA_H +#ifdef USE_OTA + #include "globals.h" #include "update.h" #include #include -//#include #include #include -void checkFirmwareUpdates(); -void processOTAUpdate(const String &version); +void do_ota_update(); void start_ota_update(); int version_compare(const String v1, const String v2); void show_progress(size_t current, size_t size); +void display(const uint8_t row, const std::string status, const std::string msg); + +#endif // USE_OTA #endif // OTA_H diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 1c6c6948..28264cb8 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -66,8 +66,10 @@ #define HOMECYCLE 30 // house keeping cycle in seconds [default = 30 secs] // OTA settings +#define USE_OTA 1 // Comment out to disable OTA update #define WIFI_MAX_TRY 20 // maximum number of wifi connect attempts for OTA update [default = 20] #define FLASH_MAX_TRY 3 // maximum number of attempts for writing update binary to flash [default = 3] +#define OTA_MIN_BATT 3700 // minimum battery level vor OTA [millivolt] // LMIC settings // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 7f984cdb..42e855a9 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -18,7 +18,7 @@ void set_reset(uint8_t val[]) { case 1: // reset MAC counter ESP_LOGI(TAG, "Remote command: reset MAC counter"); reset_counters(); // clear macs - reset_salt(); // get new salt + get_salt(); // get new salt sprintf(display_line6, "Reset counter"); break; case 2: // reset device to factory settings @@ -33,9 +33,14 @@ void set_reset(uint8_t val[]) { break; case 9: // reset and ask for software update via Wifi OTA ESP_LOGI(TAG, "Remote command: software update via Wifi"); +#ifdef USE_OTA sprintf(display_line6, "Software update"); cfg.runmode = 1; +#else + sprintf(display_line6, "Software update not implemented"); +#endif // USE_OTA break; + default: ESP_LOGW(TAG, "Remote command: reset called with invalid parameter(s)"); } diff --git a/src/senddata.cpp b/src/senddata.cpp index f738ee6b..2ca7973a 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -29,7 +29,7 @@ void SendData(uint8_t port) { // clear counter if not in cumulative counter mode if ((port == COUNTERPORT) && (cfg.countermode != 1)) { reset_counters(); // clear macs container and reset all counters - reset_salt(); // get new salt for salting hashes + get_salt(); // get new salt for salting hashes ESP_LOGI(TAG, "Counter cleared"); } } // SendData diff --git a/src/statemachine.cpp b/src/statemachine.cpp index 9dfac811..c9c5ed07 100644 --- a/src/statemachine.cpp +++ b/src/statemachine.cpp @@ -10,16 +10,15 @@ void stateMachine(void *pvParameters) { while (1) { #ifdef HAS_BUTTON - readButton(); + if (ButtonPressedIRQ) + readButton(); #endif #ifdef HAS_DISPLAY - updateDisplay(); + if (DisplayTimerIRQ) + refreshtheDisplay(); #endif - // check wifi scan cycle and if due rotate channel - if (ChannelTimerIRQ) - switchWifiChannel(channel); // check housekeeping cycle and if due do the work if (HomeCycleIRQ) doHousekeeping(); diff --git a/src/statemachine.h b/src/statemachine.h index 7390e5c9..ec9966a0 100644 --- a/src/statemachine.h +++ b/src/statemachine.h @@ -8,5 +8,6 @@ #include "cyclic.h" void stateMachine(void *pvParameters); +void stateMachineInit(); #endif diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index 55c690ff..21a5a95e 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -30,7 +30,11 @@ void wifi_sniffer_init(void) { cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM wifi_promiscuous_filter_t filter = { .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // configure Wifi with cfg + + // esp_event_loop_init(NULL, NULL); + // ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // configure Wifi with cfg ESP_ERROR_CHECK( esp_wifi_set_country(&wifi_country)); // set locales for RF and channels ESP_ERROR_CHECK( @@ -43,20 +47,22 @@ void wifi_sniffer_init(void) { ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode } -// Wifi channel rotation -void switchWifiChannel(uint8_t &ch) { - portENTER_CRITICAL(&timerMux); - ChannelTimerIRQ = 0; - portEXIT_CRITICAL(&timerMux); - // rotates variable channel 1..WIFI_CHANNEL_MAX - ch = (ch % WIFI_CHANNEL_MAX) + 1; - esp_wifi_set_channel(ch, WIFI_SECOND_CHAN_NONE); - ESP_LOGD(TAG, "Wifi set channel %d", &ch); - } +// IRQ Handler +void ChannelSwitchIRQ() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + // unblock wifi channel rotation task + xSemaphoreGiveFromISR(xWifiChannelSwitchSemaphore, &xHigherPriorityTaskWoken); +} -// IRQ handler -void IRAM_ATTR ChannelSwitchIRQ() { - portENTER_CRITICAL(&timerMux); - ChannelTimerIRQ++; - portEXIT_CRITICAL(&timerMux); -} \ No newline at end of file +// Wifi channel rotation task +void switchWifiChannel(void * parameter) { + while (1) { + // task is remaining in block state waiting for channel switch timer interrupt event + xSemaphoreTake(xWifiChannelSwitchSemaphore, portMAX_DELAY); + // rotates variable channel 1..WIFI_CHANNEL_MAX + channel = (channel % WIFI_CHANNEL_MAX) + 1; + esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); + ESP_LOGD(TAG, "Wifi set channel %d", channel); + } + vTaskDelete(NULL); +} diff --git a/src/wifiscan.h b/src/wifiscan.h index 5e8aae9a..930178f2 100644 --- a/src/wifiscan.h +++ b/src/wifiscan.h @@ -28,6 +28,6 @@ typedef struct { void wifi_sniffer_init(void); void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void ChannelSwitchIRQ(void); -void switchWifiChannel(uint8_t &ch); +void switchWifiChannel(void * parameter); #endif \ No newline at end of file