diff --git a/README.md b/README.md index 878a8b46..eab22936 100644 --- a/README.md +++ b/README.md @@ -169,17 +169,18 @@ Output of user sensor data can be switched by user remote control command 0x14 s Output of sensor and peripheral data is internally switched by a bitmask register. Default mask can be tailored by editing *cfg.payloadmask* initialization value in [*configmanager.cpp*](src/configmanager.cpp) following this scheme: -| Bit | Sensordata | -| --- | ------------- | -| 0 | GPS | -| 1 | Beacon alarm | -| 2 | BME280/680 | -| 3 | Paxcounter | -| 4 | User sensor 1 | -| 5 | User sensor 2 | -| 6 | User sensor 3 | -| 7 | Batterylevel | +| Bit | Sensordata | Default +| --- | ------------- | ------- +| 0 | GPS | off* +| 1 | Beacon alarm | on +| 2 | BME280/680 | on +| 3 | Paxcounter | on +| 4 | User sensor 1 | on +| 5 | User sensor 2 | on +| 6 | User sensor 3 | on +| 7 | Batterylevel | off +*) GPS data can also be combined with payload on port 1, *#define GPSPORT 1* in paxcounter.conf to enable # Time sync @@ -428,6 +429,11 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts. 0 = battery data off [default] 1 = battery data on, sends voltage on port 8 +0x17 set Wifi scanner + + 0 = disabled + 1 = enabled [default] + 0x80 get device configuration Device answers with it's current configuration on Port 3. diff --git a/include/globals.h b/include/globals.h index 5b61fa58..8f2ef032 100644 --- a/include/globals.h +++ b/include/globals.h @@ -72,6 +72,7 @@ typedef struct { uint8_t wifichancycle; // wifi channel switch cycle [seconds/100] uint8_t blescantime; // BLE scan cycle duration [seconds] uint8_t blescan; // 0=disabled, 1=enabled + uint8_t wifiscan; // 0=disabled, 1=enabled uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4) uint8_t vendorfilter; // 0=disabled, 1=enabled uint8_t rgblum; // RGB Led luminosity (0..100%) diff --git a/include/rcommand.h b/include/rcommand.h index b3205256..2f6ae64f 100644 --- a/include/rcommand.h +++ b/include/rcommand.h @@ -8,6 +8,7 @@ #include "lorawan.h" #endif #include "macsniff.h" +#include "wifiscan.h" #include #include "cyclic.h" #include "timekeeper.h" diff --git a/include/wifiscan.h b/include/wifiscan.h index 35c42e06..340208cb 100644 --- a/include/wifiscan.h +++ b/include/wifiscan.h @@ -8,6 +8,7 @@ #include "hash.h" void wifi_sniffer_init(void); +void switch_wifi_sniffer (uint8_t state); static void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type); void switchWifiChannel(TimerHandle_t xTimer); diff --git a/platformio.ini b/platformio.ini index d7c1c122..9025d209 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,15 +43,15 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.9.72 +release_version = 1.9.82 ; 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 = 3 +debug_level = 4 extra_scripts = pre:build.py otakeyfile = ota.conf lorakeyfile = loraconf.h lmicconfigfile = lmic_config.h -platform_espressif32 = espressif32@1.11.0 +platform_espressif32 = espressif32@1.11.1 monitor_speed = 115200 upload_speed = 115200 lib_deps_lora = diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 0fd6ca39..40d4a0a8 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -9,9 +9,9 @@ nvs_handle my_handle; esp_err_t err; #define PAYLOADMASK \ - ((GPS_DATA | ALARM_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | \ - SENSOR2_DATA | SENSOR3_DATA) & \ - ~BATT_DATA) + ((ALARM_DATA | MEMS_DATA | COUNT_DATA | SENSOR1_DATA | SENSOR2_DATA | \ + SENSOR3_DATA) & \ + (~BATT_DATA) & (~GPS_DATA)) // populate cfg vars with factory settings void defaultConfig() { @@ -29,6 +29,7 @@ void defaultConfig() { BLESCANINTERVAL / 10; // BT channel scan cycle [seconds/100], default 1 (= 10ms) cfg.blescan = BLECOUNTER; // 0=disabled, 1=enabled + cfg.wifiscan = WIFICOUNTER; // 0=disabled, 1=enabled cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4) cfg.vendorfilter = VENDORFILTER; // 0=disabled, 1=enabled cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%) @@ -136,6 +137,10 @@ void saveConfig() { flash8 != cfg.blescan) nvs_set_i8(my_handle, "blescanmode", cfg.blescan); + if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) != ESP_OK || + flash8 != cfg.wifiscan) + nvs_set_i8(my_handle, "wifiscanmode", cfg.wifiscan); + if (nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || flash8 != cfg.wifiant) nvs_set_i8(my_handle, "wifiant", cfg.wifiant); @@ -321,6 +326,14 @@ void loadConfig() { saveConfig(); } + if (nvs_get_i8(my_handle, "wifiscanmode", &flash8) == ESP_OK) { + cfg.wifiscan = flash8; + ESP_LOGI(TAG, "WIFIscanmode = %d", flash8); + } else { + ESP_LOGI(TAG, "WIFIscanmode set to default %d", cfg.wifiscan); + saveConfig(); + } + if (nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK) { cfg.rssilimit = flash16; ESP_LOGI(TAG, "rssilimit = %d", flash16); diff --git a/src/display.cpp b/src/display.cpp index 05808f3c..2ac23091 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -218,12 +218,27 @@ void draw_page(time_t t, uint8_t page) { case 0: // line 3: wifi + bluetooth counters - dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi); -#if (BLECOUNTER) +#if ((WIFICOUNTER) && (BLECOUNTER)) + if (cfg.wifiscan) + dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi); + else + dp_printf(0, 3, FONT_SMALL, 0, "%s", "WIFI:off"); if (cfg.blescan) dp_printf(66, 3, FONT_SMALL, 0, "BLTH:%-5d", macs_ble); else dp_printf(66, 3, FONT_SMALL, 0, "%s", "BLTH:off"); +#elif ((WIFICOUNTER) && (!BLECOUNTER)) + if (cfg.wifiscan) + dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi); + else + dp_printf(0, 3, FONT_SMALL, 0, "%s", "WIFI:off"); +#elif ((!WIFICOUNTER) && (BLECOUNTER)) + if (cfg.blescan) + dp_printf(0, 3, FONT_SMALL, 0, "BLTH:%-5d", macs_ble); + else + dp_printf(0, 3, FONT_SMALL, 0, "%s", "BLTH:off"); +#else + dp_printf(0, 3, FONT_SMALL, 0, "%s", "Sniffer disabled"); #endif // line 4: Battery + GPS status + Wifi channel diff --git a/src/hal/octopus32.h b/src/hal/octopus32.h index f34f609b..19ed4ca5 100644 --- a/src/hal/octopus32.h +++ b/src/hal/octopus32.h @@ -9,6 +9,8 @@ // Hardware related definitions for #IoT Octopus32 with the Adafruit LoRaWAN Wing // You can use this configuration also with the Adafruit ESP32 Feather + the LoRaWAN Wing // In this config we use the Adafruit OLED Wing which is only 128x32 pixel, need to find a smaller font +// NOTE: if LORA_IRQ and LORA_IO1 are tied to the same GPIO using diodes on the board, +// you must disable LMIC_USE_INTERRUPTS in lmic_config.h // disable brownout detection (avoid unexpected reset on some boards) #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature diff --git a/src/lmic_config.h b/src/lmic_config.h index fb3a5816..dc55260a 100644 --- a/src/lmic_config.h +++ b/src/lmic_config.h @@ -21,7 +21,10 @@ #define LMIC_USE_INTERRUPTS 1 // time sync via LoRaWAN network, note: not supported by TTNv2 -// #define LMIC_ENABLE_DeviceTimeReq 1 +//#define LMIC_ENABLE_DeviceTimeReq 1 + +// use callback event handlers, not onEvent() reference +#define LMIC_ENABLE_onEvent 0 // This tells LMIC to make the receive windows bigger, in case your clock is // faster or slower. This causes the transceiver to be earlier switched on, diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 8b787580..ff8ecfe7 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -89,9 +89,7 @@ void lora_setupForNetwork(bool preJoin) { // other regions, this will need to be changed. LMIC_selectSubBand(1); #elif CFG_LMIC_EU_like - // setting for TheThingsNetwork - // TTN uses SF9, not SF12, for RX2 window - LMIC.dn2Dr = EU868_DR_SF9; + // settings for TheThingsNetwork // Enable link check validation LMIC_setLinkCheckMode(true); #endif diff --git a/src/main.cpp b/src/main.cpp index bf41a823..6d96d7b9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -62,7 +62,7 @@ PMUIRQ -> PMU chip gpio -> irqHandlerTask (Core 1) fired by software (Ticker.h) TIMESYNC_IRQ -> timeSync() -> irqHandlerTask (Core 1) -CYLCIC_IRQ -> housekeeping() -> irqHandlerTask (Core 1) +CYCLIC_IRQ -> housekeeping() -> irqHandlerTask (Core 1) SENDCYCLE_IRQ -> sendcycle() -> irqHandlerTask (Core 1) BME_IRQ -> bmecycle() -> irqHandlerTask (Core 1) @@ -364,16 +364,15 @@ void setup() { // start wifi in monitor mode and start channel rotation timer ESP_LOGI(TAG, "Starting Wifi..."); wifi_sniffer_init(); +#else + // switch off wifi + esp_wifi_deinit(); +#endif + // 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 -#else - // switch off wifi - WiFi.mode(WIFI_OFF); - esp_wifi_stop(); - esp_wifi_deinit(); -#endif // start state machine ESP_LOGI(TAG, "Starting Interrupt Handler..."); diff --git a/src/ota.cpp b/src/ota.cpp index d78a6453..087b92e7 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -246,7 +246,7 @@ int do_ota_update() { goto retry; } -#ifdef HAS_LED +#if (HAS_LED != NOT_A_PIN) #ifndef LED_ACTIVE_LOW if (!Update.begin(contentLength, U_FLASH, HAS_LED, HIGH)) { #else diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 293e9fae..3f3093de 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -224,6 +224,13 @@ void set_blescan(uint8_t val[]) { } } +void set_wifiscan(uint8_t val[]) { + ESP_LOGI(TAG, "Remote command: set WIFI scanner to %s", + val[0] ? "on" : "off"); + cfg.wifiscan = val[0] ? 1 : 0; + switch_wifi_sniffer(cfg.wifiscan); +} + void set_wifiant(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", val[0] ? "external" : "internal"); @@ -348,10 +355,11 @@ static cmd_t table[] = { {0x11, set_monitor, 1, true}, {0x12, set_beacon, 7, false}, {0x13, set_sensor, 2, true}, {0x14, set_payloadmask, 1, true}, {0x15, set_bme, 1, true}, {0x16, set_batt, 1, true}, - {0x80, get_config, 0, false}, {0x81, get_status, 0, false}, - {0x83, get_batt, 0, false}, {0x84, get_gps, 0, false}, - {0x85, get_bme, 0, false}, {0x86, get_time, 0, false}, - {0x87, set_time, 0, false}, {0x99, set_flush, 0, false}}; + {0x17, set_wifiscan, 1, true}, {0x80, get_config, 0, false}, + {0x81, get_status, 0, false}, {0x83, get_batt, 0, false}, + {0x84, get_gps, 0, false}, {0x85, get_bme, 0, false}, + {0x86, get_time, 0, false}, {0x87, set_time, 0, false}, + {0x99, set_flush, 0, false}}; static const uint8_t cmdtablesize = sizeof(table) / sizeof(table[0]); // number of commands in command table diff --git a/src/reset.cpp b/src/reset.cpp index 0fa965d3..94f6626d 100644 --- a/src/reset.cpp +++ b/src/reset.cpp @@ -34,8 +34,15 @@ void do_after_reset(int reason) { RTC_runmode = RUNMODE_POWERCYCLE; break; + case SW_CPU_RESET: // 0x0c Software reset CPU + // keep previous runmode (could be RUNMODE_UPDATE) + break; + case DEEPSLEEP_RESET: // 0x05 Deep Sleep reset digital core RTC_runmode = RUNMODE_WAKEUP; +#if (HAS_LORA) + // to be done: restore LoRaWAN channel configuration and datarate here +#endif break; case SW_RESET: // 0x03 Software reset digital core @@ -46,11 +53,11 @@ void do_after_reset(int reason) { case RTCWDT_SYS_RESET: // 0x09 RTC Watch dog Reset digital core case INTRUSION_RESET: // 0x0a Instrusion tested to reset CPU case TGWDT_CPU_RESET: // 0x0b Time Group reset CPU - case SW_CPU_RESET: // 0x0c Software reset CPU case RTCWDT_CPU_RESET: // 0x0d RTC Watch dog Reset CPU case EXT_CPU_RESET: // 0x0e for APP CPU, reseted by PRO CPU case RTCWDT_RTC_RESET: // 0x10 RTC Watch dog reset digital core and rtc mode default: + RTC_runmode = RUNMODE_POWERCYCLE; break; } @@ -66,6 +73,9 @@ void enter_deepsleep(const int wakeup_sec, const gpio_num_t wakeup_gpio) { #if (HAS_LORA) if (os_queryTimeCriticalJobs(ms2osticks(10000))) return; + + // to be done: save LoRaWAN channel configuration here + #endif // set up power domains diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index d24116fc..dc2fd29d 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -29,8 +29,8 @@ typedef struct { } wifi_ieee80211_packet_t; // using IRAM_:ATTR here to speed up callback function -static IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, - wifi_promiscuous_pkt_type_t type) { +static IRAM_ATTR void +wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type) { const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff; const wifi_ieee80211_packet_t *ipkt = @@ -47,6 +47,7 @@ static IRAM_ATTR void wifi_sniffer_packet_handler(void *buff, // Software-timer driven Wifi channel rotation callback function void switchWifiChannel(TimerHandle_t xTimer) { + configASSERT(xTimer); channel = (channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); @@ -72,15 +73,30 @@ void wifi_sniffer_init(void) { esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL)); ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE)); // no modem power saving - ESP_ERROR_CHECK(esp_wifi_start()); // must be started to be able to switch ch ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter)); // set frame filter ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler)); + ESP_ERROR_CHECK(esp_wifi_start()); //for esp_wifi v3.3 ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode // setup wifi channel rotation timer WifiChanTimer = xTimerCreate("WifiChannelTimer", pdMS_TO_TICKS(cfg.wifichancycle * 10), pdTRUE, (void *)0, switchWifiChannel); + switch_wifi_sniffer(1); +} + +void switch_wifi_sniffer(uint8_t state) { assert(WifiChanTimer); - xTimerStart(WifiChanTimer, 0); + if (state) { + // switch wifi sniffer on + ESP_ERROR_CHECK(esp_wifi_start()); + xTimerStart(WifiChanTimer, 0); + esp_wifi_set_promiscuous(true); + } else { + // switch wifi sniffer off + xTimerStop(WifiChanTimer, 0); + esp_wifi_set_promiscuous(false); + ESP_ERROR_CHECK(esp_wifi_stop()); + macs_wifi = 0; // clear WIFI counter + } } \ No newline at end of file