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.
------------------------------------------------------------------------------------------------
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>
* ESP32/016 WiFi Sniffer

View File

@ -6,13 +6,13 @@
; ---> SELECT TARGET PLATFORM HERE! <---
[platformio]
env_default = generic
;env_default = generic
;env_default = ebox
;env_default = heltec
;env_default = ttgov1
;env_default = ttgov2
;env_default = ttgov21old
;env_default = ttgov21new
env_default = ttgov21new
;env_default = ttgobeam
;env_default = lopy
;env_default = lopy4
@ -26,10 +26,10 @@ 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.6
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
debug_level = 3
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
upload_protocol = esptool
;upload_protocol = custom

View File

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

View File

@ -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

View File

@ -9,7 +9,6 @@ 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

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> beacons;
extern SemaphoreHandle_t xWifiChannelSwitchSemaphore;
#ifdef HAS_GPS
extern TaskHandle_t GpsTask;
#include "gps.h"

View File

@ -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
}
}

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
loraloop 1 1 runs the LMIC stack
statemachine 1 3 switches application process logic
wifiloop 0 4 rotates wifi channels
ESP32 hardware timers
==========================
@ -58,7 +59,9 @@ hw_timer_t *channelSwitch, *displaytimer, *sendCycle, *homeCycle;
uint8_t volatile ButtonPressedIRQ = 0, ChannelTimerIRQ = 0,
SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0, HomeCycleIRQ = 0;
TaskHandle_t StateTask = NULL;
TaskHandle_t stateMachineTask = NULL;
SemaphoreHandle_t xWifiChannelSwitchSemaphore;
// RTos send queues for payload transmit
#ifdef HAS_LORA
@ -245,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);
@ -260,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();
@ -326,18 +330,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
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
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()
@ -350,4 +366,4 @@ void loop() {
// give yield to CPU
vTaskDelay(2 / portTICK_PERIOD_MS);
}
}

View File

@ -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();

View File

@ -8,5 +8,6 @@
#include "cyclic.h"
void stateMachine(void *pvParameters);
void stateMachineInit();
#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
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 volatile &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);
}
// Wifi channel rotation task
void switchWifiChannel(void * parameter) {
while (1) {
// task in block state to wait 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);
}

View File

@ -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 volatile &ch);
void switchWifiChannel(void * parameter);
#endif