Merge pull request #97 from cyberman54/master

sync master -> dev
This commit is contained in:
Verkehrsrot 2018-06-12 20:02:03 +02:00 committed by GitHub
commit 442326385b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1221 additions and 2309 deletions

View File

@ -11,11 +11,11 @@
; ---> SELECT TARGET PLATFORM HERE! <--- ; ---> SELECT TARGET PLATFORM HERE! <---
[platformio] [platformio]
;env_default = heltec env_default = heltec
;env_default = ttgov1 ;env_default = ttgov1
;env_default = ttgov2 ;env_default = ttgov2
;env_default = ttgov21 ;env_default = ttgov21
env_default = ttgobeam ;env_default = ttgobeam
;env_default = lopy ;env_default = lopy
;env_default = lopy4 ;env_default = lopy4
;env_default = fipy ;env_default = fipy

View File

@ -5,25 +5,25 @@
#include <driver/adc.h> #include <driver/adc.h>
#include <esp_adc_cal.h> #include <esp_adc_cal.h>
#define DEFAULT_VREF 1100 // to be done: use adc2_vref_to_gpio() to obtain a better estimate #define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
#define NO_OF_SAMPLES 64 // we do multisampling #define NO_OF_SAMPLES 64 // we do multisampling
// Local logging tag // Local logging tag
static const char TAG[] = "main"; static const char TAG[] = "main";
static void print_char_val_type(esp_adc_cal_value_t val_type) static void print_char_val_type(esp_adc_cal_value_t val_type) {
{
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
ESP_LOGI(TAG,"ADC characterization based on Two Point values stored in eFuse"); ESP_LOGI(TAG,
"ADC characterization based on Two Point values stored in eFuse");
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
ESP_LOGI(TAG,"ADC characterization based on reference voltage stored in eFuse"); ESP_LOGI(TAG,
"ADC characterization based on reference voltage stored in eFuse");
} else { } else {
ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); ESP_LOGI(TAG, "ADC characterization based on default reference voltage");
} }
} }
uint16_t read_voltage(void) uint16_t read_voltage(void) {
{
static const adc1_channel_t channel = HAS_BATTERY_PROBE; static const adc1_channel_t channel = HAS_BATTERY_PROBE;
static const adc_atten_t atten = ADC_ATTEN_DB_11; static const adc_atten_t atten = ADC_ATTEN_DB_11;
static const adc_unit_t unit = ADC_UNIT_1; static const adc_unit_t unit = ADC_UNIT_1;
@ -33,8 +33,11 @@ uint16_t read_voltage(void)
ESP_ERROR_CHECK(adc1_config_channel_atten(channel, atten)); ESP_ERROR_CHECK(adc1_config_channel_atten(channel, atten));
// calibrate ADC1 // calibrate ADC1
esp_adc_cal_characteristics_t *adc_chars = (esp_adc_cal_characteristics_t *) calloc(1, sizeof(esp_adc_cal_characteristics_t)); esp_adc_cal_characteristics_t *adc_chars =
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); (esp_adc_cal_characteristics_t *)calloc(
1, sizeof(esp_adc_cal_characteristics_t));
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(
unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
print_char_val_type(val_type); print_char_val_type(val_type);
// multisample ADC1 // multisample ADC1
@ -46,7 +49,8 @@ uint16_t read_voltage(void)
adc_reading /= NO_OF_SAMPLES; adc_reading /= NO_OF_SAMPLES;
// Convert adc_reading to voltage in mV // Convert adc_reading to voltage in mV
uint16_t voltage = (uint16_t) esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); uint16_t voltage =
(uint16_t)esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
#ifdef BATT_FACTOR #ifdef BATT_FACTOR
voltage *= BATT_FACTOR; voltage *= BATT_FACTOR;
#endif #endif

View File

@ -1,4 +1,4 @@
/* switches wifi antenna, if board has switch to select internal and external antenna */ /* switches wifi antenna, if board has switch internal / external antenna */
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
@ -7,10 +7,7 @@
// Local logging tag // Local logging tag
static const char TAG[] = "wifi"; static const char TAG[] = "wifi";
typedef enum { typedef enum { ANTENNA_INT = 0, ANTENNA_EXT } antenna_type_t;
ANTENNA_INT = 0,
ANTENNA_EXT
} antenna_type_t;
void antenna_init(void) { void antenna_init(void) {
gpio_config_t gpioconf = {.pin_bit_mask = 1ull << HAS_ANTENNA_SWITCH, gpio_config_t gpioconf = {.pin_bit_mask = 1ull << HAS_ANTENNA_SWITCH,

View File

@ -14,7 +14,8 @@ https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
#include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove #include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
#include <bt_types.h> #include <bt_types.h>
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] #define BT_BD_ADDR_HEX(addr) \
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
// local Tag for logging // local Tag for logging
static const char TAG[] = "bluetooth"; static const char TAG[] = "bluetooth";
@ -38,45 +39,81 @@ const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
} // bt_addr_t_to_string } // bt_addr_t_to_string
const char *btsig_gap_type(uint32_t gap_type) { const char *btsig_gap_type(uint32_t gap_type) {
switch (gap_type) switch (gap_type) {
{ case 0x01:
case 0x01: return "Flags"; return "Flags";
case 0x02: return "Incomplete List of 16-bit Service Class UUIDs"; case 0x02:
case 0x03: return "Complete List of 16-bit Service Class UUIDs"; return "Incomplete List of 16-bit Service Class UUIDs";
case 0x04: return "Incomplete List of 32-bit Service Class UUIDs"; case 0x03:
case 0x05: return "Complete List of 32-bit Service Class UUIDs"; return "Complete List of 16-bit Service Class UUIDs";
case 0x06: return "Incomplete List of 128-bit Service Class UUIDs"; case 0x04:
case 0x07: return "Complete List of 128-bit Service Class UUIDs"; return "Incomplete List of 32-bit Service Class UUIDs";
case 0x08: return "Shortened Local Name"; case 0x05:
case 0x09: return "Complete Local Name"; return "Complete List of 32-bit Service Class UUIDs";
case 0x0A: return "Tx Power Level"; case 0x06:
case 0x0D: return "Class of Device"; return "Incomplete List of 128-bit Service Class UUIDs";
case 0x0E: return "Simple Pairing Hash C/C-192"; case 0x07:
case 0x0F: return "Simple Pairing Randomizer R/R-192"; return "Complete List of 128-bit Service Class UUIDs";
case 0x10: return "Device ID/Security Manager TK Value"; case 0x08:
case 0x11: return "Security Manager Out of Band Flags"; return "Shortened Local Name";
case 0x12: return "Slave Connection Interval Range"; case 0x09:
case 0x14: return "List of 16-bit Service Solicitation UUIDs"; return "Complete Local Name";
case 0x1F: return "List of 32-bit Service Solicitation UUIDs"; case 0x0A:
case 0x15: return "List of 128-bit Service Solicitation UUIDs"; return "Tx Power Level";
case 0x16: return "Service Data - 16-bit UUID"; case 0x0D:
case 0x20: return "Service Data - 32-bit UUID"; return "Class of Device";
case 0x21: return "Service Data - 128-bit UUID"; case 0x0E:
case 0x22: return "LE Secure Connections Confirmation Value"; return "Simple Pairing Hash C/C-192";
case 0x23: return "LE Secure Connections Random Value"; case 0x0F:
case 0x24: return "URI"; return "Simple Pairing Randomizer R/R-192";
case 0x25: return "Indoor Positioning"; case 0x10:
case 0x26: return "Transport Discovery Data"; return "Device ID/Security Manager TK Value";
case 0x17: return "Public Target Address"; case 0x11:
case 0x18: return "Random Target Address"; return "Security Manager Out of Band Flags";
case 0x19: return "Appearance"; case 0x12:
case 0x1A: return "Advertising Interval"; return "Slave Connection Interval Range";
case 0x1B: return "LE Bluetooth Device Address"; case 0x14:
case 0x1C: return "LE Role"; return "List of 16-bit Service Solicitation UUIDs";
case 0x1D: return "Simple Pairing Hash C-256"; case 0x1F:
case 0x1E: return "Simple Pairing Randomizer R-256"; return "List of 32-bit Service Solicitation UUIDs";
case 0x3D: return "3D Information Data"; case 0x15:
case 0xFF: return "Manufacturer Specific Data"; return "List of 128-bit Service Solicitation UUIDs";
case 0x16:
return "Service Data - 16-bit UUID";
case 0x20:
return "Service Data - 32-bit UUID";
case 0x21:
return "Service Data - 128-bit UUID";
case 0x22:
return "LE Secure Connections Confirmation Value";
case 0x23:
return "LE Secure Connections Random Value";
case 0x24:
return "URI";
case 0x25:
return "Indoor Positioning";
case 0x26:
return "Transport Discovery Data";
case 0x17:
return "Public Target Address";
case 0x18:
return "Random Target Address";
case 0x19:
return "Appearance";
case 0x1A:
return "Advertising Interval";
case 0x1B:
return "LE Bluetooth Device Address";
case 0x1C:
return "LE Role";
case 0x1D:
return "Simple Pairing Hash C-256";
case 0x1E:
return "Simple Pairing Randomizer R-256";
case 0x3D:
return "3D Information Data";
case 0xFF:
return "Manufacturer Specific Data";
default: default:
return "Unknown type"; return "Unknown type";
@ -84,14 +121,14 @@ const char *btsig_gap_type(uint32_t gap_type) {
} // btsig_gap_type } // btsig_gap_type
// using IRAM_:ATTR here to speed up callback function // using IRAM_:ATTR here to speed up callback function
IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event,
{ esp_ble_gap_cb_param_t *param) {
esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param; esp_ble_gap_cb_param_t *p = (esp_ble_gap_cb_param_t *)param;
ESP_LOGD(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv, btsig_gap_type(*p->scan_rst.ble_adv)); ESP_LOGD(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
btsig_gap_type(*p->scan_rst.ble_adv));
switch (event) switch (event) {
{
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
// restart scan // restart scan
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME)); ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
@ -99,26 +136,33 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
case ESP_GAP_BLE_SCAN_RESULT_EVT: case ESP_GAP_BLE_SCAN_RESULT_EVT:
// evaluate scan results // evaluate scan results
if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done if (p->scan_rst.search_evt ==
ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
{ // restart scan { // restart scan
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME)); ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
return; return;
} }
if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device if (p->scan_rst.search_evt ==
ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
{ // evaluate sniffed packet { // evaluate sniffed packet
ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x", BT_BD_ADDR_HEX(p->scan_rst.bda)); ESP_LOGD(TAG, "Device address (bda): %02x:%02x:%02x:%02x:%02x:%02x",
ESP_LOGD(TAG, "Addr_type : %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type)); BT_BD_ADDR_HEX(p->scan_rst.bda));
ESP_LOGD(TAG, "Addr_type : %s",
bt_addr_t_to_string(p->scan_rst.ble_addr_type));
ESP_LOGD(TAG, "RSSI : %d", p->scan_rst.rssi); ESP_LOGD(TAG, "RSSI : %d", p->scan_rst.rssi);
if ((cfg.rssilimit) && (p->scan_rst.rssi < cfg.rssilimit )) { // rssi is negative value if ((cfg.rssilimit) &&
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi, cfg.rssilimit); (p->scan_rst.rssi < cfg.rssilimit)) { // rssi is negative value
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi,
cfg.rssilimit);
break; break;
} }
#ifdef VENDORFILTER #ifdef VENDORFILTER
if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) ||
(p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) {
ESP_LOGD(TAG, "BT device filtered"); ESP_LOGD(TAG, "BT device filtered");
break; break;
} }
@ -130,18 +174,21 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
/* to be improved in vendorfilter if: /* to be improved in vendorfilter if:
// you can search for elements in the payload using the // you can search for elements in the payload using the
// function esp_ble_resolve_adv_data() // function esp_ble_resolve_adv_data()
// //
// Like this, that scans for the "Complete name" (looking inside the payload buffer) // Like this, that scans for the "Complete name" (looking inside the
payload buffer)
// uint8_t len; // uint8_t len;
// uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &len); // uint8_t *data = esp_ble_resolve_adv_data(p->scan_rst.ble_adv,
ESP_BLE_AD_TYPE_NAME_CMPL, &len);
filter BLE devices using their advertisements to get filter alternative to vendor OUI filter BLE devices using their advertisements to get filter alternative to
if vendorfiltering is on, we ... vendor OUI if vendorfiltering is on, we ...
- want to count: mobile phones and tablets - want to count: mobile phones and tablets
- don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines - don't want to count: beacons, peripherals (earphones, headsets,
see printers), cars and machines see
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
http://www.libelium.com/products/meshlium/smartphone-detection/ http://www.libelium.com/products/meshlium/smartphone-detection/
@ -150,9 +197,10 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
https://www.bluetooth.com/specifications/assigned-numbers/baseband https://www.bluetooth.com/specifications/assigned-numbers/baseband
"The Class of Device (CoD) in case of Bluetooth which allows us to differentiate the type of "The Class of Device (CoD) in case of Bluetooth which allows us to
device (smartphone, handsfree, computer, LAN/network AP). With this parameter we can differentiate the type of device (smartphone, handsfree, computer,
differentiate among pedestrians and vehicles." LAN/network AP). With this parameter we can differentiate among
pedestrians and vehicles."
*/ */
@ -164,7 +212,6 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb
} }
} // gap_callback_handler } // gap_callback_handler
esp_err_t register_ble_callback(void) { esp_err_t register_ble_callback(void) {
ESP_LOGI(TAG, "Register GAP callback"); ESP_LOGI(TAG, "Register GAP callback");
@ -172,20 +219,21 @@ esp_err_t register_ble_callback(void) {
// register the scan callback function to the gap module // register the scan callback function to the gap module
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler)); ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler));
static esp_ble_scan_params_t ble_scan_params = static esp_ble_scan_params_t ble_scan_params = {
{
.scan_type = BLE_SCAN_TYPE_PASSIVE, .scan_type = BLE_SCAN_TYPE_PASSIVE,
.own_addr_type = BLE_ADDR_TYPE_RANDOM, .own_addr_type = BLE_ADDR_TYPE_RANDOM,
#ifdef VENDORFILTER #ifdef VENDORFILTER
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR,
// ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used for broadcasting // ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used for broadcasting
// data in broadcast applications (e.g., Beacons), so we don't want them in vendorfilter mode // data in broadcast applications (e.g., Beacons), so we don't want them in
// vendorfilter mode
#else #else
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
#endif #endif
.scan_interval = (uint16_t) (cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec .scan_interval =
(uint16_t)(cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec
.scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec .scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec
}; };
@ -203,11 +251,13 @@ void start_BLEscan(void){
// Initialize BT controller to allocate task and other resource. // Initialize BT controller to allocate task and other resource.
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
bt_cfg.controller_task_stack_size = BLESTACKSIZE; // set BT stack size to value configured in paxcounter.conf bt_cfg.controller_task_stack_size =
BLESTACKSIZE; // set BT stack size to value configured in paxcounter.conf
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg)); ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BTDM)); ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BTDM));
// Init and alloc the resource for bluetooth stack, must be done prior to every bluetooth stuff // Init and alloc the resource for bluetooth stack, must be done prior to
// every bluetooth stuff
ESP_ERROR_CHECK(esp_bluedroid_init()); ESP_ERROR_CHECK(esp_bluedroid_init());
ESP_ERROR_CHECK(esp_bluedroid_enable()); ESP_ERROR_CHECK(esp_bluedroid_enable());

