commit
28f0396185
108
.clang-format
Normal file
108
.clang-format
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
@ -5,52 +5,57 @@
|
|||||||
#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 \
|
||||||
#define NO_OF_SAMPLES 64 // we do multisampling
|
1100 // to be done: use adc2_vref_to_gpio() to obtain a better estimate
|
||||||
|
#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,
|
||||||
ESP_LOGI(TAG,"ADC characterization based on Two Point values stored in eFuse");
|
"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,
|
||||||
} else {
|
"ADC characterization based on reference voltage stored in eFuse");
|
||||||
ESP_LOGI(TAG,"ADC characterization based on default reference voltage");
|
} else {
|
||||||
}
|
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;
|
|
||||||
|
|
||||||
//configure ADC1
|
// configure ADC1
|
||||||
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
|
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
|
||||||
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(
|
||||||
print_char_val_type(val_type);
|
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);
|
||||||
|
|
||||||
//multisample ADC1
|
// multisample ADC1
|
||||||
uint32_t adc_reading = 0;
|
uint32_t adc_reading = 0;
|
||||||
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
||||||
adc_reading += adc1_get_raw(channel);
|
adc_reading += adc1_get_raw(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
||||||
#ifdef BATT_FACTOR
|
(uint16_t)esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);
|
||||||
voltage *= BATT_FACTOR;
|
#ifdef BATT_FACTOR
|
||||||
#endif
|
voltage *= BATT_FACTOR;
|
||||||
ESP_LOGI(TAG,"Raw: %d / Voltage: %dmV", adc_reading, voltage);
|
#endif
|
||||||
return voltage;
|
ESP_LOGI(TAG, "Raw: %d / Voltage: %dmV", adc_reading, voltage);
|
||||||
|
return voltage;
|
||||||
}
|
}
|
||||||
#endif // HAS_BATTERY_PROBE
|
#endif // HAS_BATTERY_PROBE
|
@ -1,4 +1,5 @@
|
|||||||
/* switches wifi antenna, if board has switch to select internal and external antenna */
|
/* switches wifi antenna, if board has switch to select internal and external
|
||||||
|
* antenna */
|
||||||
|
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
|
|
||||||
@ -7,35 +8,32 @@
|
|||||||
// 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,
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
.intr_type = GPIO_INTR_DISABLE};
|
.intr_type = GPIO_INTR_DISABLE};
|
||||||
gpio_config(&gpioconf);
|
gpio_config(&gpioconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void antenna_select (const uint8_t _ant) {
|
void antenna_select(const uint8_t _ant) {
|
||||||
if (HAS_ANTENNA_SWITCH < 32) {
|
if (HAS_ANTENNA_SWITCH < 32) {
|
||||||
if (_ant == ANTENNA_EXT) {
|
if (_ant == ANTENNA_EXT) {
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH);
|
GPIO_REG_WRITE(GPIO_OUT_W1TS_REG, 1 << HAS_ANTENNA_SWITCH);
|
||||||
} else {
|
} else {
|
||||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_REG, 1 << HAS_ANTENNA_SWITCH);
|
GPIO_REG_WRITE(GPIO_OUT_W1TC_REG, 1 << HAS_ANTENNA_SWITCH);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_ant == ANTENNA_EXT) {
|
if (_ant == ANTENNA_EXT) {
|
||||||
GPIO_REG_WRITE(GPIO_OUT1_W1TS_REG, 1 << (HAS_ANTENNA_SWITCH & 31));
|
GPIO_REG_WRITE(GPIO_OUT1_W1TS_REG, 1 << (HAS_ANTENNA_SWITCH & 31));
|
||||||
} else {
|
} else {
|
||||||
GPIO_REG_WRITE(GPIO_OUT1_W1TC_REG, 1 << (HAS_ANTENNA_SWITCH & 31));
|
GPIO_REG_WRITE(GPIO_OUT1_W1TC_REG, 1 << (HAS_ANTENNA_SWITCH & 31));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Wifi Antenna switched to %s", _ant ? "external" : "internal");
|
ESP_LOGI(TAG, "Wifi Antenna switched to %s", _ant ? "external" : "internal");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
403
src/blecsan.cpp
403
src/blecsan.cpp
@ -8,13 +8,14 @@ https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
// Bluetooth specific includes
|
// Bluetooth specific includes
|
||||||
|
#include <bt_types.h>
|
||||||
|
#include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
|
||||||
#include <esp_bt.h>
|
#include <esp_bt.h>
|
||||||
#include <esp_bt_main.h>
|
#include <esp_bt_main.h>
|
||||||
#include <esp_gap_ble_api.h>
|
#include <esp_gap_ble_api.h>
|
||||||
#include <esp_blufi_api.h> // needed for BLE_ADDR types, do not remove
|
|
||||||
#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";
|
||||||
@ -23,208 +24,256 @@ static const char TAG[] = "bluetooth";
|
|||||||
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type);
|
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type);
|
||||||
|
|
||||||
const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
|
const char *bt_addr_t_to_string(esp_ble_addr_type_t type) {
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case BLE_ADDR_TYPE_PUBLIC:
|
case BLE_ADDR_TYPE_PUBLIC:
|
||||||
return "BLE_ADDR_TYPE_PUBLIC";
|
return "BLE_ADDR_TYPE_PUBLIC";
|
||||||
case BLE_ADDR_TYPE_RANDOM:
|
case BLE_ADDR_TYPE_RANDOM:
|
||||||
return "BLE_ADDR_TYPE_RANDOM";
|
return "BLE_ADDR_TYPE_RANDOM";
|
||||||
case BLE_ADDR_TYPE_RPA_PUBLIC:
|
case BLE_ADDR_TYPE_RPA_PUBLIC:
|
||||||
return "BLE_ADDR_TYPE_RPA_PUBLIC";
|
return "BLE_ADDR_TYPE_RPA_PUBLIC";
|
||||||
case BLE_ADDR_TYPE_RPA_RANDOM:
|
case BLE_ADDR_TYPE_RPA_RANDOM:
|
||||||
return "BLE_ADDR_TYPE_RPA_RANDOM";
|
return "BLE_ADDR_TYPE_RPA_RANDOM";
|
||||||
default:
|
default:
|
||||||
return "Unknown addr_t";
|
return "Unknown addr_t";
|
||||||
}
|
}
|
||||||
} // 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:
|
||||||
default:
|
return "Service Data - 16-bit UUID";
|
||||||
return "Unknown type";
|
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:
|
||||||
|
return "Unknown 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));
|
|
||||||
|
|
||||||
switch (event)
|
ESP_LOGD(TAG, "BT payload rcvd -> type: 0x%.2x -> %s", *p->scan_rst.ble_adv,
|
||||||
{
|
btsig_gap_type(*p->scan_rst.ble_adv));
|
||||||
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
|
||||||
// restart scan
|
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
|
||||||
// evaluate scan results
|
|
||||||
if ( p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
|
|
||||||
{ // restart scan
|
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
|
|
||||||
{ // 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, "Addr_type : %s", bt_addr_t_to_string(p->scan_rst.ble_addr_type));
|
|
||||||
ESP_LOGD(TAG, "RSSI : %d", p->scan_rst.rssi);
|
|
||||||
|
|
||||||
if ((cfg.rssilimit) && (p->scan_rst.rssi < cfg.rssilimit )) { // rssi is negative value
|
switch (event) {
|
||||||
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi, cfg.rssilimit);
|
case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
|
||||||
break;
|
// restart scan
|
||||||
}
|
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef VENDORFILTER
|
case ESP_GAP_BLE_SCAN_RESULT_EVT:
|
||||||
|
// evaluate scan results
|
||||||
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.search_evt ==
|
||||||
ESP_LOGD(TAG, "BT device filtered");
|
ESP_GAP_SEARCH_INQ_CMPL_EVT) // Inquiry complete, scan is done
|
||||||
break;
|
{ // restart scan
|
||||||
}
|
ESP_ERROR_CHECK(esp_ble_gap_start_scanning(BLESCANTIME));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
if (p->scan_rst.search_evt ==
|
||||||
|
ESP_GAP_SEARCH_INQ_RES_EVT) // Inquiry result for a peer device
|
||||||
|
{ // 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, "Addr_type : %s",
|
||||||
|
bt_addr_t_to_string(p->scan_rst.ble_addr_type));
|
||||||
|
ESP_LOGD(TAG, "RSSI : %d", p->scan_rst.rssi);
|
||||||
|
|
||||||
// add this device and show new count total if it was not previously added
|
if ((cfg.rssilimit) &&
|
||||||
mac_add((uint8_t *) p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
|
(p->scan_rst.rssi < cfg.rssilimit)) { // rssi is negative value
|
||||||
|
ESP_LOGI(TAG, "BLTH RSSI %d -> ignoring (limit: %d)", p->scan_rst.rssi,
|
||||||
/* to be improved in vendorfilter if:
|
cfg.rssilimit);
|
||||||
|
|
||||||
// you can search for elements in the payload using the
|
|
||||||
// function esp_ble_resolve_adv_data()
|
|
||||||
//
|
|
||||||
// Like this, that scans for the "Complete name" (looking inside the payload buffer)
|
|
||||||
// uint8_t 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
|
|
||||||
if vendorfiltering is on, we ...
|
|
||||||
- want to count: mobile phones and tablets
|
|
||||||
- don't want to count: beacons, peripherals (earphones, headsets, printers), cars and machines
|
|
||||||
see
|
|
||||||
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
|
|
||||||
|
|
||||||
http://www.libelium.com/products/meshlium/smartphone-detection/
|
|
||||||
|
|
||||||
https://www.question-defense.com/2013/01/12/bluetooth-cod-bluetooth-class-of-deviceclass-of-service-explained
|
|
||||||
|
|
||||||
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
|
|
||||||
device (smartphone, handsfree, computer, LAN/network AP). With this parameter we can
|
|
||||||
differentiate among pedestrians and vehicles."
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // evaluate sniffed packet
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VENDORFILTER
|
||||||
|
|
||||||
|
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");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// add this device and show new count total if it was not previously added
|
||||||
|
mac_add((uint8_t *)p->scan_rst.bda, p->scan_rst.rssi, MAC_SNIFF_BLE);
|
||||||
|
|
||||||
|
/* to be improved in vendorfilter if:
|
||||||
|
|
||||||
|
// you can search for elements in the payload using the
|
||||||
|
// function esp_ble_resolve_adv_data()
|
||||||
|
//
|
||||||
|
// Like this, that scans for the "Complete name" (looking inside the
|
||||||
|
payload buffer)
|
||||||
|
// uint8_t 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 if vendorfiltering is on, we ...
|
||||||
|
- want to count: mobile phones and tablets
|
||||||
|
- don't want to count: beacons, peripherals (earphones, headsets,
|
||||||
|
printers), cars and machines see
|
||||||
|
https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/src/BLEAdvertisedDevice.cpp
|
||||||
|
|
||||||
|
http://www.libelium.com/products/meshlium/smartphone-detection/
|
||||||
|
|
||||||
|
https://www.question-defense.com/2013/01/12/bluetooth-cod-bluetooth-class-of-deviceclass-of-service-explained
|
||||||
|
|
||||||
|
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 device (smartphone, handsfree, computer,
|
||||||
|
LAN/network AP). With this parameter we can differentiate among
|
||||||
|
pedestrians and vehicles."
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // evaluate sniffed packet
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
} // 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");
|
||||||
|
|
||||||
// This function is called to occur gap event, such as scan result.
|
|
||||||
//register the scan callback function to the gap module
|
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler));
|
|
||||||
|
|
||||||
static esp_ble_scan_params_t ble_scan_params =
|
// This function is called to occur gap event, such as scan result.
|
||||||
{
|
// register the scan callback function to the gap module
|
||||||
.scan_type = BLE_SCAN_TYPE_PASSIVE,
|
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler));
|
||||||
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
|
||||||
|
|
||||||
#ifdef VENDORFILTER
|
|
||||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR,
|
|
||||||
// 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
|
|
||||||
#else
|
|
||||||
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.scan_interval = (uint16_t) (cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec
|
static esp_ble_scan_params_t ble_scan_params = {
|
||||||
.scan_window = (uint16_t) (BLESCANWINDOW / 0.625) // Time = N * 0.625 msec
|
.scan_type = BLE_SCAN_TYPE_PASSIVE,
|
||||||
};
|
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Set GAP scan parameters");
|
#ifdef VENDORFILTER
|
||||||
|
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR,
|
||||||
|
// 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
|
||||||
|
#else
|
||||||
|
.scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL,
|
||||||
|
#endif
|
||||||
|
|
||||||
// This function is called to set scan parameters.
|
.scan_interval =
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&ble_scan_params));
|
(uint16_t)(cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec
|
||||||
|
.scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec
|
||||||
return ESP_OK;
|
};
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Set GAP scan parameters");
|
||||||
|
|
||||||
|
// This function is called to set scan parameters.
|
||||||
|
ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&ble_scan_params));
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
|
||||||
} // register_ble_callback
|
} // register_ble_callback
|
||||||
|
|
||||||
void start_BLEscan(void){
|
void start_BLEscan(void) {
|
||||||
ESP_LOGI(TAG, "Initializing bluetooth scanner ...");
|
ESP_LOGI(TAG, "Initializing bluetooth scanner ...");
|
||||||
|
|
||||||
// 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 =
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
|
BLESTACKSIZE; // set BT stack size to value configured in paxcounter.conf
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BTDM));
|
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
|
||||||
|
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
|
||||||
ESP_ERROR_CHECK(esp_bluedroid_init());
|
// every bluetooth stuff
|
||||||
ESP_ERROR_CHECK(esp_bluedroid_enable());
|
ESP_ERROR_CHECK(esp_bluedroid_init());
|
||||||
|
ESP_ERROR_CHECK(esp_bluedroid_enable());
|
||||||
|
|
||||||
// Register callback function for capturing bluetooth packets
|
// Register callback function for capturing bluetooth packets
|
||||||
ESP_ERROR_CHECK(register_ble_callback());
|
ESP_ERROR_CHECK(register_ble_callback());
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Bluetooth scanner started");
|
ESP_LOGI(TAG, "Bluetooth scanner started");
|
||||||
} // start_BLEscan
|
} // start_BLEscan
|
||||||
|
|
||||||
void stop_BLEscan(void){
|
void stop_BLEscan(void) {
|
||||||
ESP_LOGI(TAG, "Shutting down bluetooth scanner ...");
|
ESP_LOGI(TAG, "Shutting down bluetooth scanner ...");
|
||||||
ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL));
|
ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL));
|
||||||
ESP_ERROR_CHECK(esp_bluedroid_disable());
|
ESP_ERROR_CHECK(esp_bluedroid_disable());
|
||||||
ESP_ERROR_CHECK(esp_bluedroid_deinit());
|
ESP_ERROR_CHECK(esp_bluedroid_deinit());
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_disable());
|
ESP_ERROR_CHECK(esp_bt_controller_disable());
|
||||||
ESP_ERROR_CHECK(esp_bt_controller_deinit());
|
ESP_ERROR_CHECK(esp_bt_controller_deinit());
|
||||||
ESP_LOGI(TAG, "Bluetooth scanner stopped");
|
ESP_LOGI(TAG, "Bluetooth scanner stopped");
|
||||||
} // stop_BLEscan
|
} // stop_BLEscan
|
||||||
|
|
||||||
#endif // BLECOUNTER
|
#endif // BLECOUNTER
|
@ -13,130 +13,152 @@ esp_err_t err;
|
|||||||
|
|
||||||
// defined in antenna.cpp
|
// defined in antenna.cpp
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
void antenna_select(const uint8_t _ant);
|
void antenna_select(const uint8_t _ant);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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 spreadfactor defined in
|
||||||
cfg.txpower = 15; // 2-15, lora tx power
|
// paxcounter.conf
|
||||||
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
cfg.txpower = 15; // 2-15, lora tx power
|
||||||
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
||||||
cfg.screenon = 1; // 0=disabled, 1=enabled
|
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
||||||
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
cfg.screenon = 1; // 0=disabled, 1=enabled
|
||||||
cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
|
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||||
cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
|
cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
|
||||||
cfg.wifichancycle = WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
|
cfg.sendcycle = SEND_SECS; // payload send cycle [seconds/2]
|
||||||
cfg.blescantime = BLESCANINTERVAL / 10; // BT channel scan cycle duration [seconds/100], default 1 (= 10ms)
|
cfg.wifichancycle =
|
||||||
cfg.blescan = 1; // 0=disabled, 1=enabled
|
WIFI_CHANNEL_SWITCH_INTERVAL; // wifi channel switch cycle [seconds/100]
|
||||||
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
|
cfg.blescantime =
|
||||||
cfg.vendorfilter = 1; // 0=disabled, 1=enabled
|
BLESCANINTERVAL /
|
||||||
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)
|
10; // BT channel scan cycle duration [seconds/100], default 1 (= 10ms)
|
||||||
cfg.gpsmode = 1; // 0=disabled, 1=enabled
|
cfg.blescan = 1; // 0=disabled, 1=enabled
|
||||||
|
cfg.wifiant = 0; // 0=internal, 1=external (for LoPy/LoPy4)
|
||||||
|
cfg.vendorfilter = 1; // 0=disabled, 1=enabled
|
||||||
|
cfg.rgblum = RGBLUMINOSITY; // RGB Led luminosity (0..100%)
|
||||||
|
cfg.gpsmode = 1; // 0=disabled, 1=enabled
|
||||||
|
|
||||||
strncpy( cfg.version, PROGVERSION, sizeof(cfg.version)-1 );
|
strncpy(cfg.version, PROGVERSION, sizeof(cfg.version) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void open_storage() {
|
void open_storage() {
|
||||||
|
err = nvs_flash_init();
|
||||||
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
|
||||||
|
// NVS partition was truncated and needs to be erased
|
||||||
|
// Retry nvs_flash_init
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
err = nvs_flash_init();
|
err = nvs_flash_init();
|
||||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
|
}
|
||||||
// NVS partition was truncated and needs to be erased
|
ESP_ERROR_CHECK(err);
|
||||||
// Retry nvs_flash_init
|
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
||||||
err = nvs_flash_init();
|
|
||||||
}
|
|
||||||
ESP_ERROR_CHECK( err );
|
|
||||||
|
|
||||||
// Open
|
// Open
|
||||||
ESP_LOGI(TAG, "Opening NVS");
|
ESP_LOGI(TAG, "Opening NVS");
|
||||||
err = nvs_open("config", NVS_READWRITE, &my_handle);
|
err = nvs_open("config", NVS_READWRITE, &my_handle);
|
||||||
if (err != ESP_OK)
|
if (err != ESP_OK)
|
||||||
ESP_LOGI(TAG, "Error (%d) opening NVS handle", err);
|
ESP_LOGI(TAG, "Error (%d) opening NVS handle", err);
|
||||||
else
|
else
|
||||||
ESP_LOGI(TAG, "Done");
|
ESP_LOGI(TAG, "Done");
|
||||||
}
|
}
|
||||||
|
|
||||||
// erase all keys and values in NVRAM
|
// erase all keys and values in NVRAM
|
||||||
void eraseConfig() {
|
void eraseConfig() {
|
||||||
ESP_LOGI(TAG, "Clearing settings in NVS");
|
ESP_LOGI(TAG, "Clearing settings in NVS");
|
||||||
open_storage();
|
open_storage();
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
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
|
||||||
void saveConfig() {
|
void saveConfig() {
|
||||||
ESP_LOGI(TAG, "Storing settings in NVS");
|
ESP_LOGI(TAG, "Storing settings in NVS");
|
||||||
open_storage();
|
open_storage();
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
int8_t flash8 = 0;
|
int8_t flash8 = 0;
|
||||||
int16_t flash16 = 0;
|
int16_t flash16 = 0;
|
||||||
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) !=
|
||||||
nvs_set_str(my_handle, "version", cfg.version);
|
ESP_OK ||
|
||||||
|
strcmp(storedversion, cfg.version) != 0)
|
||||||
|
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 ||
|
||||||
nvs_set_i8(my_handle, "lorasf", cfg.lorasf);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "txpower", cfg.txpower);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "adrmode", cfg.adrmode);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "screensaver", cfg.screensaver);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "screenon", cfg.screenon);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "countermode", cfg.countermode);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "sendcycle", cfg.sendcycle);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "wifichancycle", cfg.wifichancycle);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "blescantime", cfg.blescantime);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "blescanmode", cfg.blescan);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "wifiant", cfg.wifiant);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "vendorfilter", cfg.vendorfilter);
|
flash8 != 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 ||
|
||||||
nvs_set_i8(my_handle, "rgblum", cfg.rgblum);
|
flash8 != 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 ||
|
||||||
nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit);
|
flash16 != cfg.rssilimit)
|
||||||
|
nvs_set_i16(my_handle, "rssilimit", cfg.rssilimit);
|
||||||
|
|
||||||
err = nvs_commit(my_handle);
|
err = nvs_commit(my_handle);
|
||||||
nvs_close(my_handle);
|
nvs_close(my_handle);
|
||||||
if ( err == ESP_OK ) {
|
if (err == ESP_OK) {
|
||||||
ESP_LOGI(TAG, "Done");
|
ESP_LOGI(TAG, "Done");
|
||||||
} else {
|
|
||||||
ESP_LOGW(TAG, "NVS config write failed");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "Error (%d) opening NVS handle", err);
|
ESP_LOGW(TAG, "NVS config write failed");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "Error (%d) opening NVS handle", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set and save cfg.version
|
// set and save cfg.version
|
||||||
@ -152,31 +174,33 @@ void loadConfig() {
|
|||||||
ESP_LOGI(TAG, "Reading settings from NVS");
|
ESP_LOGI(TAG, "Reading settings from NVS");
|
||||||
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;
|
||||||
size_t required_size;
|
size_t required_size;
|
||||||
|
|
||||||
// check if configuration stored in NVRAM matches PROGVERSION
|
// check if configuration stored in NVRAM matches PROGVERSION
|
||||||
if( nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK ) {
|
if (nvs_get_str(my_handle, "version", NULL, &required_size) == ESP_OK) {
|
||||||
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();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI(TAG, "new version %s, deleting NVRAM settings", PROGVERSION);
|
ESP_LOGI(TAG, "new version %s, deleting NVRAM settings", PROGVERSION);
|
||||||
nvs_close(my_handle);
|
nvs_close(my_handle);
|
||||||
eraseConfig();
|
eraseConfig();
|
||||||
migrateVersion();
|
migrateVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite defaults with valid values from NVRAM
|
// overwrite defaults with valid values from NVRAM
|
||||||
if( nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "lorasf", &flash8) == ESP_OK) {
|
||||||
cfg.lorasf = flash8;
|
cfg.lorasf = flash8;
|
||||||
ESP_LOGI(TAG, "lorasf = %d", flash8);
|
ESP_LOGI(TAG, "lorasf = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -184,7 +208,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "txpower", &flash8) == ESP_OK) {
|
||||||
cfg.txpower = flash8;
|
cfg.txpower = flash8;
|
||||||
ESP_LOGI(TAG, "txpower = %d", flash8);
|
ESP_LOGI(TAG, "txpower = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -192,7 +216,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "adrmode", &flash8) == ESP_OK) {
|
||||||
cfg.adrmode = flash8;
|
cfg.adrmode = flash8;
|
||||||
ESP_LOGI(TAG, "adrmode = %d", flash8);
|
ESP_LOGI(TAG, "adrmode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -200,7 +224,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "screensaver", &flash8) == ESP_OK) {
|
||||||
cfg.screensaver = flash8;
|
cfg.screensaver = flash8;
|
||||||
ESP_LOGI(TAG, "screensaver = %d", flash8);
|
ESP_LOGI(TAG, "screensaver = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -208,7 +232,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "screenon", &flash8) == ESP_OK) {
|
||||||
cfg.screenon = flash8;
|
cfg.screenon = flash8;
|
||||||
ESP_LOGI(TAG, "screenon = %d", flash8);
|
ESP_LOGI(TAG, "screenon = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -216,7 +240,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "countermode", &flash8) == ESP_OK) {
|
||||||
cfg.countermode = flash8;
|
cfg.countermode = flash8;
|
||||||
ESP_LOGI(TAG, "countermode = %d", flash8);
|
ESP_LOGI(TAG, "countermode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -224,7 +248,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "sendcycle", &flash8) == ESP_OK) {
|
||||||
cfg.sendcycle = flash8;
|
cfg.sendcycle = flash8;
|
||||||
ESP_LOGI(TAG, "sendcycle = %d", flash8);
|
ESP_LOGI(TAG, "sendcycle = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -232,7 +256,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "wifichancycle", &flash8) == ESP_OK) {
|
||||||
cfg.wifichancycle = flash8;
|
cfg.wifichancycle = flash8;
|
||||||
ESP_LOGI(TAG, "wifichancycle = %d", flash8);
|
ESP_LOGI(TAG, "wifichancycle = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -240,7 +264,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "wifiant", &flash8) == ESP_OK) {
|
||||||
cfg.wifiant = flash8;
|
cfg.wifiant = flash8;
|
||||||
ESP_LOGI(TAG, "wifiantenna = %d", flash8);
|
ESP_LOGI(TAG, "wifiantenna = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -248,7 +272,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "vendorfilter", &flash8) == ESP_OK) {
|
||||||
cfg.vendorfilter = flash8;
|
cfg.vendorfilter = flash8;
|
||||||
ESP_LOGI(TAG, "vendorfilter = %d", flash8);
|
ESP_LOGI(TAG, "vendorfilter = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -256,7 +280,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "rgblum", &flash8) == ESP_OK) {
|
||||||
cfg.rgblum = flash8;
|
cfg.rgblum = flash8;
|
||||||
ESP_LOGI(TAG, "rgbluminosity = %d", flash8);
|
ESP_LOGI(TAG, "rgbluminosity = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -264,7 +288,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "blescantime", &flash8) == ESP_OK) {
|
||||||
cfg.blescantime = flash8;
|
cfg.blescantime = flash8;
|
||||||
ESP_LOGI(TAG, "blescantime = %d", flash8);
|
ESP_LOGI(TAG, "blescantime = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -272,7 +296,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "blescanmode", &flash8) == ESP_OK) {
|
||||||
cfg.blescan = flash8;
|
cfg.blescan = flash8;
|
||||||
ESP_LOGI(TAG, "BLEscanmode = %d", flash8);
|
ESP_LOGI(TAG, "BLEscanmode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -280,7 +304,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK ) {
|
if (nvs_get_i16(my_handle, "rssilimit", &flash16) == ESP_OK) {
|
||||||
cfg.rssilimit = flash16;
|
cfg.rssilimit = flash16;
|
||||||
ESP_LOGI(TAG, "rssilimit = %d", flash16);
|
ESP_LOGI(TAG, "rssilimit = %d", flash16);
|
||||||
} else {
|
} else {
|
||||||
@ -288,7 +312,7 @@ void loadConfig() {
|
|||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nvs_get_i8(my_handle, "gpsmode", &flash8) == ESP_OK ) {
|
if (nvs_get_i8(my_handle, "gpsmode", &flash8) == ESP_OK) {
|
||||||
cfg.gpsmode = flash8;
|
cfg.gpsmode = flash8;
|
||||||
ESP_LOGI(TAG, "GPSmode = %d", flash8);
|
ESP_LOGI(TAG, "GPSmode = %d", flash8);
|
||||||
} else {
|
} else {
|
||||||
@ -300,9 +324,9 @@ void loadConfig() {
|
|||||||
ESP_LOGI(TAG, "Done");
|
ESP_LOGI(TAG, "Done");
|
||||||
|
|
||||||
// put actions to be triggered after config loaded here
|
// put actions to be triggered after config loaded here
|
||||||
|
|
||||||
#ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one
|
#ifdef HAS_ANTENNA_SWITCH // set antenna type, if device has one
|
||||||
antenna_select(cfg.wifiant);
|
antenna_select(cfg.wifiant);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,63 +2,63 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
// std::set for unified array functions
|
// std::set for unified array functions
|
||||||
#include <set>
|
|
||||||
#include <array>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
// OLED Display
|
// OLED Display
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
#include <U8x8lib.h>
|
#include <U8x8lib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//GPS
|
// GPS
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
#include <TinyGPS++.h>
|
#include <TinyGPS++.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LMIC-Arduino LoRaWAN Stack
|
// LMIC-Arduino LoRaWAN Stack
|
||||||
#include <lmic.h>
|
|
||||||
#include <hal/hal.h>
|
#include <hal/hal.h>
|
||||||
|
#include <lmic.h>
|
||||||
|
|
||||||
// LED controls
|
// LED controls
|
||||||
#ifdef HAS_RGB_LED
|
#ifdef HAS_RGB_LED
|
||||||
#include <SmartLeds.h>
|
#include <SmartLeds.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "rgb_led.h"
|
|
||||||
#include "macsniff.h"
|
#include "macsniff.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "rgb_led.h"
|
||||||
|
|
||||||
// Struct holding devices's runtime configuration
|
// Struct holding devices's runtime configuration
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t lorasf; // 7-12, lora spreadfactor
|
uint8_t lorasf; // 7-12, lora spreadfactor
|
||||||
uint8_t txpower; // 2-15, lora tx power
|
uint8_t txpower; // 2-15, lora tx power
|
||||||
uint8_t adrmode; // 0=disabled, 1=enabled
|
uint8_t adrmode; // 0=disabled, 1=enabled
|
||||||
uint8_t screensaver; // 0=disabled, 1=enabled
|
uint8_t screensaver; // 0=disabled, 1=enabled
|
||||||
uint8_t screenon; // 0=disabled, 1=enabled
|
uint8_t screenon; // 0=disabled, 1=enabled
|
||||||
uint8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed
|
uint8_t countermode; // 0=cyclic unconfirmed, 1=cumulative, 2=cyclic confirmed
|
||||||
int16_t rssilimit; // threshold for rssilimiter, negative value!
|
int16_t rssilimit; // threshold for rssilimiter, negative value!
|
||||||
uint8_t sendcycle; // payload send cycle [seconds/2]
|
uint8_t sendcycle; // payload send cycle [seconds/2]
|
||||||
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
uint8_t wifichancycle; // wifi channel switch cycle [seconds/100]
|
||||||
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
uint8_t blescantime; // BLE scan cycle duration [seconds]
|
||||||
uint8_t blescan; // 0=disabled, 1=enabled
|
uint8_t blescan; // 0=disabled, 1=enabled
|
||||||
uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
uint8_t wifiant; // 0=internal, 1=external (for LoPy/LoPy4)
|
||||||
uint8_t vendorfilter; // 0=disabled, 1=enabled
|
uint8_t vendorfilter; // 0=disabled, 1=enabled
|
||||||
uint8_t rgblum; // RGB Led luminosity (0..100%)
|
uint8_t rgblum; // RGB Led luminosity (0..100%)
|
||||||
uint8_t gpsmode; // 0=disabled, 1=enabled
|
uint8_t gpsmode; // 0=disabled, 1=enabled
|
||||||
char version[10]; // Firmware version
|
char version[10]; // Firmware version
|
||||||
} configData_t;
|
} configData_t;
|
||||||
|
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t latitude;
|
uint32_t latitude;
|
||||||
uint32_t longitude;
|
uint32_t longitude;
|
||||||
uint8_t satellites;
|
uint8_t satellites;
|
||||||
uint16_t hdop;
|
uint16_t hdop;
|
||||||
uint16_t altitude;
|
uint16_t altitude;
|
||||||
} gpsStatus_t;
|
} gpsStatus_t;
|
||||||
extern gpsStatus_t gps_status; // struct for storing gps data
|
extern gpsStatus_t gps_status; // struct for storing gps data
|
||||||
extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
|
extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern configData_t cfg;
|
extern configData_t cfg;
|
||||||
@ -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
|
||||||
extern xref2u1_t rcmd_data; // buffer for rcommand results size
|
*channelSwitch; // hardware timer used for wifi channel switching
|
||||||
extern u1_t rcmd_data_size; // 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
|
||||||
|
113
src/gpsread.cpp
113
src/gpsread.cpp
@ -7,74 +7,73 @@ static const char TAG[] = "main";
|
|||||||
|
|
||||||
// read GPS data and cast to global struct
|
// read GPS data and cast to global struct
|
||||||
void gps_read() {
|
void gps_read() {
|
||||||
gps_status.latitude = (uint32_t) (gps.location.lat() * 1000000);
|
gps_status.latitude = (uint32_t)(gps.location.lat() * 1000000);
|
||||||
gps_status.longitude = (uint32_t) (gps.location.lng() * 1000000);
|
gps_status.longitude = (uint32_t)(gps.location.lng() * 1000000);
|
||||||
gps_status.satellites = (uint8_t) gps.satellites.value();
|
gps_status.satellites = (uint8_t)gps.satellites.value();
|
||||||
gps_status.hdop = (uint16_t) gps.hdop.value();
|
gps_status.hdop = (uint16_t)gps.hdop.value();
|
||||||
gps_status.altitude = (uint16_t) gps.altitude.meters();
|
gps_status.altitude = (uint16_t)gps.altitude.meters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPS serial feed FreeRTos Task
|
// GPS serial feed FreeRTos Task
|
||||||
void gps_loop(void * pvParameters) {
|
void gps_loop(void *pvParameters) {
|
||||||
|
|
||||||
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
||||||
|
|
||||||
// initialize and, if needed, configure, GPS
|
// initialize and, if needed, configure, GPS
|
||||||
#if defined GPS_SERIAL
|
#if defined GPS_SERIAL
|
||||||
HardwareSerial GPS_Serial(1);
|
HardwareSerial GPS_Serial(1);
|
||||||
#elif defined GPS_I2C
|
#elif defined GPS_I2C
|
||||||
// to be done
|
// to be done
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
|
|
||||||
if (cfg.gpsmode)
|
if (cfg.gpsmode) {
|
||||||
{
|
#if defined GPS_SERIAL
|
||||||
#if defined GPS_SERIAL
|
|
||||||
|
|
||||||
// serial connect to GPS device
|
|
||||||
GPS_Serial.begin(GPS_SERIAL);
|
|
||||||
|
|
||||||
while(cfg.gpsmode) {
|
|
||||||
// feed GPS decoder with serial NMEA data from GPS device
|
|
||||||
while (GPS_Serial.available()) {
|
|
||||||
gps.encode(GPS_Serial.read());
|
|
||||||
}
|
|
||||||
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
|
||||||
}
|
|
||||||
// after GPS function was disabled, close connect to GPS device
|
|
||||||
GPS_Serial.end();
|
|
||||||
|
|
||||||
#elif defined GPS_I2C
|
// serial connect to GPS device
|
||||||
|
GPS_Serial.begin(GPS_SERIAL);
|
||||||
// I2C connect to GPS device with 100 kHz
|
|
||||||
Wire.begin(GPS_I2C_PINS, 100000);
|
|
||||||
Wire.beginTransmission(GPS_I2C_ADDRESS_WRITE);
|
|
||||||
Wire.write(0x00);
|
|
||||||
|
|
||||||
i2c_ret == Wire.beginTransmission(GPS_I2C_ADDRESS_READ);
|
while (cfg.gpsmode) {
|
||||||
if (i2c_ret == 0) { // check if device seen on i2c bus
|
// feed GPS decoder with serial NMEA data from GPS device
|
||||||
while(cfg.gpsmode) {
|
while (GPS_Serial.available()) {
|
||||||
// feed GPS decoder with serial NMEA data from GPS device
|
gps.encode(GPS_Serial.read());
|
||||||
while (Wire.available()) {
|
|
||||||
Wire.requestFrom(GPS_I2C_ADDRESS_READ, 255);
|
|
||||||
gps.encode(Wire.read());
|
|
||||||
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// after GPS function was disabled, close connect to GPS device
|
|
||||||
|
|
||||||
Wire.endTransmission();
|
|
||||||
Wire.setClock(400000); // Set back to 400KHz to speed up OLED
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
|
||||||
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
}
|
||||||
|
// after GPS function was disabled, close connect to GPS device
|
||||||
|
GPS_Serial.end();
|
||||||
|
|
||||||
} // end of infinite loop
|
#elif defined GPS_I2C
|
||||||
|
|
||||||
|
// I2C connect to GPS device with 100 kHz
|
||||||
|
Wire.begin(GPS_I2C_PINS, 100000);
|
||||||
|
Wire.beginTransmission(GPS_I2C_ADDRESS_WRITE);
|
||||||
|
Wire.write(0x00);
|
||||||
|
|
||||||
|
i2c_ret == Wire.beginTransmission(GPS_I2C_ADDRESS_READ);
|
||||||
|
if (i2c_ret == 0) { // check if device seen on i2c bus
|
||||||
|
while (cfg.gpsmode) {
|
||||||
|
// feed GPS decoder with serial NMEA data from GPS device
|
||||||
|
while (Wire.available()) {
|
||||||
|
Wire.requestFrom(GPS_I2C_ADDRESS_READ, 255);
|
||||||
|
gps.encode(Wire.read());
|
||||||
|
vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// after GPS function was disabled, close connect to GPS device
|
||||||
|
|
||||||
|
Wire.endTransmission();
|
||||||
|
Wire.setClock(400000); // Set back to 400KHz to speed up OLED
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(1 / portTICK_PERIOD_MS); // reset watchdog
|
||||||
|
|
||||||
|
} // end of infinite loop
|
||||||
|
|
||||||
} // gps_loop()
|
} // gps_loop()
|
||||||
|
|
||||||
#endif // HAS_GPS
|
#endif // HAS_GPS
|
@ -1,19 +1,19 @@
|
|||||||
// Hardware related definitions for Pycom FiPy Board
|
// Hardware related definitions for Pycom FiPy Board
|
||||||
|
|
||||||
#define CFG_sx1272_radio 1
|
#define CFG_sx1272_radio 1
|
||||||
#define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED
|
#define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED
|
||||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||||
|
|
||||||
// Hardware pin definitions for Pycom FiPy board
|
// Hardware pin definitions for Pycom FiPy board
|
||||||
#define PIN_SPI_SS GPIO_NUM_18
|
#define PIN_SPI_SS GPIO_NUM_18
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27
|
#define PIN_SPI_MOSI GPIO_NUM_27
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19
|
#define PIN_SPI_MISO GPIO_NUM_19
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5
|
#define PIN_SPI_SCK GPIO_NUM_5
|
||||||
#define RST LMIC_UNUSED_PIN
|
#define RST LMIC_UNUSED_PIN
|
||||||
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
||||||
#define DIO1 GPIO_NUM_23 // workaround
|
#define DIO1 GPIO_NUM_23 // workaround
|
||||||
#define DIO2 LMIC_UNUSED_PIN
|
#define DIO2 LMIC_UNUSED_PIN
|
||||||
|
|
||||||
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
||||||
#define HAS_ANTENNA_SWITCH GPIO_NUM_21 // pin for switching wifi antenna
|
#define HAS_ANTENNA_SWITCH GPIO_NUM_21 // pin for switching wifi antenna
|
||||||
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
||||||
|
@ -4,22 +4,36 @@
|
|||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
||||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||||
#define HAS_LED GPIO_NUM_25 // white LED on board
|
#define HAS_LED GPIO_NUM_25 // white LED on board
|
||||||
#define HAS_BUTTON GPIO_NUM_0 // button "PROG" on board
|
#define HAS_BUTTON GPIO_NUM_0 // button "PROG" on board
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input
|
GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
// Input
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input
|
#define PIN_SPI_MOSI \
|
||||||
|
GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#define RST GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST \
|
||||||
#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger
|
||||||
#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
// Input
|
||||||
#define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO0 \
|
||||||
|
GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for
|
||||||
|
// detecting LoRa RX_Done & TX_Done
|
||||||
|
#define DIO1 \
|
||||||
|
GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for
|
||||||
|
// detecting LoRa RX_Timeout
|
||||||
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by
|
||||||
|
// LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C Display
|
// Hardware pin definitions for Heltec LoRa-32 Board with OLED SSD1306 I2C
|
||||||
|
// Display
|
||||||
#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 RST
|
#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 RST
|
||||||
#define OLED_SDA GPIO_NUM_4 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
#define OLED_SDA GPIO_NUM_4 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
||||||
#define OLED_SCL GPIO_NUM_15 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
#define OLED_SCL GPIO_NUM_15 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
||||||
|
@ -6,33 +6,50 @@
|
|||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
||||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||||
#define HAS_LED NOT_A_PIN // Led os on same pin as Lora SS pin, to avoid problems, we don't use it
|
#define HAS_LED \
|
||||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
NOT_A_PIN // Led os on same pin as Lora SS pin, to avoid problems, we don't
|
||||||
// Anyway shield is on over the LoLin32 board, so we won't be able to see this LED
|
// use it
|
||||||
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
#define LED_ACTIVE_LOW \
|
||||||
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
1 // Onboard LED is active when pin is LOW
|
||||||
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
// Anyway shield is on over the LoLin32 board, so we won't be able to see
|
||||||
|
// this LED
|
||||||
|
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||||
|
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
||||||
|
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
||||||
|
|
||||||
#define CFG_sx1276_radio 1 // RFM95 module
|
#define CFG_sx1276_radio 1 // RFM95 module
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS 5 // ESP32 GPIO5 (Pin5) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI 23 // ESP32 GPIO23 (Pin23) -- SX1276 MOSI (Pin18) SPI Data Input
|
5 // ESP32 GPIO5 (Pin5) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
||||||
#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
#define PIN_SPI_MOSI \
|
||||||
#define PIN_SPI_SCK 18 // ESP32 GPIO18 (Pin18 -- SX1276 SCK (Pin16) SPI Clock Input
|
23 // ESP32 GPIO23 (Pin23) -- SX1276 MOSI (Pin18) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
18 // ESP32 GPIO18 (Pin18 -- SX1276 SCK (Pin16) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST \
|
||||||
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO0 \
|
||||||
#define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting
|
||||||
#define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
// LoRa RX_Done & TX_Done
|
||||||
|
#define DIO1 \
|
||||||
|
26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting
|
||||||
|
// LoRa RX_Timeout
|
||||||
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by
|
||||||
|
// LMIC for LoRa (Timeout for FSK only)
|
||||||
|
#define DIO5 \
|
||||||
|
LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC
|
||||||
|
// for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
||||||
#define OLED_SDA 21 // ESP32 GPIO21 (Pin21) -- OLED SDA
|
#define OLED_SDA 21 // ESP32 GPIO21 (Pin21) -- OLED SDA
|
||||||
#define OLED_SCL 22 // ESP32 GPIO22 (Pin22) -- OLED SCL
|
#define OLED_SCL 22 // ESP32 GPIO22 (Pin22) -- OLED SCL
|
||||||
|
|
||||||
// I2C config for Microchip 24AA02E64 DEVEUI unique address
|
// I2C config for Microchip 24AA02E64 DEVEUI unique address
|
||||||
#define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64
|
#define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64
|
||||||
#define MCP_24AA02E64_MAC_ADDRESS 0xF8 // Memory adress of unique deveui 64 bits
|
#define MCP_24AA02E64_MAC_ADDRESS 0xF8 // Memory adress of unique deveui 64 bits
|
||||||
|
@ -6,32 +6,45 @@
|
|||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
||||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||||
#define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED
|
#define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED
|
||||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||||
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||||
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
||||||
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
||||||
|
|
||||||
#define CFG_sx1276_radio 1 // RFM95 module
|
#define CFG_sx1276_radio 1 // RFM95 module
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS 5 // ESP32 GPIO5 (Pin5) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI 23 // ESP32 GPIO23 (Pin23) -- SX1276 MOSI (Pin18) SPI Data Input
|
5 // ESP32 GPIO5 (Pin5) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
||||||
#define PIN_SPI_MISO 19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
#define PIN_SPI_MOSI \
|
||||||
#define PIN_SPI_SCK 18 // ESP32 GPIO18 (Pin18 -- SX1276 SCK (Pin16) SPI Clock Input
|
23 // ESP32 GPIO23 (Pin23) -- SX1276 MOSI (Pin18) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
18 // ESP32 GPIO18 (Pin18 -- SX1276 SCK (Pin16) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#define RST 25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST \
|
||||||
#define DIO0 27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
25 // ESP32 GPIO25 (Pin25) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
||||||
#define DIO1 26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
#define DIO0 \
|
||||||
#define DIO2 LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
27 // ESP32 GPIO27 (Pin27) -- SX1276 DIO0 (Pin8) used by LMIC for detecting
|
||||||
#define DIO5 LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC for LoRa (Timeout for FSK only)
|
// LoRa RX_Done & TX_Done
|
||||||
|
#define DIO1 \
|
||||||
|
26 // ESP32 GPIO26 (Pin26) -- SX1276 DIO1 (Pin9) used by LMIC for detecting
|
||||||
|
// LoRa RX_Timeout
|
||||||
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // 4 ESP32 GPIO4 (Pin4) -- SX1276 DIO2 (Pin10) not used by
|
||||||
|
// LMIC for LoRa (Timeout for FSK only)
|
||||||
|
#define DIO5 \
|
||||||
|
LMIC_UNUSED_PIN // 35 ESP32 GPIO35 (Pin35) -- SX1276 DIO5 not used by LMIC
|
||||||
|
// for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
// Hardware pin definitions for LoRaNode32 Board with OLED I2C Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
#define OLED_RST U8X8_PIN_NONE // Not reset pin
|
||||||
#define OLED_SDA 14 // ESP32 GPIO14 (Pin14) -- OLED SDA
|
#define OLED_SDA 14 // ESP32 GPIO14 (Pin14) -- OLED SDA
|
||||||
#define OLED_SCL 12 // ESP32 GPIO12 (Pin12) -- OLED SCL
|
#define OLED_SCL 12 // ESP32 GPIO12 (Pin12) -- OLED SCL
|
||||||
|
|
||||||
// I2C config for Microchip 24AA02E64 DEVEUI unique address
|
// I2C config for Microchip 24AA02E64 DEVEUI unique address
|
||||||
#define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64
|
#define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64
|
||||||
#define MCP_24AA02E64_MAC_ADDRESS 0xF8 // Memory adress of unique deveui 64 bits
|
#define MCP_24AA02E64_MAC_ADDRESS 0xF8 // Memory adress of unique deveui 64 bits
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
|
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
|
||||||
|
|
||||||
#define CFG_sx1272_radio 1
|
#define CFG_sx1272_radio 1
|
||||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4
|
#define HAS_LED \
|
||||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4
|
||||||
|
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||||
|
|
||||||
// !!EXPERIMENTAL - not tested yet!!
|
// !!EXPERIMENTAL - not tested yet!!
|
||||||
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
||||||
// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
// see
|
||||||
|
// http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
||||||
//#define HAS_GPS 1
|
//#define HAS_GPS 1
|
||||||
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||||
//#define GPS_I2C_ADDRESS_READ 0x21
|
//#define GPS_I2C_ADDRESS_READ 0x21
|
||||||
@ -14,15 +16,15 @@
|
|||||||
//#define HAS_BUTTON GPIO_NUM_4
|
//#define HAS_BUTTON GPIO_NUM_4
|
||||||
|
|
||||||
// Hardware pin definitions for Pycom LoPy board
|
// Hardware pin definitions for Pycom LoPy board
|
||||||
#define PIN_SPI_SS GPIO_NUM_17
|
#define PIN_SPI_SS GPIO_NUM_17
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27
|
#define PIN_SPI_MOSI GPIO_NUM_27
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19
|
#define PIN_SPI_MISO GPIO_NUM_19
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5
|
#define PIN_SPI_SCK GPIO_NUM_5
|
||||||
#define RST GPIO_NUM_18
|
#define RST GPIO_NUM_18
|
||||||
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
||||||
#define DIO1 GPIO_NUM_23 // workaround
|
#define DIO1 GPIO_NUM_23 // workaround
|
||||||
#define DIO2 LMIC_UNUSED_PIN
|
#define DIO2 LMIC_UNUSED_PIN
|
||||||
|
|
||||||
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
||||||
#define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna
|
#define HAS_ANTENNA_SWITCH 16 // pin for switching wifi antenna
|
||||||
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
|
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
|
||||||
|
|
||||||
#define CFG_sx1276_radio 1
|
#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 \
|
||||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4
|
||||||
|
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||||
|
|
||||||
// !!EXPERIMENTAL - not tested yet!!f
|
// !!EXPERIMENTAL - not tested yet!!f
|
||||||
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
||||||
// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
// see
|
||||||
|
// http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
||||||
//#define HAS_GPS 1
|
//#define HAS_GPS 1
|
||||||
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||||
//#define GPS_I2C_ADDRESS_READ 0x21
|
//#define GPS_I2C_ADDRESS_READ 0x21
|
||||||
@ -14,15 +16,15 @@
|
|||||||
//#define HAS_BUTTON GPIO_NUM_4
|
//#define HAS_BUTTON GPIO_NUM_4
|
||||||
|
|
||||||
// Hardware pin definitions for Pycom LoPy4 board
|
// Hardware pin definitions for Pycom LoPy4 board
|
||||||
#define PIN_SPI_SS GPIO_NUM_18
|
#define PIN_SPI_SS GPIO_NUM_18
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27
|
#define PIN_SPI_MOSI GPIO_NUM_27
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19
|
#define PIN_SPI_MISO GPIO_NUM_19
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5
|
#define PIN_SPI_SCK GPIO_NUM_5
|
||||||
#define RST LMIC_UNUSED_PIN
|
#define RST LMIC_UNUSED_PIN
|
||||||
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
#define DIO0 GPIO_NUM_23 // LoRa IRQ
|
||||||
#define DIO1 GPIO_NUM_23 // workaround
|
#define DIO1 GPIO_NUM_23 // workaround
|
||||||
#define DIO2 LMIC_UNUSED_PIN
|
#define DIO2 LMIC_UNUSED_PIN
|
||||||
|
|
||||||
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
// select WIFI antenna (internal = onboard / external = u.fl socket)
|
||||||
#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna
|
#define HAS_ANTENNA_SWITCH 21 // pin for switching wifi antenna
|
||||||
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
|
@ -3,20 +3,31 @@
|
|||||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||||
|
|
||||||
#define HAS_LED GPIO_NUM_21 // on board green LED_G1
|
#define HAS_LED GPIO_NUM_21 // on board green LED_G1
|
||||||
//#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset button) !! seems not to work!!
|
//#define HAS_BUTTON GPIO_NUM_39 // on board button "BOOT" (next to reset
|
||||||
#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
// button) !! seems not to work!!
|
||||||
|
#define HAS_BATTERY_PROBE \
|
||||||
|
ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||||
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
||||||
#define HAS_GPS 1 // use on board GPS
|
#define HAS_GPS 1 // use on board GPS
|
||||||
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M or 7M with default configuration
|
#define GPS_SERIAL \
|
||||||
|
9600, SERIAL_8N1, GPIO_NUM_12, \
|
||||||
|
GPIO_NUM_15 // UBlox NEO 6M or 7M with default configuration
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
// Input
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
#define PIN_SPI_MOSI \
|
||||||
|
GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#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_33 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !!
|
#define DIO1 GPIO_NUM_33 // Lora1 <-> HPD13A IO1 // !! NEEDS EXTERNAL WIRING !!
|
||||||
#define DIO2 LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not necessary for LoRa, only FSK
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // Lora2 <-> HPD13A IO2 // needs external wiring, but not
|
||||||
|
// necessary for LoRa, only FSK
|
||||||
|
@ -4,21 +4,34 @@
|
|||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
||||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||||
#define HAS_LED GPIO_NUM_2 // white LED on board
|
#define HAS_LED GPIO_NUM_2 // white LED on board
|
||||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||||
#define HAS_BUTTON GPIO_NUM_0 // button "PRG" on board
|
#define HAS_BUTTON GPIO_NUM_0 // button "PRG" on board
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input
|
GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- SX1276 NSS (Pin19) SPI Chip Select
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
// Input
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input
|
#define PIN_SPI_MOSI \
|
||||||
|
GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- SX1276 MOSI (Pin18) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- SX1276 MISO (Pin17) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- SX1276 SCK (Pin16) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#define RST GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger Input
|
#define RST \
|
||||||
#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for detecting LoRa RX_Done & TX_Done
|
GPIO_NUM_14 // ESP32 GPIO14 (Pin14) -- SX1276 NRESET (Pin7) Reset Trigger
|
||||||
#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for detecting LoRa RX_Timeout
|
// Input
|
||||||
#define DIO2 LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by LMIC for LoRa (Timeout for FSK only)
|
#define DIO0 \
|
||||||
|
GPIO_NUM_26 // ESP32 GPIO26 (Pin15) -- SX1276 DIO0 (Pin8) used by LMIC for
|
||||||
|
// detecting LoRa RX_Done & TX_Done
|
||||||
|
#define DIO1 \
|
||||||
|
GPIO_NUM_33 // ESP32 GPIO33 (Pin13) -- SX1276 DIO1 (Pin9) used by LMIC for
|
||||||
|
// detecting LoRa RX_Timeout
|
||||||
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // 32 ESP32 GPIO32 (Pin12) -- SX1276 DIO2 (Pin10) not used by
|
||||||
|
// LMIC for LoRa (Timeout for FSK only)
|
||||||
|
|
||||||
// Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display
|
// Hardware pin definitions for TTGOv1 Board with OLED SSD1306 I2C Display
|
||||||
#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset
|
#define OLED_RST GPIO_NUM_16 // ESP32 GPIO16 (Pin16) -- SD1306 Reset
|
||||||
|
@ -4,28 +4,37 @@
|
|||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||||
#define HAS_LED NOT_A_PIN // on-board LED is wired to SCL (used by display) therefore totally useless
|
#define HAS_LED \
|
||||||
|
NOT_A_PIN // on-board LED is wired to SCL (used by display) therefore totally
|
||||||
|
// useless
|
||||||
|
|
||||||
// disable brownout detection (needed on TTGOv2 for battery powered operation)
|
// disable brownout detection (needed on TTGOv2 for battery powered operation)
|
||||||
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
// Input
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
#define PIN_SPI_MOSI \
|
||||||
|
GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#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 wired on PCB to HPD13A
|
#define DIO0 GPIO_NUM_26 // ESP32 GPIO26 wired on PCB to HPD13A
|
||||||
#define DIO1 GPIO_NUM_33 // HPDIO1 on pcb, needs to be wired external to GPIO33
|
#define DIO1 GPIO_NUM_33 // HPDIO1 on pcb, needs to be wired external to GPIO33
|
||||||
#define DIO2 LMIC_UNUSED_PIN // 32 HPDIO2 on pcb, needs to be wired external to GPIO32 (not necessary for LoRa, only FSK)
|
#define DIO2 \
|
||||||
|
LMIC_UNUSED_PIN // 32 HPDIO2 on pcb, needs to be wired external to GPIO32 (not
|
||||||
|
// necessary for LoRa, only FSK)
|
||||||
|
|
||||||
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display
|
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C
|
||||||
|
// Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
||||||
#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
||||||
#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ESP32 LoRa module (SPI) OLED display (I2C)
|
ESP32 LoRa module (SPI) OLED display (I2C)
|
||||||
@ -48,6 +57,6 @@
|
|||||||
{2} Must be manually wired!
|
{2} Must be manually wired!
|
||||||
DIO2 is wired to a separate pin but is not wired on-board to pin/GPIO32.
|
DIO2 is wired to a separate pin but is not wired on-board to pin/GPIO32.
|
||||||
Explicitly wire board pin labeled DIO2 to pin 32 (see TTGO V2.0 pinout).
|
Explicitly wire board pin labeled DIO2 to pin 32 (see TTGO V2.0 pinout).
|
||||||
{3} The on-board LED is wired to SCL (used by display) therefore totally useless!
|
{3} The on-board LED is wired to SCL (used by display) therefore totally
|
||||||
|
useless!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3,24 +3,32 @@
|
|||||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||||
|
|
||||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
#define DISPLAY_FLIP 1 // rotated display
|
#define DISPLAY_FLIP 1 // rotated display
|
||||||
#define HAS_LED GPIO_NUM_23 // green on board LED_G3 (not in initial board version)
|
#define HAS_LED \
|
||||||
#define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
GPIO_NUM_23 // green on board LED_G3 (not in initial board version)
|
||||||
|
#define HAS_BATTERY_PROBE \
|
||||||
|
ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||||
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
#define BATT_FACTOR 2 // voltage divider 100k/100k on board
|
||||||
|
|
||||||
// re-define pin definitions of pins_arduino.h
|
// re-define pin definitions of pins_arduino.h
|
||||||
#define PIN_SPI_SS GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select Input
|
#define PIN_SPI_SS \
|
||||||
#define PIN_SPI_MOSI GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
GPIO_NUM_18 // ESP32 GPIO18 (Pin18) -- HPD13A NSS/SEL (Pin4) SPI Chip Select
|
||||||
#define PIN_SPI_MISO GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
// Input
|
||||||
#define PIN_SPI_SCK GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
#define PIN_SPI_MOSI \
|
||||||
|
GPIO_NUM_27 // ESP32 GPIO27 (Pin27) -- HPD13A MOSI/DSI (Pin6) SPI Data Input
|
||||||
|
#define PIN_SPI_MISO \
|
||||||
|
GPIO_NUM_19 // ESP32 GPIO19 (Pin19) -- HPD13A MISO/DSO (Pin7) SPI Data Output
|
||||||
|
#define PIN_SPI_SCK \
|
||||||
|
GPIO_NUM_5 // ESP32 GPIO5 (Pin5) -- HPD13A SCK (Pin5) SPI Clock Input
|
||||||
|
|
||||||
// non arduino pin definitions
|
// non arduino pin definitions
|
||||||
#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_33 // ESP32 GPIO33 <-> HPDIO1 <-> HPD13A IO1
|
#define DIO1 GPIO_NUM_33 // ESP32 GPIO33 <-> HPDIO1 <-> HPD13A IO1
|
||||||
#define DIO2 GPIO_NUM_32 // ESP32 GPIO32 <-> HPDIO2 <-> HPD13A IO2
|
#define DIO2 GPIO_NUM_32 // ESP32 GPIO32 <-> HPDIO2 <-> HPD13A IO2
|
||||||
|
|
||||||
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C Display
|
// Hardware pin definitions for TTGO V2 Board with OLED SSD1306 0,96" I2C
|
||||||
|
// Display
|
||||||
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
#define OLED_RST U8X8_PIN_NONE // connected to CPU RST/EN
|
||||||
#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
#define OLED_SDA GPIO_NUM_21 // ESP32 GPIO4 (Pin4) -- SD1306 D1+D2
|
||||||
#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
#define OLED_SCL GPIO_NUM_22 // ESP32 GPIO15 (Pin15) -- SD1306 D0
|
@ -1,28 +1,31 @@
|
|||||||
/************************************************************
|
/************************************************************
|
||||||
* LMIC LoRaWAN configuration
|
* LMIC LoRaWAN configuration
|
||||||
*
|
*
|
||||||
* Read the values from TTN console (or whatever applies), insert them here,
|
* Read the values from TTN console (or whatever applies), insert them here,
|
||||||
* 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,
|
||||||
* the DEVEUI will be overwriten by the one contained in the Microchip module
|
* the DEVEUI will be overwriten by the one contained in the Microchip module
|
||||||
*
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
static const u1_t DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
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};
|
386
src/lorawan.cpp
386
src/lorawan.cpp
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
// LMIC-Arduino LoRaWAN Stack
|
// LMIC-Arduino LoRaWAN Stack
|
||||||
#include "loraconf.h"
|
#include "loraconf.h"
|
||||||
#include <lmic.h>
|
|
||||||
#include <hal/hal.h>
|
#include <hal/hal.h>
|
||||||
|
#include <lmic.h>
|
||||||
|
|
||||||
#ifdef MCP_24AA02E64_I2C_ADDRESS
|
#ifdef MCP_24AA02E64_I2C_ADDRESS
|
||||||
#include <Wire.h> // Needed for 24AA02E64, does not hurt anything if included and not used
|
#include <Wire.h> // Needed for 24AA02E64, does not hurt anything if included and not used
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Local logging Tag
|
// Local logging Tag
|
||||||
@ -19,219 +19,257 @@ void switch_lora(uint8_t sf, uint8_t tx);
|
|||||||
|
|
||||||
// DevEUI generator using devices's MAC address
|
// DevEUI generator using devices's MAC address
|
||||||
void gen_lora_deveui(uint8_t *pdeveui) {
|
void gen_lora_deveui(uint8_t *pdeveui) {
|
||||||
uint8_t *p = pdeveui, dmac[6];
|
uint8_t *p = pdeveui, dmac[6];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
esp_efuse_mac_get_default(dmac);
|
esp_efuse_mac_get_default(dmac);
|
||||||
// deveui is LSB, we reverse it so TTN DEVEUI display
|
// deveui is LSB, we reverse it so TTN DEVEUI display
|
||||||
// will remain the same as MAC address
|
// will remain the same as MAC address
|
||||||
// MAC is 6 bytes, devEUI 8, set first 2 ones
|
// MAC is 6 bytes, devEUI 8, set first 2 ones
|
||||||
// with an arbitrary value
|
// with an arbitrary value
|
||||||
*p++ = 0xFF;
|
*p++ = 0xFF;
|
||||||
*p++ = 0xFE;
|
*p++ = 0xFE;
|
||||||
// Then next 6 bytes are mac address reversed
|
// Then next 6 bytes are mac address reversed
|
||||||
for ( i=0; i<6 ; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
*p++ = dmac[5-i];
|
*p++ = dmac[5 - i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to do a byte swap in a byte array
|
// Function to do a byte swap in a byte array
|
||||||
void RevBytes(unsigned char* b, size_t c)
|
void RevBytes(unsigned char *b, size_t c) {
|
||||||
{
|
|
||||||
u1_t i;
|
u1_t i;
|
||||||
for (i = 0; i < c / 2; i++)
|
for (i = 0; i < c / 2; i++) {
|
||||||
{ unsigned char t = b[i];
|
unsigned char t = b[i];
|
||||||
b[i] = b[c - 1 - i];
|
b[i] = b[c - 1 - i];
|
||||||
b[c - 1 - i] = t; }
|
b[c - 1 - i] = t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_hard_deveui(uint8_t *pdeveui) {
|
void get_hard_deveui(uint8_t *pdeveui) {
|
||||||
// read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present
|
// read DEVEUI from Microchip 24AA02E64 2Kb serial eeprom if present
|
||||||
#ifdef MCP_24AA02E64_I2C_ADDRESS
|
#ifdef MCP_24AA02E64_I2C_ADDRESS
|
||||||
uint8_t i2c_ret;
|
uint8_t i2c_ret;
|
||||||
// Init this just in case, no more to 100KHz
|
// Init this just in case, no more to 100KHz
|
||||||
Wire.begin(OLED_SDA, OLED_SCL, 100000);
|
Wire.begin(OLED_SDA, OLED_SCL, 100000);
|
||||||
|
Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS);
|
||||||
|
Wire.write(MCP_24AA02E64_MAC_ADDRESS);
|
||||||
|
i2c_ret = Wire.endTransmission();
|
||||||
|
// check if device seen on i2c bus
|
||||||
|
if (i2c_ret == 0) {
|
||||||
|
char deveui[32] = "";
|
||||||
|
uint8_t data;
|
||||||
Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS);
|
Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS);
|
||||||
Wire.write(MCP_24AA02E64_MAC_ADDRESS);
|
Wire.write(MCP_24AA02E64_MAC_ADDRESS);
|
||||||
i2c_ret = Wire.endTransmission();
|
Wire.requestFrom(MCP_24AA02E64_I2C_ADDRESS, 8);
|
||||||
// check if device seen on i2c bus
|
while (Wire.available()) {
|
||||||
if (i2c_ret == 0) {
|
data = Wire.read();
|
||||||
char deveui[32]="";
|
sprintf(deveui + strlen(deveui), "%02X ", data);
|
||||||
uint8_t data;
|
*pdeveui++ = data;
|
||||||
Wire.beginTransmission(MCP_24AA02E64_I2C_ADDRESS);
|
|
||||||
Wire.write(MCP_24AA02E64_MAC_ADDRESS);
|
|
||||||
Wire.requestFrom(MCP_24AA02E64_I2C_ADDRESS, 8);
|
|
||||||
while (Wire.available()) {
|
|
||||||
data = Wire.read();
|
|
||||||
sprintf(deveui+strlen(deveui), "%02X ", data);
|
|
||||||
*pdeveui++ = data;
|
|
||||||
}
|
|
||||||
i2c_ret = Wire.endTransmission();
|
|
||||||
ESP_LOGI(TAG, "Serial EEPROM 24AA02E64 found, read DEVEUI %s", deveui);
|
|
||||||
} else {
|
|
||||||
ESP_LOGI(TAG, "Serial EEPROM 24AA02E64 not found ret=%d", i2c_ret);
|
|
||||||
}
|
}
|
||||||
// Set back to 400KHz to speed up OLED
|
i2c_ret = Wire.endTransmission();
|
||||||
Wire.setClock(400000);
|
ESP_LOGI(TAG, "Serial EEPROM 24AA02E64 found, read DEVEUI %s", deveui);
|
||||||
#endif // MCP 24AA02E64
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Serial EEPROM 24AA02E64 not found ret=%d", i2c_ret);
|
||||||
|
}
|
||||||
|
// Set back to 400KHz to speed up OLED
|
||||||
|
Wire.setClock(400000);
|
||||||
|
#endif // MCP 24AA02E64
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
|
|
||||||
// Display a key
|
// Display a key
|
||||||
void printKey(const char * name, const uint8_t * key, uint8_t len, bool lsb) {
|
void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb) {
|
||||||
const uint8_t * p ;
|
const uint8_t *p;
|
||||||
char keystring[len+1] = "", keybyte[3];
|
char keystring[len + 1] = "", keybyte[3];
|
||||||
for (uint8_t i=0; i<len ; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
p = lsb ? key+len-i-1 : key+i;
|
p = lsb ? key + len - i - 1 : key + i;
|
||||||
sprintf(keybyte, "%02X", * p);
|
sprintf(keybyte, "%02X", *p);
|
||||||
strncat(keystring, keybyte, 2);
|
strncat(keystring, keybyte, 2);
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "%s: %s", name, keystring);
|
ESP_LOGI(TAG, "%s: %s", name, keystring);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display OTAA keys
|
// Display OTAA keys
|
||||||
void printKeys(void) {
|
void printKeys(void) {
|
||||||
// LMIC may not have used callback to fill
|
// LMIC may not have used callback to fill
|
||||||
// all EUI buffer so we do it here to a temp
|
// all EUI buffer so we do it here to a temp
|
||||||
// buffer to be able to display them
|
// buffer to be able to display them
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
os_getDevEui((u1_t*) buf);
|
os_getDevEui((u1_t *)buf);
|
||||||
printKey("DevEUI", buf, 8, true);
|
printKey("DevEUI", buf, 8, true);
|
||||||
os_getArtEui((u1_t*) buf);
|
os_getArtEui((u1_t *)buf);
|
||||||
printKey("AppEUI", buf, 8, true);
|
printKey("AppEUI", buf, 8, true);
|
||||||
os_getDevKey((u1_t*) buf);
|
os_getDevKey((u1_t *)buf);
|
||||||
printKey("AppKey", buf, 16, false);
|
printKey("AppKey", buf, 16, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // VERBOSE
|
#endif // VERBOSE
|
||||||
|
|
||||||
void do_send(osjob_t* j){
|
void do_send(osjob_t *j) {
|
||||||
|
|
||||||
// Check if there is a pending TX/RX job running
|
// Check if there is a pending TX/RX job running
|
||||||
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");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare payload with sum of unique WIFI MACs seen
|
// prepare payload with sum of unique WIFI MACs seen
|
||||||
static uint8_t mydata[4];
|
static uint8_t mydata[4];
|
||||||
|
|
||||||
mydata[0] = (macs_wifi & 0xff00) >> 8;
|
mydata[0] = (macs_wifi & 0xff00) >> 8;
|
||||||
mydata[1] = macs_wifi & 0xff;
|
mydata[1] = macs_wifi & 0xff;
|
||||||
|
|
||||||
if (cfg.blescan) {
|
|
||||||
// append sum of unique BLE MACs seen to payload
|
|
||||||
mydata[2] = (macs_ble & 0xff00) >> 8;
|
|
||||||
mydata[3] = macs_ble & 0xff;
|
|
||||||
} else {
|
|
||||||
mydata[2] = 0;
|
|
||||||
mydata[3] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAS_GPS
|
if (cfg.blescan) {
|
||||||
static uint8_t gpsdata[18];
|
// append sum of unique BLE MACs seen to payload
|
||||||
if (cfg.gpsmode && gps.location.isValid()) {
|
mydata[2] = (macs_ble & 0xff00) >> 8;
|
||||||
gps_read();
|
mydata[3] = macs_ble & 0xff;
|
||||||
memcpy (gpsdata, mydata, 4);
|
} else {
|
||||||
memcpy (gpsdata+4, &gps_status, sizeof(gps_status));
|
mydata[2] = 0;
|
||||||
ESP_LOGI(TAG, "lat=%.6f / lon=%.6f | %u Sats | HDOP=%.1f | Altitude=%u m", \
|
mydata[3] = 0;
|
||||||
gps_status.latitude / (float) 1000000, \
|
}
|
||||||
gps_status.longitude / (float) 1000000, \
|
|
||||||
gps_status.satellites, \
|
|
||||||
gps_status.hdop / (float) 100, \
|
|
||||||
gps_status.altitude);
|
|
||||||
LMIC_setTxData2(COUNTERPORT, gpsdata, sizeof(gpsdata), (cfg.countermode & 0x02));
|
|
||||||
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(gpsdata));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#endif
|
|
||||||
LMIC_setTxData2(COUNTERPORT, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
|
||||||
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata));
|
|
||||||
sprintf(display_lmic, "PACKET QUEUED");
|
|
||||||
|
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
}
|
static uint8_t gpsdata[18];
|
||||||
#endif
|
if (cfg.gpsmode && gps.location.isValid()) {
|
||||||
|
gps_read();
|
||||||
// clear counter if not in cumulative counter mode
|
memcpy(gpsdata, mydata, 4);
|
||||||
if (cfg.countermode != 1) {
|
memcpy(gpsdata + 4, &gps_status, sizeof(gps_status));
|
||||||
reset_counters(); // clear macs container and reset all counters
|
ESP_LOGI(TAG, "lat=%.6f / lon=%.6f | %u Sats | HDOP=%.1f | Altitude=%u m",
|
||||||
reset_salt(); // get new salt for salting hashes
|
gps_status.latitude / (float)1000000,
|
||||||
ESP_LOGI(TAG, "Counter cleared (countermode = %d)", cfg.countermode);
|
gps_status.longitude / (float)1000000, gps_status.satellites,
|
||||||
}
|
gps_status.hdop / (float)100, gps_status.altitude);
|
||||||
|
LMIC_setTxData2(COUNTERPORT, gpsdata, sizeof(gpsdata),
|
||||||
|
(cfg.countermode & 0x02));
|
||||||
|
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(gpsdata));
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
LMIC_setTxData2(COUNTERPORT, mydata, sizeof(mydata),
|
||||||
|
(cfg.countermode & 0x02));
|
||||||
|
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata));
|
||||||
|
sprintf(display_lmic, "PACKET QUEUED");
|
||||||
|
|
||||||
// Schedule next transmission
|
#ifdef HAS_GPS
|
||||||
end:
|
}
|
||||||
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(cfg.sendcycle * 2), do_send);
|
#endif
|
||||||
|
|
||||||
|
// clear counter if not in cumulative counter mode
|
||||||
|
if (cfg.countermode != 1) {
|
||||||
|
reset_counters(); // clear macs container and reset all counters
|
||||||
|
reset_salt(); // get new salt for salting hashes
|
||||||
|
ESP_LOGI(TAG, "Counter cleared (countermode = %d)", cfg.countermode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule next transmission
|
||||||
|
end:
|
||||||
|
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(cfg.sendcycle * 2),
|
||||||
|
do_send);
|
||||||
|
|
||||||
} // do_send()
|
} // do_send()
|
||||||
|
|
||||||
void onEvent (ev_t ev) {
|
void onEvent(ev_t ev) {
|
||||||
char buff[24]="";
|
char buff[24] = "";
|
||||||
|
|
||||||
switch(ev) {
|
switch (ev) {
|
||||||
case EV_SCAN_TIMEOUT: strcpy_P(buff, PSTR("SCAN TIMEOUT")); break;
|
case EV_SCAN_TIMEOUT:
|
||||||
case EV_BEACON_FOUND: strcpy_P(buff, PSTR("BEACON FOUND")); break;
|
strcpy_P(buff, PSTR("SCAN TIMEOUT"));
|
||||||
case EV_BEACON_MISSED: strcpy_P(buff, PSTR("BEACON MISSED")); break;
|
break;
|
||||||
case EV_BEACON_TRACKED: strcpy_P(buff, PSTR("BEACON TRACKED")); break;
|
case EV_BEACON_FOUND:
|
||||||
case EV_JOINING: strcpy_P(buff, PSTR("JOINING")); break;
|
strcpy_P(buff, PSTR("BEACON FOUND"));
|
||||||
case EV_LOST_TSYNC: strcpy_P(buff, PSTR("LOST TSYNC")); break;
|
break;
|
||||||
case EV_RESET: strcpy_P(buff, PSTR("RESET")); break;
|
case EV_BEACON_MISSED:
|
||||||
case EV_RXCOMPLETE: strcpy_P(buff, PSTR("RX COMPLETE")); break;
|
strcpy_P(buff, PSTR("BEACON MISSED"));
|
||||||
case EV_LINK_DEAD: strcpy_P(buff, PSTR("LINK DEAD")); break;
|
break;
|
||||||
case EV_LINK_ALIVE: strcpy_P(buff, PSTR("LINK ALIVE")); break;
|
case EV_BEACON_TRACKED:
|
||||||
case EV_RFU1: strcpy_P(buff, PSTR("RFUI")); break;
|
strcpy_P(buff, PSTR("BEACON TRACKED"));
|
||||||
case EV_JOIN_FAILED: strcpy_P(buff, PSTR("JOIN FAILED")); break;
|
break;
|
||||||
case EV_REJOIN_FAILED: strcpy_P(buff, PSTR("REJOIN FAILED")); break;
|
case EV_JOINING:
|
||||||
|
strcpy_P(buff, PSTR("JOINING"));
|
||||||
case EV_JOINED:
|
break;
|
||||||
|
case EV_LOST_TSYNC:
|
||||||
|
strcpy_P(buff, PSTR("LOST TSYNC"));
|
||||||
|
break;
|
||||||
|
case EV_RESET:
|
||||||
|
strcpy_P(buff, PSTR("RESET"));
|
||||||
|
break;
|
||||||
|
case EV_RXCOMPLETE:
|
||||||
|
strcpy_P(buff, PSTR("RX COMPLETE"));
|
||||||
|
break;
|
||||||
|
case EV_LINK_DEAD:
|
||||||
|
strcpy_P(buff, PSTR("LINK DEAD"));
|
||||||
|
break;
|
||||||
|
case EV_LINK_ALIVE:
|
||||||
|
strcpy_P(buff, PSTR("LINK ALIVE"));
|
||||||
|
break;
|
||||||
|
case EV_RFU1:
|
||||||
|
strcpy_P(buff, PSTR("RFUI"));
|
||||||
|
break;
|
||||||
|
case EV_JOIN_FAILED:
|
||||||
|
strcpy_P(buff, PSTR("JOIN FAILED"));
|
||||||
|
break;
|
||||||
|
case EV_REJOIN_FAILED:
|
||||||
|
strcpy_P(buff, PSTR("REJOIN FAILED"));
|
||||||
|
break;
|
||||||
|
|
||||||
strcpy_P(buff, PSTR("JOINED"));
|
case EV_JOINED:
|
||||||
sprintf(display_lora, " "); // clear previous lmic status message from display
|
|
||||||
|
|
||||||
// set data rate adaptation
|
strcpy_P(buff, PSTR("JOINED"));
|
||||||
LMIC_setAdrMode(cfg.adrmode);
|
sprintf(display_lora,
|
||||||
// Set data rate and transmit power (note: txpower seems to be ignored by the library)
|
" "); // clear previous lmic status message from display
|
||||||
switch_lora(cfg.lorasf,cfg.txpower);
|
|
||||||
|
|
||||||
// show effective LoRa parameters after join
|
|
||||||
ESP_LOGI(TAG, "ADR=%d, SF=%d, TXPOWER=%d", cfg.adrmode, cfg.lorasf, cfg.txpower);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EV_TXCOMPLETE:
|
// set data rate adaptation
|
||||||
|
LMIC_setAdrMode(cfg.adrmode);
|
||||||
|
// Set data rate and transmit power (note: txpower seems to be ignored by
|
||||||
|
// the library)
|
||||||
|
switch_lora(cfg.lorasf, cfg.txpower);
|
||||||
|
|
||||||
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") : PSTR("TX COMPLETE"));
|
// show effective LoRa parameters after join
|
||||||
sprintf(display_lora, " "); // clear previous lmic status message from display
|
ESP_LOGI(TAG, "ADR=%d, SF=%d, TXPOWER=%d", cfg.adrmode, cfg.lorasf,
|
||||||
|
cfg.txpower);
|
||||||
if (LMIC.dataLen) {
|
break;
|
||||||
ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", LMIC.dataLen, LMIC.rssi, (signed char)LMIC.snr / 4);
|
|
||||||
// LMIC.snr = SNR twos compliment [dB] * 4
|
|
||||||
// LMIC.rssi = RSSI [dBm] (-196...+63)
|
|
||||||
sprintf(display_lora, "RSSI %d SNR %d", LMIC.rssi, (signed char)LMIC.snr / 4 );
|
|
||||||
|
|
||||||
// check if payload received on command port, then call remote command interpreter
|
case EV_TXCOMPLETE:
|
||||||
if ( (LMIC.txrxFlags & TXRX_PORT) && (LMIC.frame[LMIC.dataBeg-1] == RCMDPORT ) ) {
|
|
||||||
// caution: buffering LMIC values here because rcommand() can modify LMIC.frame
|
|
||||||
unsigned char* buffer = new unsigned char[MAX_LEN_FRAME];
|
|
||||||
memcpy(buffer, LMIC.frame, MAX_LEN_FRAME); //Copy data from cfg to char*
|
|
||||||
int i, k = LMIC.dataBeg, l = LMIC.dataBeg+LMIC.dataLen-2;
|
|
||||||
for (i=k; i<=l; i+=2) {
|
|
||||||
rcommand(buffer[i], buffer[i+1]);
|
|
||||||
}
|
|
||||||
delete[] buffer; //free memory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: sprintf_P(buff, PSTR("UNKNOWN EVENT %d"), ev); break;
|
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK")
|
||||||
|
: PSTR("TX COMPLETE"));
|
||||||
|
sprintf(display_lora,
|
||||||
|
" "); // clear previous lmic status message from display
|
||||||
|
|
||||||
|
if (LMIC.dataLen) {
|
||||||
|
ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d",
|
||||||
|
LMIC.dataLen, LMIC.rssi, (signed char)LMIC.snr / 4);
|
||||||
|
// LMIC.snr = SNR twos compliment [dB] * 4
|
||||||
|
// LMIC.rssi = RSSI [dBm] (-196...+63)
|
||||||
|
sprintf(display_lora, "RSSI %d SNR %d", LMIC.rssi,
|
||||||
|
(signed char)LMIC.snr / 4);
|
||||||
|
|
||||||
|
// check if payload received on command port, then call remote command
|
||||||
|
// interpreter
|
||||||
|
if ((LMIC.txrxFlags & TXRX_PORT) &&
|
||||||
|
(LMIC.frame[LMIC.dataBeg - 1] == RCMDPORT)) {
|
||||||
|
// caution: buffering LMIC values here because rcommand() can modify
|
||||||
|
// LMIC.frame
|
||||||
|
unsigned char *buffer = new unsigned char[MAX_LEN_FRAME];
|
||||||
|
memcpy(buffer, LMIC.frame, MAX_LEN_FRAME); // Copy data from cfg to
|
||||||
|
// char*
|
||||||
|
int i, k = LMIC.dataBeg, l = LMIC.dataBeg + LMIC.dataLen - 2;
|
||||||
|
for (i = k; i <= l; i += 2) {
|
||||||
|
rcommand(buffer[i], buffer[i + 1]);
|
||||||
|
}
|
||||||
|
delete[] buffer; // free memory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sprintf_P(buff, PSTR("UNKNOWN EVENT %d"), ev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log & Display if asked
|
||||||
|
if (*buff) {
|
||||||
|
ESP_LOGI(TAG, "EV_%s", buff);
|
||||||
|
sprintf(display_lmic, buff);
|
||||||
|
}
|
||||||
|
|
||||||
// Log & Display if asked
|
|
||||||
if (*buff) {
|
|
||||||
ESP_LOGI(TAG, "EV_%s", buff);
|
|
||||||
sprintf(display_lmic, buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // onEvent()
|
} // onEvent()
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#define LORAWAN_H
|
#define LORAWAN_H
|
||||||
|
|
||||||
void onEvent(ev_t ev);
|
void onEvent(ev_t ev);
|
||||||
void do_send(osjob_t* j);
|
void do_send(osjob_t *j);
|
||||||
void gen_lora_deveui(uint8_t * pdeveui);
|
void gen_lora_deveui(uint8_t *pdeveui);
|
||||||
void RevBytes(unsigned char* b, size_t c);
|
void RevBytes(unsigned char *b, size_t c);
|
||||||
void get_hard_deveui(uint8_t *pdeveui);
|
void get_hard_deveui(uint8_t *pdeveui);
|
||||||
|
|
||||||
#endif
|
#endif
|
176
src/macsniff.cpp
176
src/macsniff.cpp
@ -3,114 +3,136 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
#ifdef VENDORFILTER
|
#ifdef VENDORFILTER
|
||||||
#include "vendor_array.h"
|
#include "vendor_array.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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(
|
||||||
return salt;
|
65536); // get new 16bit random for salting hashes and set global salt var
|
||||||
|
return salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||||
|
|
||||||
char buff[16]; // temporary buffer for printf
|
char buff[16]; // temporary buffer for printf
|
||||||
bool added = false;
|
bool added = false;
|
||||||
uint32_t addr2int, vendor2int; // temporary buffer for MAC and Vendor OUI
|
uint32_t addr2int, vendor2int; // temporary buffer for MAC and Vendor OUI
|
||||||
uint16_t hashedmac; // temporary buffer for generated hash value
|
uint16_t hashedmac; // temporary buffer for generated hash value
|
||||||
|
|
||||||
// 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) |
|
||||||
// use OUI vendor filter list only on Wifi, not on BLE
|
((uint32_t)paddr[0] << 16);
|
||||||
if ( (sniff_type==MAC_SNIFF_BLE) || std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end() )
|
// use OUI vendor filter list only on Wifi, not on BLE
|
||||||
{
|
if ((sniff_type == MAC_SNIFF_BLE) ||
|
||||||
#endif
|
std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end()) {
|
||||||
|
#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
|
||||||
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
|
// and increment counter on display
|
||||||
|
// https://en.wikipedia.org/wiki/MAC_Address_Anonymization
|
||||||
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
|
addr2int += (uint32_t)salt; // add 16-bit salt to pseudo MAC
|
||||||
hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars to fit hash in uint16_t container
|
snprintf(
|
||||||
auto newmac = macs.insert(hashedmac); // add hashed MAC to total container if new unique
|
buff, sizeof(buff), "%08X",
|
||||||
added = newmac.second ? true:false; // true if hashed MAC is unique in container
|
addr2int); // convert unsigned 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 to total container 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) {
|
||||||
// increment counter and one blink led
|
// increment counter and one blink led
|
||||||
if (sniff_type == MAC_SNIFF_WIFI ) {
|
if (sniff_type == MAC_SNIFF_WIFI) {
|
||||||
macs_wifi++; // increment Wifi MACs counter
|
macs_wifi++; // increment Wifi MACs counter
|
||||||
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||||
blink_LED(COLOR_GREEN, 50);
|
blink_LED(COLOR_GREEN, 50);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
else if (sniff_type == MAC_SNIFF_BLE ) {
|
else if (sniff_type == MAC_SNIFF_BLE) {
|
||||||
macs_ble++; // increment BLE Macs counter
|
macs_ble++; // increment BLE Macs counter
|
||||||
#if (HAS_LED != NOT_A_PIN) || defined (HAS_RGB_LED)
|
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||||
blink_LED(COLOR_MAGENTA, 50);
|
blink_LED(COLOR_MAGENTA, 50);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,
|
||||||
added ? "new " : "known",
|
"%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d -> "
|
||||||
sniff_type==MAC_SNIFF_WIFI ? "WiFi":"BLTH",
|
"%d Bytes left",
|
||||||
rssi, buff, hashedmac, macs_wifi, macs_ble,
|
added ? "new " : "known",
|
||||||
ESP.getFreeHeap());
|
sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff,
|
||||||
|
hashedmac, macs_wifi, macs_ble, 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 = {
|
||||||
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // configure Wifi with cfg
|
.filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // we need only MGMT frames
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country)); // set locales for RF and channels
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // configure Wifi with cfg
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM
|
ESP_ERROR_CHECK(
|
||||||
//ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
|
esp_wifi_set_country(&wifi_country)); // set locales for RF and channels
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter
|
ESP_ERROR_CHECK(
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler));
|
esp_wifi_set_storage(WIFI_STORAGE_RAM)); // we don't need NVRAM
|
||||||
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
|
// 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_rx_cb(&wifi_sniffer_packet_handler));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode
|
||||||
}
|
}
|
||||||
|
|
||||||
void wifi_sniffer_set_channel(uint8_t channel) {
|
void wifi_sniffer_set_channel(uint8_t channel) {
|
||||||
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,
|
||||||
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
|
wifi_promiscuous_pkt_type_t type) {
|
||||||
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
|
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
|
||||||
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
|
const wifi_ieee80211_packet_t *ipkt =
|
||||||
|
(wifi_ieee80211_packet_t *)ppkt->payload;
|
||||||
if ((cfg.rssilimit) && (ppkt->rx_ctrl.rssi < cfg.rssilimit )) { // rssi is negative value
|
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
|
||||||
ESP_LOGI(TAG, "WiFi RSSI %d -> ignoring (limit: %d)", ppkt->rx_ctrl.rssi, cfg.rssilimit);
|
|
||||||
} else {
|
|
||||||
uint8_t *p = (uint8_t *) hdr->addr2;
|
|
||||||
mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((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 {
|
||||||
|
uint8_t *p = (uint8_t *)hdr->addr2;
|
||||||
|
mac_add(p, ppkt->rx_ctrl.rssi, MAC_SNIFF_WIFI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,21 +5,21 @@
|
|||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
#define MAC_SNIFF_WIFI 0
|
#define MAC_SNIFF_WIFI 0
|
||||||
#define MAC_SNIFF_BLE 1
|
#define MAC_SNIFF_BLE 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned frame_ctrl:16;
|
unsigned frame_ctrl : 16;
|
||||||
unsigned duration_id:16;
|
unsigned duration_id : 16;
|
||||||
uint8_t addr1[6]; /* receiver address */
|
uint8_t addr1[6]; /* receiver address */
|
||||||
uint8_t addr2[6]; /* sender address */
|
uint8_t addr2[6]; /* sender address */
|
||||||
uint8_t addr3[6]; /* filtering address */
|
uint8_t addr3[6]; /* filtering address */
|
||||||
unsigned sequence_ctrl:16;
|
unsigned sequence_ctrl : 16;
|
||||||
uint8_t addr4[6]; /* optional */
|
uint8_t addr4[6]; /* optional */
|
||||||
} wifi_ieee80211_mac_hdr_t;
|
} wifi_ieee80211_mac_hdr_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
wifi_ieee80211_mac_hdr_t hdr;
|
wifi_ieee80211_mac_hdr_t hdr;
|
||||||
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
|
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
|
||||||
} wifi_ieee80211_packet_t;
|
} wifi_ieee80211_packet_t;
|
||||||
|
|
||||||
uint16_t reset_salt(void);
|
uint16_t reset_salt(void);
|
||||||
@ -28,6 +28,6 @@ void wifi_sniffer_set_channel(uint8_t channel);
|
|||||||
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);
|
||||||
|
|
||||||
// function defined in rokkithash.cpp
|
// function defined in rokkithash.cpp
|
||||||
uint32_t rokkit(const char * , int );
|
uint32_t rokkit(const char *, int);
|
||||||
|
|
||||||
#endif
|
#endif
|
953
src/main.cpp
953
src/main.cpp
File diff suppressed because it is too large
Load Diff
29
src/main.h
29
src/main.h
@ -3,21 +3,19 @@
|
|||||||
#include "lorawan.h"
|
#include "lorawan.h"
|
||||||
#include "macsniff.h"
|
#include "macsniff.h"
|
||||||
|
|
||||||
// program version - note: increment version after modifications to configData_t struct!!
|
// program version - note: increment version after modifications to configData_t
|
||||||
#define PROGVERSION "1.3.8" // use max 10 chars here!
|
// struct!!
|
||||||
#define PROGNAME "PAXCNT"
|
#define PROGVERSION "1.3.8" // use max 10 chars here!
|
||||||
|
#define PROGNAME "PAXCNT"
|
||||||
|
|
||||||
//--- 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"};
|
||||||
#elif defined(CFG_us915)
|
#elif defined(CFG_us915)
|
||||||
const char lora_datarate[] = {"100908078CNA121110090807"};
|
const char lora_datarate[] = {"100908078CNA121110090807"};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--- Prototypes ---
|
//--- Prototypes ---
|
||||||
@ -27,15 +25,14 @@ 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);
|
||||||
void stop_BLEscan(void);
|
void stop_BLEscan(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//defined in gpsread.cpp
|
// defined in gpsread.cpp
|
||||||
#ifdef HAS_GPS
|
#ifdef HAS_GPS
|
||||||
void gps_read(void);
|
void gps_read(void);
|
||||||
void gps_loop(void * pvParameters);
|
void gps_loop(void *pvParameters);
|
||||||
#endif
|
#endif
|
487
src/rcommand.cpp
487
src/rcommand.cpp
@ -1,310 +1,365 @@
|
|||||||
// 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"
|
||||||
|
|
||||||
// LMIC-Arduino LoRaWAN Stack
|
// LMIC-Arduino LoRaWAN Stack
|
||||||
#include <lmic.h>
|
|
||||||
#include <hal/hal.h>
|
#include <hal/hal.h>
|
||||||
|
#include <lmic.h>
|
||||||
|
|
||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = "main";
|
static const char TAG[] = "main";
|
||||||
|
|
||||||
// table of remote commands and assigned functions
|
// table of remote commands and assigned functions
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint8_t nam;
|
const uint8_t nam;
|
||||||
void (*func)(uint8_t);
|
void (*func)(uint8_t);
|
||||||
const bool store;
|
const bool store;
|
||||||
} cmd_t;
|
} cmd_t;
|
||||||
|
|
||||||
// function defined in antenna.cpp
|
// function defined in antenna.cpp
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
void antenna_select(const uint8_t _ant);
|
void antenna_select(const uint8_t _ant);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// function defined in adcread.cpp
|
// function defined in adcread.cpp
|
||||||
#ifdef HAS_BATTERY_PROBE
|
#ifdef HAS_BATTERY_PROBE
|
||||||
uint32_t read_voltage(void);
|
uint32_t read_voltage(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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
|
||||||
if (LMIC.opmode & OP_TXRXPEND) {
|
// transmission
|
||||||
ESP_LOGI(TAG, "LoRa busy, rescheduling");
|
if (LMIC.opmode & OP_TXRXPEND) {
|
||||||
sprintf(display_lmic, "LORA BUSY");
|
ESP_LOGI(TAG, "LoRa busy, rescheduling");
|
||||||
os_setTimedCallback(&rcmdjob, os_getTime()+sec2osticks(RETRANSMIT_RCMD), do_transmit);
|
sprintf(display_lmic, "LORA BUSY");
|
||||||
}
|
os_setTimedCallback(&rcmdjob, os_getTime() + sec2osticks(RETRANSMIT_RCMD),
|
||||||
LMIC_setTxData2(RCMDPORT, rcmd_data, rcmd_data_size, 0); // send data unconfirmed on RCMD Port
|
do_transmit);
|
||||||
ESP_LOGI(TAG, "%d bytes queued to send", rcmd_data_size);
|
}
|
||||||
sprintf(display_lmic, "PACKET QUEUED");
|
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);
|
||||||
|
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
|
||||||
void transmit(xref2u1_t mydata, u1_t mydata_size){
|
// do_transmit() cannot have params
|
||||||
rcmd_data = mydata;
|
void transmit(xref2u1_t mydata, u1_t mydata_size) {
|
||||||
rcmd_data_size = mydata_size;
|
rcmd_data = mydata;
|
||||||
do_transmit(&rcmdjob);
|
rcmd_data_size = mydata_size;
|
||||||
|
do_transmit(&rcmdjob);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
cfg.txpower = tx;
|
return;
|
||||||
switch (sf) {
|
cfg.txpower = tx;
|
||||||
case 7: LMIC_setDrTxpow(DR_SF7,tx); cfg.lorasf=sf; break;
|
switch (sf) {
|
||||||
case 8: LMIC_setDrTxpow(DR_SF8,tx); cfg.lorasf=sf; break;
|
case 7:
|
||||||
case 9: LMIC_setDrTxpow(DR_SF9,tx); cfg.lorasf=sf; break;
|
LMIC_setDrTxpow(DR_SF7, tx);
|
||||||
case 10: LMIC_setDrTxpow(DR_SF10,tx); cfg.lorasf=sf; break;
|
cfg.lorasf = sf;
|
||||||
case 11:
|
break;
|
||||||
#if defined(CFG_eu868)
|
case 8:
|
||||||
LMIC_setDrTxpow(DR_SF11,tx); cfg.lorasf=sf; break;
|
LMIC_setDrTxpow(DR_SF8, tx);
|
||||||
#elif defined(CFG_us915)
|
cfg.lorasf = sf;
|
||||||
LMIC_setDrTxpow(DR_SF11CR,tx); cfg.lorasf=sf; break;
|
break;
|
||||||
#endif
|
case 9:
|
||||||
case 12:
|
LMIC_setDrTxpow(DR_SF9, tx);
|
||||||
#if defined(CFG_eu868)
|
cfg.lorasf = sf;
|
||||||
LMIC_setDrTxpow(DR_SF12,tx); cfg.lorasf=sf; break;
|
break;
|
||||||
#elif defined(CFG_us915)
|
case 10:
|
||||||
LMIC_setDrTxpow(DR_SF12CR,tx); cfg.lorasf=sf; break;
|
LMIC_setDrTxpow(DR_SF10, tx);
|
||||||
#endif
|
cfg.lorasf = sf;
|
||||||
default: break;
|
break;
|
||||||
}
|
case 11:
|
||||||
|
#if defined(CFG_eu868)
|
||||||
|
LMIC_setDrTxpow(DR_SF11, tx);
|
||||||
|
cfg.lorasf = sf;
|
||||||
|
break;
|
||||||
|
#elif defined(CFG_us915)
|
||||||
|
LMIC_setDrTxpow(DR_SF11CR, tx);
|
||||||
|
cfg.lorasf = sf;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 12:
|
||||||
|
#if defined(CFG_eu868)
|
||||||
|
LMIC_setDrTxpow(DR_SF12, tx);
|
||||||
|
cfg.lorasf = sf;
|
||||||
|
break;
|
||||||
|
#elif defined(CFG_us915)
|
||||||
|
LMIC_setDrTxpow(DR_SF12CR, tx);
|
||||||
|
cfg.lorasf = sf;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set of functions that can be triggered by remote commands
|
// set of functions that can be triggered by remote commands
|
||||||
void set_reset(uint8_t val) {
|
void set_reset(uint8_t val) {
|
||||||
switch (val) {
|
switch (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(
|
||||||
esp_restart();
|
10000 /
|
||||||
break;
|
portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
|
||||||
case 1: // reset MAC counter
|
esp_restart();
|
||||||
ESP_LOGI(TAG, "Remote command: reset MAC counter");
|
break;
|
||||||
reset_counters(); // clear macs
|
case 1: // reset MAC counter
|
||||||
reset_salt(); // get new salt
|
ESP_LOGI(TAG, "Remote command: reset MAC counter");
|
||||||
sprintf(display_lora, "Reset counter");
|
reset_counters(); // clear macs
|
||||||
break;
|
reset_salt(); // get new salt
|
||||||
case 2: // reset device to factory settings
|
sprintf(display_lora, "Reset counter");
|
||||||
ESP_LOGI(TAG, "Remote command: reset device to factory settings");
|
break;
|
||||||
sprintf(display_lora, "Factory reset");
|
case 2: // reset device to factory settings
|
||||||
eraseConfig();
|
ESP_LOGI(TAG, "Remote command: reset device to factory settings");
|
||||||
break;
|
sprintf(display_lora, "Factory reset");
|
||||||
}
|
eraseConfig();
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_rssi(uint8_t val) {
|
void set_rssi(uint8_t val) {
|
||||||
cfg.rssilimit = val * -1;
|
cfg.rssilimit = val * -1;
|
||||||
ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit);
|
ESP_LOGI(TAG, "Remote command: set RSSI limit to %d", cfg.rssilimit);
|
||||||
};
|
};
|
||||||
|
|
||||||
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",
|
||||||
#ifdef BLECOUNTER
|
cfg.blescantime / float(100));
|
||||||
// stop & restart BLE scan task to apply new parameter
|
#ifdef BLECOUNTER
|
||||||
if (cfg.blescan)
|
// stop & restart BLE scan task to apply new parameter
|
||||||
{
|
if (cfg.blescan) {
|
||||||
stop_BLEscan();
|
stop_BLEscan();
|
||||||
start_BLEscan();
|
start_BLEscan();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_countmode(uint8_t val) {
|
void set_countmode(uint8_t val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 0: // cyclic unconfirmed
|
case 0: // cyclic unconfirmed
|
||||||
cfg.countermode = 0;
|
cfg.countermode = 0;
|
||||||
ESP_LOGI(TAG, "Remote command: set counter mode to cyclic unconfirmed");
|
ESP_LOGI(TAG, "Remote command: set counter mode to cyclic unconfirmed");
|
||||||
break;
|
break;
|
||||||
case 1: // cumulative
|
case 1: // cumulative
|
||||||
cfg.countermode = 1;
|
cfg.countermode = 1;
|
||||||
ESP_LOGI(TAG, "Remote command: set counter mode to cumulative");
|
ESP_LOGI(TAG, "Remote command: set counter mode to cumulative");
|
||||||
break;
|
break;
|
||||||
default: // cyclic confirmed
|
default: // cyclic confirmed
|
||||||
cfg.countermode = 2;
|
cfg.countermode = 2;
|
||||||
ESP_LOGI(TAG, "Remote command: set counter mode to cyclic confirmed");
|
ESP_LOGI(TAG, "Remote command: set counter mode to cyclic confirmed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_lorasf(uint8_t val) {
|
void set_lorasf(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val);
|
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val);
|
||||||
switch_lora(val, cfg.txpower);
|
switch_lora(val, cfg.txpower);
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
LMIC_setAdrMode(cfg.adrmode);
|
default:
|
||||||
|
cfg.adrmode = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LMIC_setAdrMode(cfg.adrmode);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_blescan(uint8_t val) {
|
void set_blescan(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set BLE scanner to %s", val ? "on" : "off");
|
ESP_LOGI(TAG, "Remote command: set BLE scanner to %s", val ? "on" : "off");
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case 0:
|
case 0:
|
||||||
cfg.blescan = 0;
|
cfg.blescan = 0;
|
||||||
macs_ble = 0; // clear BLE counter
|
macs_ble = 0; // clear BLE counter
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
stop_BLEscan();
|
stop_BLEscan();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cfg.blescan = 1;
|
cfg.blescan = 1;
|
||||||
#ifdef BLECOUNTER
|
#ifdef BLECOUNTER
|
||||||
start_BLEscan();
|
start_BLEscan();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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",
|
||||||
switch (val) {
|
val ? "external" : "internal");
|
||||||
case 1: cfg.wifiant = val; break;
|
switch (val) {
|
||||||
default: cfg.wifiant = 0; break;
|
case 1:
|
||||||
}
|
cfg.wifiant = val;
|
||||||
#ifdef HAS_ANTENNA_SWITCH
|
break;
|
||||||
antenna_select(cfg.wifiant);
|
default:
|
||||||
#endif
|
cfg.wifiant = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef HAS_ANTENNA_SWITCH
|
||||||
|
antenna_select(cfg.wifiant);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
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",
|
||||||
switch (val) {
|
val ? "on" : "off");
|
||||||
case 1: cfg.vendorfilter = val; break;
|
switch (val) {
|
||||||
default: cfg.vendorfilter = 0; break;
|
case 1:
|
||||||
}
|
cfg.vendorfilter = val;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cfg.vendorfilter = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_rgblum(uint8_t val) {
|
void set_rgblum(uint8_t val) {
|
||||||
// Avoid wrong parameters
|
// Avoid wrong parameters
|
||||||
cfg.rgblum = (val>=0 && val<=100) ? (uint8_t) val : RGBLUMINOSITY;
|
cfg.rgblum = (val >= 0 && val <= 100) ? (uint8_t)val : RGBLUMINOSITY;
|
||||||
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
|
ESP_LOGI(TAG, "Remote command: set RGB Led luminosity %d", cfg.rgblum);
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_lorapower(uint8_t val) {
|
void set_lorapower(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val);
|
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val);
|
||||||
switch_lora(cfg.lorasf, val);
|
switch_lora(cfg.lorasf, val);
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_config (uint8_t val) {
|
void get_config(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get configuration");
|
ESP_LOGI(TAG, "Remote command: get configuration");
|
||||||
transmit((byte*)&cfg, sizeof(cfg));
|
transmit((byte *)&cfg, sizeof(cfg));
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_uptime (uint8_t val) {
|
void get_uptime(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get uptime");
|
ESP_LOGI(TAG, "Remote command: get uptime");
|
||||||
transmit((byte*)&uptimecounter, sizeof(uptimecounter));
|
transmit((byte *)&uptimecounter, sizeof(uptimecounter));
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_cputemp (uint8_t val) {
|
void get_cputemp(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get cpu temperature");
|
ESP_LOGI(TAG, "Remote command: get cpu temperature");
|
||||||
float temp = temperatureRead();
|
float temp = temperatureRead();
|
||||||
transmit((byte*)&temp, sizeof(temp));
|
transmit((byte *)&temp, sizeof(temp));
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_voltage (uint8_t val) {
|
void get_voltage(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get battery voltage");
|
ESP_LOGI(TAG, "Remote command: get battery voltage");
|
||||||
#ifdef HAS_BATTERY_PROBE
|
#ifdef HAS_BATTERY_PROBE
|
||||||
uint16_t voltage = read_voltage();
|
uint16_t voltage = read_voltage();
|
||||||
#else
|
#else
|
||||||
uint16_t voltage = 0;
|
uint16_t voltage = 0;
|
||||||
#endif
|
#endif
|
||||||
transmit((byte*)&voltage, sizeof(voltage));
|
transmit((byte *)&voltage, sizeof(voltage));
|
||||||
};
|
};
|
||||||
|
|
||||||
void get_gps (uint8_t val) {
|
void get_gps(uint8_t val) {
|
||||||
ESP_LOGI(TAG, "Remote command: get gps status");
|
ESP_LOGI(TAG, "Remote command: get gps status");
|
||||||
#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",
|
||||||
#else
|
gps_status.latitude / 1000000, gps_status.longitude / 1000000,
|
||||||
ESP_LOGE(TAG, "GPS not present");
|
gps_status.satellites, gps_status.hdop, gps_status.altitude);
|
||||||
#endif
|
#else
|
||||||
|
ESP_LOGE(TAG, "GPS not present");
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 =
|
||||||
bool store_flag = false;
|
sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||||
while(i--) {
|
bool store_flag = false;
|
||||||
if(cmd == table[i].nam) { // check if valid command
|
while (i--) {
|
||||||
table[i].func(arg); // then execute assigned function
|
if (cmd == table[i].nam) { // check if valid command
|
||||||
if ( table[i].store ) store_flag = true; // set save flag if function needs to store configuration
|
table[i].func(arg); // then execute assigned function
|
||||||
break; // exit check loop, since command was found
|
if (table[i].store)
|
||||||
}
|
store_flag =
|
||||||
|
true; // set save flag if function needs to store configuration
|
||||||
|
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
|
||||||
}
|
}
|
@ -6,23 +6,22 @@
|
|||||||
// 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)
|
t -= 1.0f;
|
||||||
t -= 1.0f;
|
|
||||||
|
|
||||||
if (t < 1.0f / 6.0f)
|
if (t < 1.0f / 6.0f)
|
||||||
return p + (q - p) * 6.0f * t;
|
return p + (q - p) * 6.0f * t;
|
||||||
|
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
return q;
|
return q;
|
||||||
|
|
||||||
if (t < 2.0f / 3.0f)
|
if (t < 2.0f / 3.0f)
|
||||||
return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
|
return p + ((q - p) * (2.0f / 3.0f - t) * 6.0f);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -30,45 +29,41 @@ 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 {
|
||||||
}
|
float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
|
||||||
else
|
float p = 2.0f * l - q;
|
||||||
{
|
r = rgb_CalcColor(p, q, h + 1.0f / 3.0f);
|
||||||
float q = l < 0.5f ? l * (1.0f + s) : l + s - (l * s);
|
g = rgb_CalcColor(p, q, h);
|
||||||
float p = 2.0f * l - q;
|
b = rgb_CalcColor(p, q, h - 1.0f / 3.0f);
|
||||||
r = rgb_CalcColor(p, q, h + 1.0f / 3.0f);
|
}
|
||||||
g = rgb_CalcColor(p, q, h);
|
|
||||||
b = rgb_CalcColor(p, q, h - 1.0f / 3.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
RGB_color.R = (uint8_t)(r * 255.0f);
|
RGB_color.R = (uint8_t)(r * 255.0f);
|
||||||
RGB_color.G = (uint8_t)(g * 255.0f);
|
RGB_color.G = (uint8_t)(g * 255.0f);
|
||||||
RGB_color.B = (uint8_t)(b * 255.0f);
|
RGB_color.B = (uint8_t)(b * 255.0f);
|
||||||
|
|
||||||
return RGB_color;
|
return RGB_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_set_color(uint16_t hue) {
|
void rgb_set_color(uint16_t hue) {
|
||||||
if (hue == COLOR_NONE) {
|
if (hue == COLOR_NONE) {
|
||||||
// Off
|
// Off
|
||||||
rgb_led[0] = Rgb(0,0,0);
|
rgb_led[0] = Rgb(0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
|
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
|
||||||
// H (is color from 0..360) should be between 0.0 and 1.0
|
// H (is color from 0..360) should be between 0.0 and 1.0
|
||||||
// S is saturation keep it to 1
|
// S is saturation keep it to 1
|
||||||
// L is brightness should be between 0.0 and 0.5
|
// L is brightness should be between 0.0 and 0.5
|
||||||
// cfg.rgblum is between 0 and 100 (percent)
|
// cfg.rgblum is between 0 and 100 (percent)
|
||||||
RGBColor target = rgb_hsl2rgb( hue / 360.0f, 1.0f, 0.005f * cfg.rgblum);
|
RGBColor target = rgb_hsl2rgb(hue / 360.0f, 1.0f, 0.005f * cfg.rgblum);
|
||||||
//uint32_t color = target.R<<16 | target.G<<8 | target.B;
|
// uint32_t color = target.R<<16 | target.G<<8 | target.B;
|
||||||
rgb_led[0] = Rgb(target.R, target.G, target.B);
|
rgb_led[0] = Rgb(target.R, target.G, target.B);
|
||||||
}
|
}
|
||||||
// Show
|
// Show
|
||||||
|
@ -3,27 +3,26 @@
|
|||||||
|
|
||||||
// value for HSL color
|
// value for HSL color
|
||||||
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
|
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
|
||||||
#define COLOR_RED 0
|
#define COLOR_RED 0
|
||||||
#define COLOR_ORANGE 30
|
#define COLOR_ORANGE 30
|
||||||
#define COLOR_ORANGE_YELLOW 45
|
#define COLOR_ORANGE_YELLOW 45
|
||||||
#define COLOR_YELLOW 60
|
#define COLOR_YELLOW 60
|
||||||
#define COLOR_YELLOW_GREEN 90
|
#define COLOR_YELLOW_GREEN 90
|
||||||
#define COLOR_GREEN 120
|
#define COLOR_GREEN 120
|
||||||
#define COLOR_GREEN_CYAN 165
|
#define COLOR_GREEN_CYAN 165
|
||||||
#define COLOR_CYAN 180
|
#define COLOR_CYAN 180
|
||||||
#define COLOR_CYAN_BLUE 210
|
#define COLOR_CYAN_BLUE 210
|
||||||
#define COLOR_BLUE 240
|
#define COLOR_BLUE 240
|
||||||
#define COLOR_BLUE_MAGENTA 275
|
#define COLOR_BLUE_MAGENTA 275
|
||||||
#define COLOR_MAGENTA 300
|
#define COLOR_MAGENTA 300
|
||||||
#define COLOR_PINK 350
|
#define COLOR_PINK 350
|
||||||
#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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exported Functions
|
// Exported Functions
|
||||||
|
@ -36,48 +36,52 @@
|
|||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
uint32_t rokkit(const char * data, int len) {
|
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)
|
||||||
hash = len;
|
return 0;
|
||||||
rem = len & 3;
|
hash = len;
|
||||||
len >>= 2;
|
rem = len & 3;
|
||||||
|
len >>= 2;
|
||||||
|
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
hash += *((uint16_t*)data);
|
hash += *((uint16_t *)data);
|
||||||
tmp = (*((uint16_t*)(data+2)) << 11) ^ hash;
|
tmp = (*((uint16_t *)(data + 2)) << 11) ^ hash;
|
||||||
hash = (hash << 16) ^ tmp;
|
hash = (hash << 16) ^ tmp;
|
||||||
data += 2*2;
|
data += 2 * 2;
|
||||||
hash += hash >> 11;
|
hash += hash >> 11;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle end cases */
|
/* Handle end cases */
|
||||||
switch (rem) {
|
switch (rem) {
|
||||||
case 3: hash += *((uint16_t*)data);
|
case 3:
|
||||||
hash ^= hash << 16;
|
hash += *((uint16_t *)data);
|
||||||
hash ^= ((signed char)data[2]) << 18;
|
hash ^= hash << 16;
|
||||||
hash += hash >> 11;
|
hash ^= ((signed char)data[2]) << 18;
|
||||||
break;
|
hash += hash >> 11;
|
||||||
case 2: hash += *((uint16_t*)data);
|
break;
|
||||||
hash ^= hash << 11;
|
case 2:
|
||||||
hash += hash >> 17;
|
hash += *((uint16_t *)data);
|
||||||
break;
|
hash ^= hash << 11;
|
||||||
case 1: hash += (signed char)*data;
|
|
||||||
hash ^= hash << 10;
|
|
||||||
hash += hash >> 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force "avalanching" of final 127 bits */
|
|
||||||
hash ^= hash << 3;
|
|
||||||
hash += hash >> 5;
|
|
||||||
hash ^= hash << 4;
|
|
||||||
hash += hash >> 17;
|
hash += hash >> 17;
|
||||||
hash ^= hash << 25;
|
break;
|
||||||
hash += hash >> 6;
|
case 1:
|
||||||
|
hash += (signed char)*data;
|
||||||
|
hash ^= hash << 10;
|
||||||
|
hash += hash >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
return hash;
|
/* Force "avalanching" of final 127 bits */
|
||||||
|
hash ^= hash << 3;
|
||||||
|
hash += hash >> 5;
|
||||||
|
hash ^= hash << 4;
|
||||||
|
hash += hash >> 17;
|
||||||
|
hash ^= hash << 25;
|
||||||
|
hash += hash >> 6;
|
||||||
|
|
||||||
|
return hash;
|
||||||
}
|
}
|
||||||
|
1639
src/vendor_array.h
1639
src/vendor_array.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user