This commit is contained in:
Klaus K Wilting 2018-09-27 14:01:23 +02:00
parent 5d883e12f6
commit cb4870bce5
12 changed files with 72 additions and 53 deletions

View File

@ -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. 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 <lpodkalicki@gmail.com> * Copyright (c) 2017, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com>
* ESP32/016 WiFi Sniffer * ESP32/016 WiFi Sniffer

View File

@ -6,13 +6,13 @@
; ---> SELECT TARGET PLATFORM HERE! <--- ; ---> SELECT TARGET PLATFORM HERE! <---
[platformio] [platformio]
env_default = generic ;env_default = generic
;env_default = ebox ;env_default = ebox
;env_default = heltec ;env_default = heltec
;env_default = ttgov1 ;env_default = ttgov1
;env_default = ttgov2 ;env_default = ttgov2
;env_default = ttgov21old ;env_default = ttgov21old
;env_default = ttgov21new env_default = ttgov21new
;env_default = ttgobeam ;env_default = ttgobeam
;env_default = lopy ;env_default = lopy
;env_default = lopy4 ;env_default = lopy4
@ -26,10 +26,10 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
[common] [common]
; for release_version use max. 10 chars total, use any decimal format like "a.b.c" ; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
release_version = 1.5.6 release_version = 1.5.7
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; 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 ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
debug_level = 0 debug_level = 3
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA ; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
upload_protocol = esptool upload_protocol = esptool
;upload_protocol = custom ;upload_protocol = custom

View File