View File

@ -18,7 +18,7 @@ esp_err_t err;
// populate cfg vars with factory settings // populate cfg vars with factory settings
void defaultConfig() { void defaultConfig() {
cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora spreadfactor defined in paxcounter.conf cfg.lorasf = LORASFDEFAULT; // 7-12, initial lora sf, see pacounter.conf
cfg.txpower = 15; // 2-15, lora tx power cfg.txpower = 15; // 2-15, lora tx power
cfg.adrmode = 1; // 0=disabled, 1=enabled cfg.adrmode = 1; // 0=disabled, 1=enabled
cfg.screensaver = 0; // 0=disabled, 1=enabled cfg.screensaver = 0; // 0=disabled, 1=enabled
@ -26,8 +26,11 @@ void defaultConfig() {
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
cfg.rssilimit = 0; // threshold for rssilimiter, negative value! cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2] cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100] cfg.wifichancycle =
cfg.blescantime = BLESCANINTERVAL / 10; // BT channel scan cycle duration [seconds/100], default 1 (= 10ms) WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
cfg.blescantime =
BLESCANINTERVAL /
10; // BT channel scan cycle [seconds/100], default 1 (= 10ms)
cfg.blescan = 1; // 0=disabled, 1=enabled cfg.blescan = 1; // 0=disabled, 1=enabled
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4) cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
cfg.vendorfilter = 1; // 0=disabled, 1=enabled cfg.vendorfilter = 1; // 0=disabled, 1=enabled
@ -64,9 +67,10 @@ void eraseConfig() {
nvs_erase_all(my_handle); nvs_erase_all(my_handle);
nvs_commit(my_handle); nvs_commit(my_handle);
nvs_close(my_handle); nvs_close(my_handle);
ESP_LOGI(TAG, "Done");} ESP_LOGI(TAG, "Done");
else { } else {
ESP_LOGW(TAG, "NVS erase failed"); } ESP_LOGW(TAG, "NVS erase failed");
}
} }
// save current configuration from RAM to NVRAM // save current configuration from RAM to NVRAM
@ -79,52 +83,69 @@ void saveConfig() {
size_t required_size; size_t required_size;
char storedversion[10]; char storedversion[10];
if( nvs_get_str(my_handle, "version", storedversion, &required_size) != ESP_OK || strcmp(storedversion, cfg.version) != 0 ) if (nvs_get_str(my_handle, "version", storedversion, &required_size) !=
ESP_OK ||
strcmp(storedversion, cfg.version) != 0)
nvs_set_str(my_handle, "version", cfg.version); nvs_set_str(my_handle, "version", cfg.version);
if( nvs_get_i8(my_handle, "lorasf", &flash8) != ESP_OK || flash8 != cfg.lorasf ) if (nvs_get_i8(my_handle, "lorasf", &flash8) != ESP_OK ||
flash8 != cfg.lorasf)
nvs_set_i8(my_handle, "lorasf", cfg.lorasf); nvs_set_i8(my_handle, "lorasf", cfg.lorasf);
if( nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK || flash8 != cfg.txpower ) if (nvs_get_i8(my_handle, "txpower", &flash8) != ESP_OK ||
flash8 != cfg.txpower)
nvs_set_i8(my_handle, "txpower", cfg.txpower); nvs_set_i8(my_handle, "txpower", cfg.txpower);
if( nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK || flash8 != cfg.adrmode ) if (nvs_get_i8(my_handle, "adrmode", &flash8) != ESP_OK ||
flash8 != cfg.adrmode)
nvs_set_i8(my_handle, "adrmode", cfg.adrmode); nvs_set_i8(my_handle, "adrmode", cfg.adrmode);
if( nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK || flash8 != cfg.screensaver ) if (nvs_get_i8(my_handle, "screensaver", &flash8) != ESP_OK ||
flash8 != cfg.screensaver)
nvs_set_i8(my_handle, "screensaver", cfg.screensaver); nvs_set_i8(my_handle, "screensaver", cfg.screensaver);
if( nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK || flash8 != cfg.screenon ) if (nvs_get_i8(my_handle, "screenon", &flash8) != ESP_OK ||
flash8 != cfg.screenon)
nvs_set_i8(my_handle, "screenon", cfg.screenon); nvs_set_i8(my_handle, "screenon", cfg.screenon);
if( nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK || flash8 != cfg.countermode ) if (nvs_get_i8(my_handle, "countermode", &flash8) != ESP_OK ||
flash8 != cfg.countermode)
nvs_set_i8(my_handle, "countermode", cfg.countermode); nvs_set_i8(my_handle, "countermode", cfg.countermode);
if( nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK || flash8 != cfg.sendcycle ) if (nvs_get_i8(my_handle, "sendcycle", &flash8) != ESP_OK ||
flash8 != cfg.sendcycle)
nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle); nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle);
if( nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK || flash8 != cfg.wifichancycle ) if (nvs_get_i8(my_handle, "wifichancycle", &flash8) != ESP_OK ||
flash8 != cfg.wifichancycle)
nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle); nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle);
if( nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK || flash8 != cfg.blescantime ) if (nvs_get_i8(my_handle, "blescantime", &flash8) != ESP_OK ||
flash8 != cfg.blescantime)
nvs_set_i8(my_handle, "blescantime", cfg.blescantime); nvs_set_i8(my_handle, "blescantime", cfg.blescantime);
if( nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK || flash8 != cfg.blescan ) if (nvs_get_i8(my_handle, "blescanmode", &flash8) != ESP_OK ||
flash8 != cfg.blescan)
nvs_set_i8(my_handle, "blescanmode", cfg.blescan); nvs_set_i8(my_handle, "blescanmode", cfg.blescan);
if( nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK || flash8 != cfg.wifiant ) if (nvs_get_i8(my_handle, "wifiant", &flash8) != ESP_OK ||
flash8 != cfg.wifiant)
nvs_set_i8(my_handle, "wifiant", cfg.wifiant); nvs_set_i8(my_handle, "wifiant", cfg.wifiant);
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK || flash8 != cfg.vendorfilter ) if (nvs_get_i8(my_handle, "vendorfilter", &flash8) != ESP_OK ||
flash8 != cfg.vendorfilter)
nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter); nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter);
if( nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK || flash8 != cfg.rgblum ) if (nvs_get_i8(my_handle, "rgblum", &flash8) != ESP_OK ||
flash8 != cfg.rgblum)
nvs_set_i8(my_handle, "rgblum", cfg.rgblum); nvs_set_i8(my_handle, "rgblum", cfg.rgblum);
if( nvs_get_i8(my_handle, "gpsmode", &flash8) != ESP_OK || flash8 != cfg.gpsmode ) if (nvs_get_i8(my_handle, "gpsmode", &flash8) != ESP_OK ||
flash8 != cfg.gpsmode)
nvs_set_i8(my_handle, "gpsmode", cfg.gpsmode); nvs_set_i8(my_handle, "gpsmode", cfg.gpsmode);
if( nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK || flash16 != cfg.rssilimit ) if (nvs_get_i16(my_handle, "rssilimit", &flash16) != ESP_OK ||
flash16 != cfg.rssilimit)
nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit); nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit);
err = nvs_commit(my_handle); err = nvs_commit(my_handle);
@ -153,7 +174,8 @@ void loadConfig() {
open_storage(); open_storage();
if (err != ESP_OK) { if (err != ESP_OK) {
ESP_LOGW(TAG, "Error (%d) opening NVS handle, storing defaults", err); ESP_LOGW(TAG, "Error (%d) opening NVS handle, storing defaults", err);
saveConfig(); } // saves factory settings to NVRAM saveConfig();
} // saves factory settings to NVRAM
else { else {
int8_t flash8 = 0; int8_t flash8 = 0;
int16_t flash16 = 0; int16_t flash16 = 0;
@ -164,7 +186,8 @@ void loadConfig() {
nvs_get_str(my_handle, "version", cfg.version, &required_size); nvs_get_str(my_handle, "version", cfg.version, &required_size);
ESP_LOGI(TAG, "NVRAM settings version = %s", cfg.version); ESP_LOGI(TAG, "NVRAM settings version = %s", cfg.version);
if (strcmp(cfg.version, PROGVERSION)) { if (strcmp(cfg.version, PROGVERSION)) {
ESP_LOGI(TAG, "migrating NVRAM settings to new version %s", PROGVERSION); ESP_LOGI(TAG, "migrating NVRAM settings to new version %s",
PROGVERSION);
nvs_close(my_handle); nvs_close(my_handle);
migrateVersion(); migrateVersion();
} }

View File

@ -68,6 +68,7 @@ extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim; extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
extern std::set<uint16_t> macs; extern std::set<uint16_t> macs;
extern hw_timer_t * channelSwitch; // hardware timer used for wifi channel switching extern hw_timer_t
*channelSwitch; // hardware timer used for wifi channel switching
extern xref2u1_t rcmd_data; // buffer for rcommand results size extern xref2u1_t rcmd_data; // buffer for rcommand results size
extern u1_t rcmd_data_size; // buffer for rcommand results size extern u1_t rcmd_data_size; // buffer for rcommand results size

View File

@ -28,8 +28,7 @@ void gps_loop(void * pvParameters) {
while (1) { while (1) {
if (cfg.gpsmode) if (cfg.gpsmode) {
{
#if defined GPS_SERIAL #if defined GPS_SERIAL
// serial connect to GPS device // serial connect to GPS device

View File

@ -19,6 +19,4 @@
#define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN #define RST LMIC_UNUSED_PIN // connected to ESP32 RST/EN
#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0 #define DIO0 GPIO_NUM_26 // ESP32 GPIO26 <-> HPD13A IO0
#define DIO1 GPIO_NUM_32 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !! #define DIO1 GPIO_NUM_32 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !!
#define DIO2 \ #define DIO2 LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // not needed for LoRa
LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not
// necessary for LoRa, only FSK

View File

@ -5,13 +5,15 @@
* and rename this file to src/loraconf.h * and rename this file to src/loraconf.h
* *
* Note that DEVEUI, APPEUI and APPKEY should all be specified in MSB format. * Note that DEVEUI, APPEUI and APPKEY should all be specified in MSB format.
* (This is different from standard LMIC-Arduino which expects DEVEUI and APPEUI in LSB format.) * (This is different from standard LMIC-Arduino which expects DEVEUI and APPEUI
* in LSB format.)
* Set your DEVEUI here, if you have one. You can leave this untouched, * Set your DEVEUI here, if you have one. You can leave this untouched,
* then the DEVEUI will be generated during runtime from device's MAC adress * then the DEVEUI will be generated during runtime from device's MAC adress
* and will be displayed on device's screen as well as on serial console. * and will be displayed on device's screen as well as on serial console.
* *
* NOTE: Use MSB format (as displayed in TTN console, so you can cut & paste from there) * NOTE: Use MSB format (as displayed in TTN console, so you can cut & paste
* from there)
* For TTN, APPEUI in MSB format always starts with 0x70, 0xB3, 0xD5 * For TTN, APPEUI in MSB format always starts with 0x70, 0xB3, 0xD5
* *
* Note: If using a board with Microchip 24AA02E64 Uinique ID for deveui, * Note: If using a board with Microchip 24AA02E64 Uinique ID for deveui,
@ -25,4 +27,5 @@ static const u1_t DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static const u1_t APPEUI[8] = {0x70, 0xB3, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00}; static const u1_t APPEUI[8] = {0x70, 0xB3, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00};
static const u1_t APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const u1_t APPKEY[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

View File

@ -211,8 +211,7 @@ void onEvent(ev_t ev) {
case EV_JOINED: case EV_JOINED:
strcpy_P(buff, PSTR("JOINED")); strcpy_P(buff, PSTR("JOINED"));
sprintf(display_lora, sprintf(display_lora, " "); // clear previous lmic status
" "); // clear previous lmic status message from display
// set data rate adaptation // set data rate adaptation
LMIC_setAdrMode(cfg.adrmode); LMIC_setAdrMode(cfg.adrmode);
@ -229,8 +228,7 @@ void onEvent(ev_t ev) {
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK")
: PSTR("TX COMPLETE")); : PSTR("TX COMPLETE"));
sprintf(display_lora, sprintf(display_lora, " "); // clear previous lmic status
" "); // clear previous lmic status message from display
if (LMIC.dataLen) { if (LMIC.dataLen) {
ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d",

View File

@ -9,13 +9,16 @@
// Local logging tag // Local logging tag
static const char TAG[] = "wifi"; static const char TAG[] = "wifi";
static wifi_country_t wifi_country = {.cc=WIFI_MY_COUNTRY, .schan=WIFI_CHANNEL_MIN, .nchan=WIFI_CHANNEL_MAX, .policy=WIFI_COUNTRY_POLICY_MANUAL}; static wifi_country_t wifi_country = {.cc = WIFI_MY_COUNTRY,
.schan = WIFI_CHANNEL_MIN,
.nchan = WIFI_CHANNEL_MAX,
.policy = WIFI_COUNTRY_POLICY_MANUAL};
// globals // globals
uint16_t salt; uint16_t salt;
uint16_t reset_salt(void) { uint16_t reset_salt(void) {
salt = random(65536); // get new 16bit random for salting hashes and set global salt var salt = random(65536); // get new 16bit random for salting hashes
return salt; return salt;
} }
@ -28,23 +31,30 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
// only last 3 MAC Address bytes are used for MAC address anonymization // 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 // but since it's uint32 we take 4 bytes to avoid 1st value to be 0
addr2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[3] << 8 ) | ( (uint32_t)paddr[4] << 16 ) | ( (uint32_t)paddr[5] << 24 ); addr2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[3] << 8) |
((uint32_t)paddr[4] << 16) | ((uint32_t)paddr[5] << 24);
#ifdef VENDORFILTER #ifdef VENDORFILTER
vendor2int = ( (uint32_t)paddr[2] ) | ( (uint32_t)paddr[1] << 8 ) | ( (uint32_t)paddr[0] << 16 ); vendor2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[1] << 8) |
((uint32_t)paddr[0] << 16);
// use OUI vendor filter list only on Wifi, not on BLE // use OUI vendor filter list only on Wifi, not on BLE
if ( (sniff_type==MAC_SNIFF_BLE) || std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end() ) if ((sniff_type == MAC_SNIFF_BLE) ||
{ std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end()) {
#endif #endif
// salt and hash MAC, and if new unique one, store identifier in container and increment counter on display // salt and hash MAC, and if new unique one, store identifier in container
// and increment counter on display
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization // https://en.wikipedia.org/wiki/MAC_Address_Anonymization
addr2int += (uint32_t)salt; // add 16-bit salt to pseudo MAC addr2int += (uint32_t)salt; // add 16-bit salt to pseudo MAC
snprintf(buff, sizeof(buff), "%08X", addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string snprintf(
hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container buff, sizeof(buff), "%08X",
auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique addr2int); // convert unsigned 32-bit salted MAC to 8 digit hex string
added = newmac.second ? true:false; // true if hashed MAC is unique in container 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
added = newmac.second ? true
: false; // true if hashed MAC is unique in container
// Count only if MAC was not yet seen // Count only if MAC was not yet seen
if (added) { if (added) {
@ -66,32 +76,39 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
} }
// Log scan result // Log scan result
ESP_LOGI(TAG, "%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d -> %d Bytes left", ESP_LOGI(TAG,
"%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d -> "
"%d Bytes left",
added ? "new " : "known", added ? "new " : "known",
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH", sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff,
rssi, buff, hashedmac, macs_wifi, macs_ble, hashedmac, macs_wifi, macs_ble, ESP.getFreeHeap());
ESP.getFreeHeap());
#ifdef VENDORFILTER #ifdef VENDORFILTER
} else { } else {
// Very noisy // Very noisy
// ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X", paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]); // ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X",
// paddr[0],paddr[1],paddr[2],paddr[3],paddr[5],paddr[5]);
} }
#endif #endif
// True if MAC WiFi/BLE was new // True if MAC WiFi/BLE was new
return added; // function returns bool if a new and unique Wifi or BLE mac was counted (true) or not (false) return added; // function returns bool if a new and unique Wifi or BLE mac was
// counted (true) or not (false)
} }
void wifi_sniffer_init(void) { void wifi_sniffer_init(void) {
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
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 = {.filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames 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_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(
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM esp_wifi_set_country(&wifi_country)); // set locales for RF and channels
ESP_ERROR_CHECK(
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_mode(WIFI_MODE_NULL));
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter ESP_ERROR_CHECK(
esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler)); ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler));
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
} }
@ -101,16 +118,19 @@ void wifi_sniffer_set_channel(uint8_t channel) {
} }
// using IRAM_:ATTR here to speed up callback function // using IRAM_:ATTR here to speed up callback function
IRAM_ATTR void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type) { 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_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload; const wifi_ieee80211_packet_t *ipkt =
(wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr; const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
if ((cfg.rssilimit) && (ppkt->rx_ctrl.rssi < cfg.rssilimit )) { // rssi is negative value if ((cfg.rssilimit) &&
ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, cfg.rssilimit); (ppkt->rx_ctrl.rssi < cfg.rssilimit)) { // rssi is negative value
ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi,
cfg.rssilimit);
} else { } else {
uint8_t *p = (uint8_t *)hdr->addr2; uint8_t *p = (uint8_t *)hdr->addr2;
mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI); mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI);
} }
} }

