mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-08 06:02:05 +00:00
Compare commits
15 Commits
cd6e8e0e68
...
8263557f21
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8263557f21 | ||
![]() |
46c7d74760 | ||
![]() |
15d2ae17f8 | ||
![]() |
91579c4650 | ||
![]() |
79b710a108 | ||
![]() |
917b6d0cd7 | ||
![]() |
f5898e0b4d | ||
![]() |
cf1e1e5373 | ||
![]() |
66560fbcfa | ||
![]() |
657eb93c44 | ||
![]() |
d9dc4b7008 | ||
![]() |
c7e44a2301 | ||
![]() |
fa17273631 | ||
![]() |
c211384f12 | ||
![]() |
f1b892ce56 |
@ -9,7 +9,7 @@ plugins:
|
||||
lint:
|
||||
enabled:
|
||||
- checkov@3.2.436
|
||||
- renovate@40.41.0
|
||||
- renovate@40.42.2
|
||||
- prettier@3.5.3
|
||||
- trufflehog@3.88.35
|
||||
- yamllint@1.37.1
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 24c7a3d287a4bd269ce191827e5dabd8ce8f57a7
|
||||
Subproject commit db60f07ac298b6161ca553b3868b542cceadcac4
|
@ -337,12 +337,12 @@ void setup()
|
||||
|
||||
#ifdef LED_POWER
|
||||
pinMode(LED_POWER, OUTPUT);
|
||||
digitalWrite(LED_POWER, HIGH);
|
||||
digitalWrite(LED_POWER, LED_STATE_ON);
|
||||
#endif
|
||||
|
||||
#ifdef USER_LED
|
||||
pinMode(USER_LED, OUTPUT);
|
||||
digitalWrite(USER_LED, LOW);
|
||||
digitalWrite(USER_LED, HIGH ^ LED_STATE_ON);
|
||||
#endif
|
||||
|
||||
#if defined(T_DECK)
|
||||
|
@ -92,10 +92,9 @@ bool CryptoEngine::encryptCurve25519(uint32_t toNode, uint32_t fromNode, meshtas
|
||||
LOG_DEBUG("Node %d or their public_key not found", toNode);
|
||||
return false;
|
||||
}
|
||||
if (!crypto->setDHPublicKey(remotePublic.bytes)) {
|
||||
if (!setCryptoSharedSecret(remotePublic)) {
|
||||
return false;
|
||||
}
|
||||
crypto->hash(shared_key, 32);
|
||||
initNonce(fromNode, packetNum, extraNonceTmp);
|
||||
|
||||
// Calculate the shared secret with the destination node and encrypt
|
||||
@ -134,10 +133,9 @@ bool CryptoEngine::decryptCurve25519(uint32_t fromNode, meshtastic_UserLite_publ
|
||||
}
|
||||
|
||||
// Calculate the shared secret with the sending node and decrypt
|
||||
if (!crypto->setDHPublicKey(remotePublic.bytes)) {
|
||||
if (!setCryptoSharedSecret(remotePublic)) {
|
||||
return false;
|
||||
}
|
||||
crypto->hash(shared_key, 32);
|
||||
|
||||
initNonce(fromNode, packetNum, extraNonce);
|
||||
printBytes("Attempt decrypt with nonce: ", nonce, 13);
|
||||
@ -266,6 +264,69 @@ void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetId, uint32_t extr
|
||||
if (extraNonce)
|
||||
memcpy(nonce + sizeof(uint32_t), &extraNonce, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
bool CryptoEngine::setCryptoSharedSecret(meshtastic_UserLite_public_key_t pubkey)
|
||||
{
|
||||
// The last used timestamp is in units of ~1.165 hours, which gives us
|
||||
// ~12.3 days before the timestamps roll over. This is ok since a periodic
|
||||
// misfire on evicting the oldest secret has very little impact.
|
||||
const uint8_t now = (millis() >> 22) & 0xff;
|
||||
|
||||
// Get a short lookup key from the pubkey
|
||||
uint32_t lookupKey;
|
||||
memcpy(&lookupKey, pubkey.bytes, sizeof(lookupKey));
|
||||
|
||||
uint16_t oldestDelta = 0;
|
||||
size_t oldestIndex = 0;
|
||||
for (size_t i = 0; i < MAX_CACHED_SHARED_SECRETS; i++) {
|
||||
CachedSharedSecret &entry = sharedSecretCache[i];
|
||||
if (entry.lookup_key == lookupKey) {
|
||||
// Cache hit! Copy it into shared_key.
|
||||
memcpy(shared_key, entry.shared_secret, 32);
|
||||
// Update the last used timestamp
|
||||
entry.last_used = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sharedSecretCache[oldestIndex].lookup_key == 0) {
|
||||
// We already have a valid slot to insert into. Keep looking for a cache hit.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.lookup_key == 0) {
|
||||
// This entry is empty. We can insert into it later, if needed.
|
||||
oldestIndex = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Track the oldest entry in case the cache is full.
|
||||
uint16_t delta = 0;
|
||||
if (now >= entry.last_used) {
|
||||
delta = now - entry.last_used;
|
||||
} else {
|
||||
// Assume a larger last used timestamp is further in the past
|
||||
delta = uint16_t(0x100) + now - entry.last_used;
|
||||
}
|
||||
if (delta > oldestDelta) {
|
||||
oldestIndex = i;
|
||||
oldestDelta = delta;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache miss. Generate the shared secret.
|
||||
if (!setDHPublicKey(pubkey.bytes)) {
|
||||
return false;
|
||||
}
|
||||
hash(shared_key, 32);
|
||||
|
||||
// Insert the calculated shared secret into the cache, overwriting an old entry if needed.
|
||||
CachedSharedSecret &oldestEntry = sharedSecretCache[oldestIndex];
|
||||
oldestEntry.lookup_key = lookupKey;
|
||||
oldestEntry.last_used = now;
|
||||
memcpy(oldestEntry.shared_secret, shared_key, 32);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef HAS_CUSTOM_CRYPTO_ENGINE
|
||||
CryptoEngine *crypto = new CryptoEngine;
|
||||
#endif
|
||||
|
@ -15,6 +15,12 @@ struct CryptoKey {
|
||||
int8_t length;
|
||||
};
|
||||
|
||||
struct CachedSharedSecret {
|
||||
uint32_t lookup_key;
|
||||
uint8_t shared_secret[32];
|
||||
uint8_t last_used;
|
||||
};
|
||||
|
||||
/**
|
||||
* see docs/software/crypto.md for details.
|
||||
*
|
||||
@ -23,6 +29,18 @@ struct CryptoKey {
|
||||
#define MAX_BLOCKSIZE 256
|
||||
#define TEST_CURVE25519_FIELD_OPS // Exposes Curve25519::isWeakPoint() for testing keys
|
||||
|
||||
/**
|
||||
* Max number of cached secrets to track. This should be roughly dependent on MAX_NUM_NODES but
|
||||
* cannot be directly because it is not a constant expression.
|
||||
*/
|
||||
#if defined(ARCH_STM32WL)
|
||||
#define MAX_CACHED_SHARED_SECRETS 2
|
||||
#elif defined(ARCH_NRF52)
|
||||
#define MAX_CACHED_SHARED_SECRETS 8
|
||||
#else
|
||||
#define MAX_CACHED_SHARED_SECRETS 10
|
||||
#endif
|
||||
|
||||
class CryptoEngine
|
||||
{
|
||||
public:
|
||||
@ -92,6 +110,19 @@ class CryptoEngine
|
||||
* a 32 bit block counter (starts at zero)
|
||||
*/
|
||||
void initNonce(uint32_t fromNode, uint64_t packetId, uint32_t extraNonce = 0);
|
||||
|
||||
/**
|
||||
* Cache mapping peers' public keys -> {shared_secret, last_used}
|
||||
*/
|
||||
CachedSharedSecret sharedSecretCache[MAX_CACHED_SHARED_SECRETS] = {0};
|
||||
|
||||
/**
|
||||
* Set cryptographic (hashed) shared_key calculated from the given pubkey
|
||||
*/
|
||||
bool setCryptoSharedSecret(meshtastic_UserLite_public_key_t pubkey);
|
||||
|
||||
// Allow unit test harness to peer into private/protected members
|
||||
friend struct TestCryptoEngine;
|
||||
};
|
||||
|
||||
extern CryptoEngine *crypto;
|
@ -65,6 +65,8 @@ PB_BIND(meshtastic_Config_SessionkeyConfig, meshtastic_Config_SessionkeyConfig,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -88,6 +88,23 @@ typedef enum _meshtastic_Config_DeviceConfig_RebroadcastMode {
|
||||
meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY = 5
|
||||
} meshtastic_Config_DeviceConfig_RebroadcastMode;
|
||||
|
||||
/* Defines buzzer behavior for audio feedback */
|
||||
typedef enum _meshtastic_Config_DeviceConfig_BuzzerMode {
|
||||
/* Default behavior.
|
||||
Buzzer is enabled for all audio feedback including button presses and alerts. */
|
||||
meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED = 0,
|
||||
/* Disabled.
|
||||
All buzzer audio feedback is disabled. */
|
||||
meshtastic_Config_DeviceConfig_BuzzerMode_DISABLED = 1,
|
||||
/* Notifications Only.
|
||||
Buzzer is enabled only for notifications and alerts, but not for button presses.
|
||||
External notification config determines the specifics of the notification behavior. */
|
||||
meshtastic_Config_DeviceConfig_BuzzerMode_NOTIFICATIONS_ONLY = 2,
|
||||
/* Non-notification system buzzer tones only.
|
||||
Buzzer is enabled only for non-notification tones such as button presses, startup, shutdown, but not for alerts. */
|
||||
meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY = 3
|
||||
} meshtastic_Config_DeviceConfig_BuzzerMode;
|
||||
|
||||
/* Bit field of boolean configuration options, indicating which optional
|
||||
fields to include when assembling POSITION messages.
|
||||
Longitude, latitude, altitude, speed, heading, and DOP
|
||||
@ -335,6 +352,9 @@ typedef struct _meshtastic_Config_DeviceConfig {
|
||||
char tzdef[65];
|
||||
/* If true, disable the default blinking LED (LED_PIN) behavior on the device */
|
||||
bool led_heartbeat_disabled;
|
||||
/* Controls buzzer behavior for audio feedback
|
||||
Defaults to ENABLED */
|
||||
meshtastic_Config_DeviceConfig_BuzzerMode buzzer_mode;
|
||||
} meshtastic_Config_DeviceConfig;
|
||||
|
||||
/* Position Config */
|
||||
@ -618,6 +638,10 @@ extern "C" {
|
||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_MAX meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY
|
||||
#define _meshtastic_Config_DeviceConfig_RebroadcastMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_RebroadcastMode)(meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY+1))
|
||||
|
||||
#define _meshtastic_Config_DeviceConfig_BuzzerMode_MIN meshtastic_Config_DeviceConfig_BuzzerMode_ALL_ENABLED
|
||||
#define _meshtastic_Config_DeviceConfig_BuzzerMode_MAX meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY
|
||||
#define _meshtastic_Config_DeviceConfig_BuzzerMode_ARRAYSIZE ((meshtastic_Config_DeviceConfig_BuzzerMode)(meshtastic_Config_DeviceConfig_BuzzerMode_SYSTEM_ONLY+1))
|
||||
|
||||
#define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET
|
||||
#define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED
|
||||
#define _meshtastic_Config_PositionConfig_PositionFlags_ARRAYSIZE ((meshtastic_Config_PositionConfig_PositionFlags)(meshtastic_Config_PositionConfig_PositionFlags_SPEED+1))
|
||||
@ -669,6 +693,7 @@ extern "C" {
|
||||
|
||||
#define meshtastic_Config_DeviceConfig_role_ENUMTYPE meshtastic_Config_DeviceConfig_Role
|
||||
#define meshtastic_Config_DeviceConfig_rebroadcast_mode_ENUMTYPE meshtastic_Config_DeviceConfig_RebroadcastMode
|
||||
#define meshtastic_Config_DeviceConfig_buzzer_mode_ENUMTYPE meshtastic_Config_DeviceConfig_BuzzerMode
|
||||
|
||||
#define meshtastic_Config_PositionConfig_gps_mode_ENUMTYPE meshtastic_Config_PositionConfig_GpsMode
|
||||
|
||||
@ -692,7 +717,7 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}}
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0}
|
||||
@ -703,7 +728,7 @@ extern "C" {
|
||||
#define meshtastic_Config_SecurityConfig_init_default {{0, {0}}, {0, {0}}, 0, {{0, {0}}, {0, {0}}, {0, {0}}}, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_SessionkeyConfig_init_default {0}
|
||||
#define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}}
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0, _meshtastic_Config_DeviceConfig_BuzzerMode_MIN}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0}
|
||||
@ -726,6 +751,7 @@ extern "C" {
|
||||
#define meshtastic_Config_DeviceConfig_disable_triple_click_tag 10
|
||||
#define meshtastic_Config_DeviceConfig_tzdef_tag 11
|
||||
#define meshtastic_Config_DeviceConfig_led_heartbeat_disabled_tag 12
|
||||
#define meshtastic_Config_DeviceConfig_buzzer_mode_tag 13
|
||||
#define meshtastic_Config_PositionConfig_position_broadcast_secs_tag 1
|
||||
#define meshtastic_Config_PositionConfig_position_broadcast_smart_enabled_tag 2
|
||||
#define meshtastic_Config_PositionConfig_fixed_position_tag 3
|
||||
@ -849,7 +875,8 @@ X(a, STATIC, SINGULAR, BOOL, double_tap_as_button_press, 8) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_managed, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, disable_triple_click, 10) \
|
||||
X(a, STATIC, SINGULAR, STRING, tzdef, 11) \
|
||||
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12)
|
||||
X(a, STATIC, SINGULAR, BOOL, led_heartbeat_disabled, 12) \
|
||||
X(a, STATIC, SINGULAR, UENUM, buzzer_mode, 13)
|
||||
#define meshtastic_Config_DeviceConfig_CALLBACK NULL
|
||||
#define meshtastic_Config_DeviceConfig_DEFAULT NULL
|
||||
|
||||
@ -995,7 +1022,7 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size
|
||||
#define meshtastic_Config_BluetoothConfig_size 10
|
||||
#define meshtastic_Config_DeviceConfig_size 98
|
||||
#define meshtastic_Config_DeviceConfig_size 100
|
||||
#define meshtastic_Config_DisplayConfig_size 32
|
||||
#define meshtastic_Config_LoRaConfig_size 85
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||
|
@ -55,6 +55,8 @@ typedef enum _meshtastic_Language {
|
||||
meshtastic_Language_SLOVENIAN = 15,
|
||||
/* Ukrainian */
|
||||
meshtastic_Language_UKRAINIAN = 16,
|
||||
/* Bulgarian */
|
||||
meshtastic_Language_BULGARIAN = 17,
|
||||
/* Simplified Chinese (experimental) */
|
||||
meshtastic_Language_SIMPLIFIED_CHINESE = 30,
|
||||
/* Traditional Chinese (experimental) */
|
||||
|
@ -360,7 +360,7 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* meshtastic_NodeDatabase_size depends on runtime parameters */
|
||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size
|
||||
#define meshtastic_BackupPreferences_size 2269
|
||||
#define meshtastic_BackupPreferences_size 2271
|
||||
#define meshtastic_ChannelFile_size 718
|
||||
#define meshtastic_DeviceState_size 1722
|
||||
#define meshtastic_NodeInfoLite_size 196
|
||||
|
@ -187,7 +187,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
||||
#define meshtastic_LocalConfig_size 745
|
||||
#define meshtastic_LocalConfig_size 747
|
||||
#define meshtastic_LocalModuleConfig_size 669
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -258,6 +258,12 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_EINK = 100,
|
||||
/* Reserved ID for future and past use */
|
||||
meshtastic_HardwareModel_QWANTZ_TINY_ARMS = 101,
|
||||
/* *
|
||||
Lilygo T-Deck Pro */
|
||||
meshtastic_HardwareModel_T_DECK_PRO = 102,
|
||||
/* *
|
||||
Lilygo TLora Pager */
|
||||
meshtastic_HardwareModel_T_LORA_PAGER = 103,
|
||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
|
@ -4,6 +4,19 @@
|
||||
#include "TestUtil.h"
|
||||
#include <unity.h>
|
||||
|
||||
struct TestCryptoEngine {
|
||||
static bool getCachedSecret(uint32_t lookupKey, CachedSharedSecret &entry)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_CACHED_SHARED_SECRETS; i++) {
|
||||
entry = crypto->sharedSecretCache[i];
|
||||
if (entry.lookup_key == lookupKey) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void HexToBytes(uint8_t *result, const std::string hex, size_t len = 0)
|
||||
{
|
||||
if (len) {
|
||||
@ -108,6 +121,33 @@ void test_DH25519(void)
|
||||
TEST_ASSERT(crypto->setDHPublicKey(public_key));
|
||||
crypto->hash(crypto->shared_key, 32);
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 32);
|
||||
|
||||
// Caching code path generates the same secret
|
||||
uint8_t now = (millis() >> 22) & 0xff;
|
||||
meshtastic_UserLite_public_key_t userlite_public_key;
|
||||
memcpy(userlite_public_key.bytes, public_key, 32);
|
||||
TEST_ASSERT(crypto->setCryptoSharedSecret(userlite_public_key));
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 32);
|
||||
|
||||
// Check it was added to the cache
|
||||
CachedSharedSecret entry;
|
||||
uint32_t lookupKey;
|
||||
memcpy(&lookupKey, public_key, sizeof(lookupKey));
|
||||
TEST_ASSERT(TestCryptoEngine::getCachedSecret(lookupKey, entry));
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected_shared, entry.shared_secret, 32);
|
||||
TEST_ASSERT_TRUE(entry.last_used >= now);
|
||||
|
||||
// Calling again should fetch from the cache. Shared secret is the same.
|
||||
// FIXME If tests could mock the millis() time, it would be ideal to mock the time forward by a
|
||||
// couple hours before hitting the cache.
|
||||
TEST_ASSERT(crypto->setCryptoSharedSecret(userlite_public_key));
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected_shared, crypto->shared_key, 32);
|
||||
|
||||
// Check cache was updated
|
||||
now = (millis() >> 22) & 0xff;
|
||||
TEST_ASSERT(TestCryptoEngine::getCachedSecret(lookupKey, entry));
|
||||
TEST_ASSERT_EQUAL_MEMORY(expected_shared, entry.shared_secret, 32);
|
||||
TEST_ASSERT_TRUE(entry.last_used >= now);
|
||||
}
|
||||
|
||||
void test_PKC(void)
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define GPS_POWER_TOGGLE // Moved definition from platformio.ini to here
|
||||
|
||||
#define BUTTON_PIN 39 // The middle button GPIO on the T-Beam
|
||||
// Note: On the ESP32 base version, gpio34-39 are input-only, and do not have internal pull-ups.
|
||||
// If 39 is not being used for a button, it is suggested to remove the #define.
|
||||
#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage
|
||||
#define ADC_CHANNEL ADC1_GPIO35_CHANNEL
|
||||
#define ADC_MULTIPLIER 1.85 // (R1 = 470k, R2 = 680k)
|
||||
|
Loading…
Reference in New Issue
Block a user