@ -13,7 +13,6 @@ void IRAM_ATTR ButtonIRQ() {
} }
void readButton() { void readButton() {
if (ButtonPressedIRQ) {
portENTER_CRITICAL(&timerMux); portENTER_CRITICAL(&timerMux);
ButtonPressedIRQ = 0; ButtonPressedIRQ = 0;
portEXIT_CRITICAL(&timerMux); portEXIT_CRITICAL(&timerMux);
@ -21,6 +20,5 @@ void readButton() {
payload.reset(); payload.reset();
payload.addButton(0x01); payload.addButton(0x01);
SendData(BUTTONPORT); SendData(BUTTONPORT);
}
} }
#endif #endif

View File

@ -91,6 +91,10 @@ void init_display(const char *Productname, const char *Version) {
void refreshtheDisplay() { void refreshtheDisplay() {
portENTER_CRITICAL(&timerMux);
DisplayTimerIRQ = 0;
portEXIT_CRITICAL(&timerMux);
// set display on/off according to current device configuration // set display on/off according to current device configuration
if (DisplayState != cfg.screenon) { if (DisplayState != cfg.screenon) {
DisplayState = cfg.screenon; DisplayState = cfg.screenon;
@ -114,7 +118,8 @@ void refreshtheDisplay() {
// update Battery status (line 2) // update Battery status (line 2)
#ifdef HAS_BATTERY_PROBE #ifdef HAS_BATTERY_PROBE
u8x8.setCursor(0, 2); 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 #endif
// update GPS status (line 2) // update GPS status (line 2)
@ -191,13 +196,4 @@ void IRAM_ATTR DisplayIRQ() {
portEXIT_CRITICAL_ISR(&timerMux); portEXIT_CRITICAL_ISR(&timerMux);
} }
void updateDisplay() {
if (DisplayTimerIRQ) {
portENTER_CRITICAL(&timerMux);
DisplayTimerIRQ = 0;
portEXIT_CRITICAL(&timerMux);
refreshtheDisplay();
}
}
#endif // HAS_DISPLAY #endif // HAS_DISPLAY

View File

@ -9,7 +9,6 @@ extern HAS_DISPLAY u8x8;
void init_display(const char *Productname, const char *Version); void init_display(const char *Productname, const char *Version);
void refreshtheDisplay(void); void refreshtheDisplay(void);
void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); void DisplayKey(const uint8_t *key, uint8_t len, bool lsb);
void updateDisplay(void);
void DisplayIRQ(void); void DisplayIRQ(void);
#endif #endif

View File

@ -53,6 +53,8 @@ extern volatile uint8_t SendCycleTimerIRQ, HomeCycleIRQ, DisplayTimerIRQ,
extern std::array<uint64_t, 0xff>::iterator it; extern std::array<uint64_t, 0xff>::iterator it;
extern std::array<uint64_t, 0xff> beacons; extern std::array<uint64_t, 0xff> beacons;
extern SemaphoreHandle_t xWifiChannelSwitchSemaphore;
#ifdef HAS_GPS #ifdef HAS_GPS
extern TaskHandle_t GpsTask; extern TaskHandle_t GpsTask;
#include "gps.h" #include "gps.h"

View File

@ -247,7 +247,9 @@ void lorawan_loop(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
while (1) { while (1) {
os_runloop_once(); // execute LMIC jobs //vTaskSuspendAll();
os_runloop_once(); // execute LMIC jobs
//xTaskResumeAll();
vTaskDelay(2 / portTICK_PERIOD_MS); // yield to CPU vTaskDelay(2 / portTICK_PERIOD_MS); // yield to CPU
} }
} }

View File

@ -32,6 +32,7 @@ gpsloop 0 2 read data from GPS over serial or i2c
IDLE 1 0 Arduino loop() -> used for LED switching IDLE 1 0 Arduino loop() -> used for LED switching
loraloop 1 1 runs the LMIC stack loraloop 1 1 runs the LMIC stack
statemachine 1 3 switches application process logic statemachine 1 3 switches application process logic
wifiloop 0 4 rotates wifi channels
ESP32 hardware timers ESP32 hardware timers
========================== ==========================
@ -58,7 +59,9 @@ hw_timer_t *channelSwitch, *displaytimer, *sendCycle, *homeCycle;
uint8_t volatile ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, uint8_t volatile ButtonPressedIRQ = 0, ChannelTimerIRQ = 0,
SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0, HomeCycleIRQ = 0; SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0, HomeCycleIRQ = 0;
TaskHandle_t StateTask = NULL; TaskHandle_t stateMachineTask = NULL;
SemaphoreHandle_t xWifiChannelSwitchSemaphore;
// RTos send queues for payload transmit // RTos send queues for payload transmit
#ifdef HAS_LORA #ifdef HAS_LORA
@ -245,11 +248,6 @@ void setup() {
timerAlarmEnable(displaytimer); timerAlarmEnable(displaytimer);
#endif #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 // setup send cycle trigger IRQ using esp32 hardware timer 2
sendCycle = timerBegin(2, 8000, true); sendCycle = timerBegin(2, 8000, true);
timerAttachInterrupt(sendCycle, &SendCycleIRQ, true); timerAttachInterrupt(sendCycle, &SendCycleIRQ, true);
@ -260,6 +258,12 @@ void setup() {
timerAttachInterrupt(homeCycle, &homeCycleIRQ, true); timerAttachInterrupt(homeCycle, &homeCycleIRQ, true);
timerAlarmWrite(homeCycle, HOMECYCLE * 10000, 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 // enable timers
// caution, see: https://github.com/espressif/arduino-esp32/issues/1313 // caution, see: https://github.com/espressif/arduino-esp32/issues/1313
yield(); yield();
@ -326,18 +330,30 @@ void setup() {
// start wifi in monitor mode and start channel rotation task on core 0 // start wifi in monitor mode and start channel rotation task on core 0
ESP_LOGI(TAG, "Starting Wifi..."); ESP_LOGI(TAG, "Starting Wifi...");
// esp_event_loop_init(NULL, NULL);
// ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_sniffer_init(); wifi_sniffer_init();
// initialize salt value using esp_random() called by random() in // initialize salt value using esp_random() called by random() in
// arduino-esp32 core. Note: do this *after* wifi has started, since // arduino-esp32 core. Note: do this *after* wifi has started, since
// function gets it's seed from RF noise // function gets it's seed from RF noise
get_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 */
3048, /* stack size of task */
NULL, /* parameter of the task */
4, /* priority of the task */
NULL, /* task handle*/
0); /* CPU core */
// start state machine // start state machine
ESP_LOGI(TAG, "Starting Statemachine..."); ESP_LOGI(TAG, "Starting Statemachine...");
xTaskCreatePinnedToCore(stateMachine, "stateloop", 2048, (void *)1, 3, xTaskCreatePinnedToCore(stateMachine, /* task function */
&StateTask, 1); "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() } // setup()

View File

@ -10,16 +10,15 @@ void stateMachine(void *pvParameters) {
while (1) { while (1) {
#ifdef HAS_BUTTON #ifdef HAS_BUTTON
readButton(); if (ButtonPressedIRQ)
readButton();
#endif #endif
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
updateDisplay(); if (DisplayTimerIRQ)
refreshtheDisplay();
#endif #endif
// check wifi scan cycle and if due rotate channel
if (ChannelTimerIRQ)
switchWifiChannel(channel);
// check housekeeping cycle and if due do the work // check housekeeping cycle and if due do the work
if (HomeCycleIRQ) if (HomeCycleIRQ)
doHousekeeping(); doHousekeeping();

View File

@ -8,5 +8,6 @@
#include "cyclic.h" #include "cyclic.h"
void stateMachine(void *pvParameters); void stateMachine(void *pvParameters);
void stateMachineInit();
#endif #endif

View File

@ -30,7 +30,11 @@ void wifi_sniffer_init(void) {
cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM cfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM
wifi_promiscuous_filter_t filter = { wifi_promiscuous_filter_t filter = {
.filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames .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_ERROR_CHECK(
esp_wifi_set_country(&wifi_country)); // set locales for RF and channels esp_wifi_set_country(&wifi_country)); // set locales for RF and channels
ESP_ERROR_CHECK( 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 ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
} }
// Wifi channel rotation // IRQ Handler
void switchWifiChannel(uint8_t volatile &ch) { void ChannelSwitchIRQ() {
portENTER_CRITICAL(&timerMux); BaseType_t xHigherPriorityTaskWoken = pdFALSE;
ChannelTimerIRQ = 0; // unblock wifi channel rotation task
portEXIT_CRITICAL(&timerMux); xSemaphoreGiveFromISR(xWifiChannelSwitchSemaphore, &xHigherPriorityTaskWoken);
// 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 // Wifi channel rotation task
void IRAM_ATTR ChannelSwitchIRQ() { void switchWifiChannel(void * parameter) {
portENTER_CRITICAL(&timerMux); while (1) {
ChannelTimerIRQ++; // task in block state to wait for channel switch timer interrupt event
portEXIT_CRITICAL(&timerMux); 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);
} }

View File

@ -28,6 +28,6 @@ typedef struct {
void wifi_sniffer_init(void); void wifi_sniffer_init(void);
void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
void ChannelSwitchIRQ(void); void ChannelSwitchIRQ(void);
void switchWifiChannel(uint8_t volatile &ch); void switchWifiChannel(void * parameter);
#endif #endif