View File

@ -1,6 +1,5 @@
/* /*
ESP32-Paxcounter
Copyright 2018 Oliver Brandmueller <ob@sysadm.in> Copyright 2018 Oliver Brandmueller <ob@sysadm.in>
Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de> Copyright 2018 Klaus Wilting <verkehrsrot@arcor.de>

View File

@ -10,10 +10,7 @@
//--- Declarations --- //--- Declarations ---
enum led_states { enum led_states { LED_OFF, LED_ON };
LED_OFF,
LED_ON
};
#if defined(CFG_eu868) #if defined(CFG_eu868)
const char lora_datarate[] = {"1211100908077BFSNA"}; const char lora_datarate[] = {"1211100908077BFSNA"};
@ -28,7 +25,6 @@ void reset_counters(void);
void blink_LED(uint16_t set_color, uint16_t set_blinkduration); void blink_LED(uint16_t set_color, uint16_t set_blinkduration);
void led_loop(void); void led_loop(void);
// defined in blescan.cpp // defined in blescan.cpp
#ifdef BLECOUNTER #ifdef BLECOUNTER
void start_BLEscan(void); void start_BLEscan(void);

View File

@ -1,6 +1,7 @@
// remote command interpreter // remote command interpreter
// parses multiple number of command / value pairs from LoRaWAN remote command port (RCMDPORT) // parses multiple number of command / value pairs from LoRaWAN remote command
// checks commands and executes each command with 1 argument per command // port (RCMDPORT) checks commands and executes each command with 1 argument per
// command
// Basic Config // Basic Config
#include "globals.h" #include "globals.h"
@ -31,18 +32,22 @@ typedef struct {
// function sends result of get commands to LoRaWAN network // function sends result of get commands to LoRaWAN network
void do_transmit(osjob_t *j) { void do_transmit(osjob_t *j) {
// check if there is a pending TX/RX job running, if yes then reschedule transmission // check if there is a pending TX/RX job running, if yes then reschedule
// transmission
if (LMIC.opmode & OP_TXRXPEND) { if (LMIC.opmode & OP_TXRXPEND) {
ESP_LOGI(TAG, "LoRa busy, rescheduling"); ESP_LOGI(TAG, "LoRa busy, rescheduling");
sprintf(display_lmic, "LORA BUSY"); sprintf(display_lmic, "LORA BUSY");
os_setTimedCallback(&rcmdjob, os_getTime()+sec2osticks(RETRANSMIT_RCMD), do_transmit); os_setTimedCallback(&rcmdjob, os_getTime() + sec2osticks(RETRANSMIT_RCMD),
do_transmit);
} }
LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size, 0); // send data unconfirmed on RCMD Port LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size,
0); // send data unconfirmed on RCMD Port
ESP_LOGI(TAG, "%d bytes queued to send", rcmd_data_size); ESP_LOGI(TAG, "%d bytes queued to send", rcmd_data_size);
sprintf(display_lmic, "PACKET QUEUED"); sprintf(display_lmic, "PACKET QUEUED");
} }
// help function to transmit result of get commands, since callback function do_transmit() cannot have params // help function to transmit result of get commands, since callback function
// do_transmit() cannot have params
void transmit(xref2u1_t mydata, u1_t mydata_size) { void transmit(xref2u1_t mydata, u1_t mydata_size) {
rcmd_data = mydata; rcmd_data = mydata;
rcmd_data_size = mydata_size; rcmd_data_size = mydata_size;
@ -51,26 +56,48 @@ void transmit(xref2u1_t mydata, u1_t mydata_size){
// help function to assign LoRa datarates to numeric spreadfactor values // help function to assign LoRa datarates to numeric spreadfactor values
void switch_lora(uint8_t sf, uint8_t tx) { void switch_lora(uint8_t sf, uint8_t tx) {
if ( tx > 20 ) return; if (tx > 20)
return;
cfg.txpower = tx; cfg.txpower = tx;
switch (sf) { switch (sf) {
case 7: LMIC_setDrTxpow(DR_SF7,tx); cfg.lorasf=sf; break; case 7:
case 8: LMIC_setDrTxpow(DR_SF8,tx); cfg.lorasf=sf; break; LMIC_setDrTxpow(DR_SF7, tx);
case 9: LMIC_setDrTxpow(DR_SF9,tx); cfg.lorasf=sf; break; cfg.lorasf = sf;
case 10: LMIC_setDrTxpow(DR_SF10,tx); cfg.lorasf=sf; break; break;
case 8:
LMIC_setDrTxpow(DR_SF8, tx);
cfg.lorasf = sf;
break;
case 9:
LMIC_setDrTxpow(DR_SF9, tx);
cfg.lorasf = sf;
break;
case 10:
LMIC_setDrTxpow(DR_SF10, tx);
cfg.lorasf = sf;
break;
case 11: case 11:
#if defined(CFG_eu868) #if defined(CFG_eu868)
LMIC_setDrTxpow(DR_SF11,tx); cfg.lorasf=sf; break; LMIC_setDrTxpow(DR_SF11, tx);
cfg.lorasf = sf;
break;
#elif defined(CFG_us915) #elif defined(CFG_us915)
LMIC_setDrTxpow(DR_SF11CR,tx); cfg.lorasf=sf; break; LMIC_setDrTxpow(DR_SF11CR, tx);
cfg.lorasf = sf;
break;
#endif #endif
case 12: case 12:
#if defined(CFG_eu868) #if defined(CFG_eu868)
LMIC_setDrTxpow(DR_SF12,tx); cfg.lorasf=sf; break; LMIC_setDrTxpow(DR_SF12, tx);
cfg.lorasf = sf;
break;
#elif defined(CFG_us915) #elif defined(CFG_us915)
LMIC_setDrTxpow(DR_SF12CR,tx); cfg.lorasf=sf; break; LMIC_setDrTxpow(DR_SF12CR, tx);
cfg.lorasf = sf;
break;
#endif #endif
default: break; default:
break;
} }
} }
@ -80,7 +107,9 @@ void set_reset(uint8_t val) {
case 0: // restart device case 0: // restart device
ESP_LOGI(TAG, "Remote command: restart device"); ESP_LOGI(TAG, "Remote command: restart device");
sprintf(display_lora, "Reset pending"); sprintf(display_lora, "Reset pending");
vTaskDelay(10000/portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server vTaskDelay(
10000 /
portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
esp_restart(); esp_restart();
break; break;
case 1: // reset MAC counter case 1: // reset MAC counter
@ -104,23 +133,28 @@ void set_rssi(uint8_t val) {
void set_sendcycle(uint8_t val) { void set_sendcycle(uint8_t val) {
cfg.sendcycle = val; cfg.sendcycle = val;
ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds", cfg.sendcycle*2); ESP_LOGI(TAG, "Remote command: set payload send cycle to %d seconds",
cfg.sendcycle * 2);
}; };
void set_wifichancycle(uint8_t val) { void set_wifichancycle(uint8_t val) {
cfg.wifichancycle = val; cfg.wifichancycle = val;
// modify wifi channel rotation IRQ // modify wifi channel rotation IRQ
timerAlarmWrite(channelSwitch, cfg.wifichancycle * 10000, true); // reload interrupt after each trigger of channel switch cycle timerAlarmWrite(
ESP_LOGI(TAG, "Remote command: set Wifi channel switch interval to %.1f seconds", cfg.wifichancycle/float(100)); channelSwitch, cfg.wifichancycle * 10000,
true); // reload interrupt after each trigger of channel switch cycle
ESP_LOGI(TAG,
"Remote command: set Wifi channel switch interval to %.1f seconds",
cfg.wifichancycle / float(100));
}; };
void set_blescantime(uint8_t val) { void set_blescantime(uint8_t val) {
cfg.blescantime = val; cfg.blescantime = val;
ESP_LOGI(TAG, "Remote command: set BLE scan time to %.1f seconds", cfg.blescantime/float(100)); ESP_LOGI(TAG, "Remote command: set BLE scan time to %.1f seconds",
cfg.blescantime / float(100));
#ifdef BLECOUNTER #ifdef BLECOUNTER
// stop & restart BLE scan task to apply new parameter // stop & restart BLE scan task to apply new parameter
if (cfg.blescan) if (cfg.blescan) {
{
stop_BLEscan(); stop_BLEscan();
start_BLEscan(); start_BLEscan();
} }
@ -147,24 +181,36 @@ void set_countmode(uint8_t val) {
void set_screensaver(uint8_t val) { void set_screensaver(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set screen saver to %s ", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.screensaver = val; break; case 1:
default: cfg.screensaver = 0; break; cfg.screensaver = val;
break;
default:
cfg.screensaver = 0;
break;
} }
}; };
void set_display(uint8_t val) { void set_display(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set screen to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.screenon = val; break; case 1:
default: cfg.screenon = 0; break; cfg.screenon = val;
break;
default:
cfg.screenon = 0;
break;
} }
}; };
void set_gps(uint8_t val) { void set_gps(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set GPS to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set GPS to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.gpsmode = val; break; case 1:
default: cfg.gpsmode = 0; break; cfg.gpsmode = val;
break;
default:
cfg.gpsmode = 0;
break;
} }
}; };
@ -176,8 +222,12 @@ void set_lorasf(uint8_t val) {
void set_loraadr(uint8_t val) { void set_loraadr(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.adrmode = val; break; case 1:
default: cfg.adrmode = 0; break; cfg.adrmode = val;
break;
default:
cfg.adrmode = 0;
break;
} }
LMIC_setAdrMode(cfg.adrmode); LMIC_setAdrMode(cfg.adrmode);
}; };
@ -202,10 +252,15 @@ void set_blescan(uint8_t val) {
}; };
void set_wifiant(uint8_t val) { void set_wifiant(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s", val ? "external" : "internal"); ESP_LOGI(TAG, "Remote command: set Wifi antenna to %s",
val ? "external" : "internal");
switch (val) { switch (val) {
case 1: cfg.wifiant = val; break; case 1:
default: cfg.wifiant = 0; break; cfg.wifiant = val;
break;
default:
cfg.wifiant = 0;
break;
} }
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
antenna_select(cfg.wifiant); antenna_select(cfg.wifiant);
@ -213,10 +268,15 @@ void set_wifiant(uint8_t val) {
}; };
void set_vendorfilter(uint8_t val) { void set_vendorfilter(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s", val ? "on" : "off"); ESP_LOGI(TAG, "Remote command: set vendorfilter mode to %s",
val ? "on" : "off");
switch (val) { switch (val) {
case 1: cfg.vendorfilter = val; break; case 1:
default: cfg.vendorfilter = 0; break; cfg.vendorfilter = val;
break;
default:
cfg.vendorfilter = 0;
break;
} }
}; };
@ -262,7 +322,9 @@ void get_gps (uint8_t val) {
#ifdef HAS_GPS #ifdef HAS_GPS
gps_read(); gps_read();
transmit((byte *)&gps_status, sizeof(gps_status)); transmit((byte *)&gps_status, sizeof(gps_status));
ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude); ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u",
gps_status.latitude / 1000000, gps_status.longitude / 1000000,
gps_status.satellites, gps_status.hdop, gps_status.altitude);
#else #else
ESP_LOGE(TAG, "GPS not present"); ESP_LOGE(TAG, "GPS not present");
#endif #endif
@ -271,40 +333,33 @@ void get_gps (uint8_t val) {
// assign previously defined functions to set of numeric remote commands // assign previously defined functions to set of numeric remote commands
// format: opcode, function, flag (1 = do make settings persistent / 0 = don't) // format: opcode, function, flag (1 = do make settings persistent / 0 = don't)
// //
cmd_t table[] = { cmd_t table[] = {{0x01, set_rssi, true}, {0x02, set_countmode, true},
{0x01, set_rssi, true}, {0x03, set_gps, true}, {0x04, set_display, true},
{0x02, set_countmode, true}, {0x05, set_lorasf, true}, {0x06, set_lorapower, true},
{0x03, set_gps, true}, {0x07, set_loraadr, true}, {0x08, set_screensaver, true},
{0x04, set_display, true}, {0x09, set_reset, false}, {0x0a, set_sendcycle, true},
{0x05, set_lorasf, true}, {0x0b, set_wifichancycle, true}, {0x0c, set_blescantime, true},
{0x06, set_lorapower, true}, {0x0d, set_vendorfilter, false}, {0x0e, set_blescan, true},
{0x07, set_loraadr, true}, {0x0f, set_wifiant, true}, {0x10, set_rgblum, true},
{0x08, set_screensaver, true}, {0x80, get_config, false}, {0x81, get_uptime, false},
{0x09, set_reset, false}, {0x82, get_cputemp, false}, {0x83, get_voltage, false},
{0x0a, set_sendcycle, true}, {0x84, get_gps, false}};
{0x0b, set_wifichancycle, true},
{0x0c, set_blescantime, true},
{0x0d, set_vendorfilter, false},
{0x0e, set_blescan, true},
{0x0f, set_wifiant, true},
{0x10, set_rgblum, true},
{0x80, get_config, false},
{0x81, get_uptime, false},
{0x82, get_cputemp, false},
{0x83, get_voltage, false},
{0x84, get_gps, false}
};
// check and execute remote command // check and execute remote command
void rcommand(uint8_t cmd, uint8_t arg) { void rcommand(uint8_t cmd, uint8_t arg) {
int i = sizeof(table) / sizeof(table[0]); // number of commands in command table int i =
sizeof(table) / sizeof(table[0]); // number of commands in command table
bool store_flag = false; bool store_flag = false;
while (i--) { while (i--) {
if (cmd == table[i].nam) { // check if valid command if (cmd == table[i].nam) { // check if valid command
table[i].func(arg); // then execute assigned function table[i].func(arg); // then execute assigned function
if ( table[i].store ) store_flag = true; // set save flag if function needs to store configuration if (table[i].store)
store_flag =
true; // set save flag if function needs to store configuration
break; // exit check loop, since command was found break; // exit check loop, since command was found
} }
} }
if (store_flag) saveConfig(); // if save flag is set: store new configuration in NVS to make it persistent if (store_flag)
saveConfig(); // if save flag is set: store new configuration in NVS to make
// it persistent
} }

View File

@ -6,8 +6,7 @@
// RGB Led instance // RGB Led instance
SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED); SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED);
float rgb_CalcColor(float p, float q, float t) float rgb_CalcColor(float p, float q, float t) {
{
if (t < 0.0f) if (t < 0.0f)
t += 1.0f; t += 1.0f;
if (t > 1.0f) if (t > 1.0f)
@ -30,19 +29,15 @@ float rgb_CalcColor(float p, float q, float t)
// HslColor using H, S, L values (0.0 - 1.0) // HslColor using H, S, L values (0.0 - 1.0)
// L should be limited to between (0.0 - 0.5) // L should be limited to between (0.0 - 0.5)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
RGBColor rgb_hsl2rgb(float h, float s, float l) RGBColor rgb_hsl2rgb(float h, float s, float l) {
{
RGBColor RGB_color; RGBColor RGB_color;
float r; float r;
float g; float g;
float b; float b;
if (s == 0.0f || l == 0.0f) if (s == 0.0f || l == 0.0f) {
{
r = g = b = l; // achromatic or black r = g = b = l; // achromatic or black
} } else {
else
{
float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s); float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
float p = 2.0f * l - q; float p = 2.0f * l - q;
r = rgb_CalcColor(p, q, h + 1.0f / 3.0f); r = rgb_CalcColor(p, q, h + 1.0f / 3.0f);

View File

@ -19,8 +19,7 @@
#define COLOR_WHITE 360 #define COLOR_WHITE 360
#define COLOR_NONE 999 #define COLOR_NONE 999
struct RGBColor struct RGBColor {
{
uint8_t R; uint8_t R;
uint8_t G; uint8_t G;
uint8_t B; uint8_t B;

View File

@ -40,7 +40,8 @@ uint32_t rokkit(const char * data, int len) {
uint32_t hash, tmp; uint32_t hash, tmp;
int rem; int rem;
if (len <= 0 || data == 0) return 0; if (len <= 0 || data == 0)
return 0;
hash = len; hash = len;
rem = len & 3; rem = len & 3;
len >>= 2; len >>= 2;
@ -57,16 +58,19 @@ uint32_t rokkit(const char * data, int len) {
/* Handle end cases */ /* Handle end cases */
switch (rem) { switch (rem) {
case 3: hash += *((uint16_t*)data); case 3:
hash += *((uint16_t *)data);
hash ^= hash << 16; hash ^= hash << 16;
hash ^= ((signed char)data[2]) << 18; hash ^= ((signed char)data[2]) << 18;
hash += hash >> 11; hash += hash >> 11;
break; break;
case 2: hash += *((uint16_t*)data); case 2:
hash += *((uint16_t *)data);
hash ^= hash << 11; hash ^= hash << 11;
hash += hash >> 17; hash += hash >> 17;
break; break;
case 1: hash += (signed char)*data; case 1:
hash += (signed char)*data;
hash ^= hash << 10; hash ^= hash << 10;
hash += hash >> 1; hash += hash >> 1;
} }

File diff suppressed because it is too large Load Diff