mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 13:24:09 +00:00
update zephyr
This commit is contained in:
@@ -347,6 +347,11 @@ message(STATUS " Board overlay: ${ZEPHCORE_BOARD_OVERLAY}")
|
||||
message(STATUS " EXTRA_CONF_FILE: ${EXTRA_CONF_FILE}")
|
||||
message(STATUS " EXTRA_DTC_OVERLAY_FILE: ${EXTRA_DTC_OVERLAY_FILE}")
|
||||
|
||||
# Upstream mbedTLS 4.x has unused-parameter warnings in ssl_misc.h / md.c that
|
||||
# fail with -Werror. Disable fatal warnings for the vendored mbedtls build.
|
||||
set(MBEDTLS_FATAL_WARNINGS OFF CACHE BOOL "" FORCE)
|
||||
set(TF_PSA_CRYPTO_FATAL_WARNINGS OFF CACHE BOOL "" FORCE)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(zephcore)
|
||||
|
||||
|
||||
@@ -412,6 +412,19 @@ void ZephyrDataStore::loadPrefs(NodePrefs &prefs)
|
||||
} else {
|
||||
prefs.leds_disabled = 0; /* Default: LEDs on */
|
||||
}
|
||||
|
||||
/* Offset 94: apc_enabled (ZephCore extension) */
|
||||
if (off < len) {
|
||||
prefs.apc_enabled = buf[off++];
|
||||
}
|
||||
|
||||
/* Offset 95: apc_margin (ZephCore extension) */
|
||||
if (off < len) {
|
||||
prefs.apc_margin = buf[off++];
|
||||
if (prefs.apc_margin < 6 || prefs.apc_margin > 30) {
|
||||
prefs.apc_margin = 20; /* companion default */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZephyrDataStore::savePrefs(const NodePrefs &prefs)
|
||||
@@ -462,7 +475,11 @@ void ZephyrDataStore::savePrefs(const NodePrefs &prefs)
|
||||
buf[off++] = prefs.rx_boost;
|
||||
/* Offset 93: leds_disabled (ZephCore extension) */
|
||||
buf[off++] = prefs.leds_disabled;
|
||||
/* Total: 94 bytes (Arduino reads 92, ZephCore reads 94) */
|
||||
/* Offset 94: apc_enabled (ZephCore extension) */
|
||||
buf[off++] = prefs.apc_enabled;
|
||||
/* Offset 95: apc_margin (ZephCore extension) */
|
||||
buf[off++] = prefs.apc_margin;
|
||||
/* Total: 96 bytes (Arduino reads 92, ZephCore reads 96) */
|
||||
|
||||
bool ok = openWrite(PREFS_FILE, buf, off);
|
||||
LOG_INF("savePrefs: wrote %s, ok=%d (%d bytes), name='%.16s'",
|
||||
|
||||
@@ -185,7 +185,8 @@ void CompanionMesh::begin()
|
||||
BaseChatMesh::begin();
|
||||
#ifdef CONFIG_ZEPHCORE_APC
|
||||
_power_ctrl.setSF(prefs.sf);
|
||||
_power_ctrl.setTargetMargin(20); /* companions are mobile — more conservative */
|
||||
_power_ctrl.setTargetMargin(prefs.apc_margin);
|
||||
_power_ctrl.setEnabled(prefs.apc_enabled != 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -809,6 +809,8 @@ void RepeaterMesh::begin(RepeaterDataStore* store) {
|
||||
_contention.setBackoffMultiplier(_prefs.backoff_multiplier);
|
||||
#ifdef CONFIG_ZEPHCORE_APC
|
||||
_power_ctrl.setSF(_prefs.sf);
|
||||
_power_ctrl.setTargetMargin(_prefs.apc_margin);
|
||||
_power_ctrl.setEnabled(_prefs.apc_enabled != 0);
|
||||
#endif
|
||||
acl.load(_store->getAclPath(), self_id);
|
||||
region_map.load(_store->getRegionsPath());
|
||||
|
||||
@@ -17,12 +17,15 @@ CONFIG_STD_CPP17=y
|
||||
# Enable floating point support in printf/sprintf (required for CLI)
|
||||
CONFIG_CBPRINTF_FP_SUPPORT=y
|
||||
|
||||
# ========== Crypto (mbedTLS) ==========
|
||||
# ========== Crypto (PSA) ==========
|
||||
# Required for mesh encryption (AES-ECB, SHA256, HMAC)
|
||||
CONFIG_MBEDTLS=y
|
||||
CONFIG_MBEDTLS_CIPHER_AES_ENABLED=y
|
||||
CONFIG_MBEDTLS_SHA256=y
|
||||
CONFIG_MBEDTLS_MD_C=y
|
||||
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
|
||||
CONFIG_PSA_WANT_ALG_SHA_256=y
|
||||
CONFIG_PSA_WANT_ALG_ECB_NO_PADDING=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_AES=y
|
||||
CONFIG_PSA_WANT_ALG_HMAC=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_HMAC=y
|
||||
|
||||
# ========== Stack Protection ==========
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
+109
-62
@@ -111,6 +111,8 @@ void CommonCLI::loadPrefs(const char* path) {
|
||||
ok = ok && prefs_read(&file, _prefs->owner_info, sizeof(_prefs->owner_info)); // 170
|
||||
ok = ok && prefs_read(&file, &_prefs->rx_boost, sizeof(_prefs->rx_boost)); // 290
|
||||
ok = ok && prefs_read(&file, &_prefs->rx_duty_cycle, sizeof(_prefs->rx_duty_cycle)); // 291
|
||||
ok = ok && prefs_read(&file, &_prefs->apc_enabled, sizeof(_prefs->apc_enabled)); // 292
|
||||
ok = ok && prefs_read(&file, &_prefs->apc_margin, sizeof(_prefs->apc_margin)); // 293
|
||||
|
||||
if (!ok) {
|
||||
LOG_WRN("Prefs file %s truncated, some fields use defaults", path);
|
||||
@@ -153,6 +155,8 @@ void CommonCLI::loadPrefs(const char* path) {
|
||||
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, (uint8_t)0, (uint8_t)2);
|
||||
_prefs->rx_boost = constrain(_prefs->rx_boost, (uint8_t)0, (uint8_t)1);
|
||||
_prefs->rx_duty_cycle = constrain(_prefs->rx_duty_cycle, (uint8_t)0, (uint8_t)1);
|
||||
_prefs->apc_enabled = constrain(_prefs->apc_enabled, (uint8_t)0, (uint8_t)1);
|
||||
_prefs->apc_margin = constrain(_prefs->apc_margin, (uint8_t)6, (uint8_t)30);
|
||||
|
||||
LOG_INF("Loaded prefs from %s", path);
|
||||
}
|
||||
@@ -216,6 +220,8 @@ void CommonCLI::savePrefs(const char* path) {
|
||||
fs_write(&file, _prefs->owner_info, sizeof(_prefs->owner_info));
|
||||
fs_write(&file, &_prefs->rx_boost, sizeof(_prefs->rx_boost));
|
||||
fs_write(&file, &_prefs->rx_duty_cycle, sizeof(_prefs->rx_duty_cycle));
|
||||
fs_write(&file, &_prefs->apc_enabled, sizeof(_prefs->apc_enabled));
|
||||
fs_write(&file, &_prefs->apc_margin, sizeof(_prefs->apc_margin));
|
||||
|
||||
fs_close(&file);
|
||||
LOG_INF("Saved prefs to %s", path);
|
||||
@@ -376,7 +382,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_callbacks->applyTempRadioParams(freq, bw, sf, cr, temp_timeout_mins);
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - temp params for %d mins", temp_timeout_mins);
|
||||
} else {
|
||||
strcpy(reply, "Error, invalid params");
|
||||
strcpy(reply, "Error: freq 300-2500, bw 7-500, sf 5-12, cr 5-8, timeout>0");
|
||||
}
|
||||
} else if (memcmp(command, "password ", 9) == 0) {
|
||||
StrHelper::strncpy(_prefs->password, &command[9], sizeof(_prefs->password));
|
||||
@@ -433,18 +439,6 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
(double)est, (double)ff);
|
||||
} else if (memcmp(config, "apc.margin", 10) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d dB", (int)_callbacks->getAPCTargetMargin());
|
||||
} else if (memcmp(config, "txpower", 7) == 0) {
|
||||
if (_callbacks->isAPCEnabled()) {
|
||||
int8_t apc = _callbacks->getAPCReduction();
|
||||
float margin = _callbacks->getAPCMargin();
|
||||
int effective = (int)_prefs->tx_power_dbm - (int)apc;
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %ddBm (max=%d apc=-%d margin=%.1f target=%d)",
|
||||
effective, (int)_prefs->tx_power_dbm, (int)apc, (double)margin,
|
||||
(int)_callbacks->getAPCTargetMargin());
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %ddBm (apc=off)",
|
||||
(int)_prefs->tx_power_dbm);
|
||||
}
|
||||
} else if (memcmp(config, "flood.max", 9) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %u", (uint32_t)_prefs->flood_max);
|
||||
} else if (memcmp(config, "direct.txdelay", 14) == 0) {
|
||||
@@ -473,7 +467,17 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
strcpy(reply, "> strict");
|
||||
}
|
||||
} else if (memcmp(config, "tx", 2) == 0 && (config[2] == 0 || config[2] == ' ')) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->tx_power_dbm);
|
||||
if (_callbacks->isAPCEnabled()) {
|
||||
int8_t apc = _callbacks->getAPCReduction();
|
||||
float margin = _callbacks->getAPCMargin();
|
||||
int effective = (int)_prefs->tx_power_dbm - (int)apc;
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %ddBm (max=%d apc=-%d margin=%.1f target=%d)",
|
||||
effective, (int)_prefs->tx_power_dbm, (int)apc, (double)margin,
|
||||
(int)_callbacks->getAPCTargetMargin());
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %ddBm (apc=off)",
|
||||
(int)_prefs->tx_power_dbm);
|
||||
}
|
||||
} else if (memcmp(config, "freq", 4) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %.3f", (double)_prefs->freq);
|
||||
} else if (memcmp(config, "public.key", 10) == 0) {
|
||||
@@ -495,6 +499,10 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %.3f", (double)adc_mult);
|
||||
}
|
||||
} else if (memcmp(config, "rxboost", 7) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->rx_boost);
|
||||
} else if (memcmp(config, "rxduty", 6) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->rx_duty_cycle);
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "??: %s", config);
|
||||
}
|
||||
@@ -505,14 +513,17 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
const char* config = &command[4];
|
||||
if (memcmp(config, "af ", 3) == 0) {
|
||||
int val = atoi(&config[3]);
|
||||
if (val <= 0 || val >= 100) {
|
||||
if (val < 0 || val > 99) {
|
||||
strcpy(reply, "Error: range 0-99 (0=unlimited)");
|
||||
} else if (val == 0) {
|
||||
_prefs->airtime_factor = 0.0f;
|
||||
savePrefs();
|
||||
strcpy(reply, "Duty Cycle set: 100% (unlimited)");
|
||||
} else {
|
||||
_prefs->airtime_factor = (float)val;
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "Duty Cycle set: %d%%", val);
|
||||
}
|
||||
savePrefs();
|
||||
int dc = (_prefs->airtime_factor == 0.0f) ? 100 : (int)_prefs->airtime_factor;
|
||||
snprintf(reply, CLI_REPLY_SIZE, "Duty Cycle set: %d%%", dc);
|
||||
} else if (memcmp(config, "int.thresh ", 11) == 0) {
|
||||
_prefs->interference_threshold = atoi(&config[11]);
|
||||
savePrefs();
|
||||
@@ -522,13 +533,26 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - interval rounded to %u", ((uint32_t)_prefs->agc_reset_interval) * 4);
|
||||
} else if (memcmp(config, "multi.acks ", 11) == 0) {
|
||||
_prefs->multi_acks = atoi(&config[11]);
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
int val = atoi(&config[11]);
|
||||
if (val == 0 || val == 1) {
|
||||
_prefs->multi_acks = (uint8_t)val;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error: must be 0 or 1");
|
||||
}
|
||||
} else if (memcmp(config, "allow.read.only ", 16) == 0) {
|
||||
_prefs->allow_read_only = memcmp(&config[16], "on", 2) == 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
if (memcmp(&config[16], "on", 2) == 0) {
|
||||
_prefs->allow_read_only = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else if (memcmp(&config[16], "off", 3) == 0) {
|
||||
_prefs->allow_read_only = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error: must be on or off");
|
||||
}
|
||||
} else if (memcmp(config, "flood.advert.interval ", 22) == 0) {
|
||||
int hours = _atoi(&config[22]);
|
||||
if ((hours > 0 && hours < 3) || (hours > 168)) {
|
||||
@@ -571,12 +595,20 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error, bad chars");
|
||||
strcpy(reply, "Error: name cannot contain [ ] \\ : , ? *");
|
||||
}
|
||||
} else if (memcmp(config, "repeat ", 7) == 0) {
|
||||
_prefs->disable_fwd = memcmp(&config[7], "off", 3) == 0;
|
||||
savePrefs();
|
||||
strcpy(reply, _prefs->disable_fwd ? "OK - repeat is now OFF" : "OK - repeat is now ON");
|
||||
if (memcmp(&config[7], "on", 2) == 0) {
|
||||
_prefs->disable_fwd = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - repeat is now ON");
|
||||
} else if (memcmp(&config[7], "off", 3) == 0) {
|
||||
_prefs->disable_fwd = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - repeat is now OFF");
|
||||
} else {
|
||||
strcpy(reply, "Error: must be on or off");
|
||||
}
|
||||
} else if (memcmp(config, "radio ", 6) == 0) {
|
||||
strcpy(tmp, &config[6]);
|
||||
const char* parts[4];
|
||||
@@ -594,7 +626,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_callbacks->savePrefs();
|
||||
strcpy(reply, "OK - reboot to apply");
|
||||
} else {
|
||||
strcpy(reply, "Error, invalid radio params");
|
||||
strcpy(reply, "Error: freq 300-2500, bw 7-500, sf 5-12, cr 5-8");
|
||||
}
|
||||
} else if (memcmp(config, "lat ", 4) == 0) {
|
||||
_prefs->node_lat = atof(&config[4]);
|
||||
@@ -613,13 +645,13 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
savePrefs();
|
||||
strcpy(reply, "OK (ignored: txdelay is now adaptive)");
|
||||
} else if (memcmp(config, "flood.max ", 10) == 0) {
|
||||
uint8_t m = atoi(&config[10]);
|
||||
if (m <= 64) {
|
||||
_prefs->flood_max = m;
|
||||
int m = atoi(&config[10]);
|
||||
if (m >= 0 && m <= 64) {
|
||||
_prefs->flood_max = (uint8_t)m;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Error, max 64");
|
||||
strcpy(reply, "Error: range 0-64");
|
||||
}
|
||||
} else if (memcmp(config, "direct.txdelay ", 15) == 0) {
|
||||
_prefs->direct_tx_delay_factor = atof(&config[15]);
|
||||
@@ -678,34 +710,47 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else if (memcmp(config, "apc.margin ", 11) == 0) {
|
||||
int val = atoi(&config[11]);
|
||||
if (val >= 6 && val <= 30) {
|
||||
_prefs->apc_margin = (uint8_t)val;
|
||||
_callbacks->setAPCTargetMargin((uint8_t)val);
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - APC target margin=%d dB", val);
|
||||
} else {
|
||||
strcpy(reply, "Error, range 6-30 dB");
|
||||
strcpy(reply, "Error: range 6-30 dB");
|
||||
}
|
||||
} else if (memcmp(config, "tx ", 3) == 0) {
|
||||
if (memcmp(&config[3], "apc", 3) == 0) {
|
||||
_prefs->apc_enabled = 1;
|
||||
_callbacks->setAPCEnabled(true);
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - tx power=%d dBm (apc=on)",
|
||||
(int)_prefs->tx_power_dbm);
|
||||
} else {
|
||||
int val = atoi(&config[3]);
|
||||
int max_tx = 30;
|
||||
#ifdef CONFIG_ZEPHCORE_MAX_TX_POWER_DBM
|
||||
if (val > CONFIG_ZEPHCORE_MAX_TX_POWER_DBM) {
|
||||
val = CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
|
||||
}
|
||||
max_tx = CONFIG_ZEPHCORE_MAX_TX_POWER_DBM;
|
||||
#endif
|
||||
_prefs->tx_power_dbm = (int8_t)val;
|
||||
savePrefs();
|
||||
_callbacks->setAPCEnabled(false);
|
||||
_callbacks->setTxPower(_prefs->tx_power_dbm);
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - tx power=%d dBm (apc=off)",
|
||||
(int)_prefs->tx_power_dbm);
|
||||
if (val < -9 || val > max_tx) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "Error: range -9 to %d dBm, or 'apc'", max_tx);
|
||||
} else {
|
||||
_prefs->apc_enabled = 0;
|
||||
_prefs->tx_power_dbm = (int8_t)val;
|
||||
savePrefs();
|
||||
_callbacks->setAPCEnabled(false);
|
||||
_callbacks->setTxPower(_prefs->tx_power_dbm);
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - tx power=%d dBm (apc=off)",
|
||||
(int)_prefs->tx_power_dbm);
|
||||
}
|
||||
}
|
||||
} else if (sender_timestamp == 0 && memcmp(config, "freq ", 5) == 0) {
|
||||
_prefs->freq = atof(&config[5]);
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - reboot to apply");
|
||||
float f = atof(&config[5]);
|
||||
if (f >= 400.0f && f <= 2500.0f) {
|
||||
_prefs->freq = f;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - reboot to apply");
|
||||
} else {
|
||||
strcpy(reply, "Error: range 400-2500 MHz");
|
||||
}
|
||||
} else if (memcmp(config, "adc.multiplier ", 15) == 0) {
|
||||
_prefs->adc_multiplier = atof(&config[15]);
|
||||
if (_board->setAdcMultiplier(_prefs->adc_multiplier)) {
|
||||
@@ -720,13 +765,23 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
strcpy(reply, "Error: unsupported by this board");
|
||||
}
|
||||
} else if (memcmp(config, "rxboost ", 8) == 0) {
|
||||
_prefs->rx_boost = atoi(&config[8]) ? 1 : 0;
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - rxboost=%d (reboot to apply)", _prefs->rx_boost);
|
||||
} else if (memcmp(config, "rxboost", 7) == 0 && (config[7] == 0 || config[7] == ' ')) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", _prefs->rx_boost);
|
||||
} else if (memcmp(config, "rxduty", 6) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "RX duty cycle disabled (continuous RX)");
|
||||
int val = atoi(&config[8]);
|
||||
if (val == 0 || val == 1) {
|
||||
_prefs->rx_boost = (uint8_t)val;
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - rxboost=%d (reboot to apply)", _prefs->rx_boost);
|
||||
} else {
|
||||
strcpy(reply, "Error: must be 0 or 1");
|
||||
}
|
||||
} else if (memcmp(config, "rxduty ", 7) == 0) {
|
||||
int val = atoi(&config[7]);
|
||||
if (val == 0 || val == 1) {
|
||||
_prefs->rx_duty_cycle = (uint8_t)val;
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - rxduty=%d (reboot to apply)", _prefs->rx_duty_cycle);
|
||||
} else {
|
||||
strcpy(reply, "Error: must be 0 or 1");
|
||||
}
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "unknown config: %s", config);
|
||||
}
|
||||
@@ -831,16 +886,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
}
|
||||
} else if (memcmp(command, "powersaving on", 14) == 0) {
|
||||
_prefs->powersaving_enabled = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command, "powersaving off", 15) == 0) {
|
||||
_prefs->powersaving_enabled = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command, "powersaving", 11) == 0) {
|
||||
strcpy(reply, _prefs->powersaving_enabled ? "on" : "off");
|
||||
strcpy(reply, "Not implemented");
|
||||
} else if (memcmp(command, "log start", 9) == 0) {
|
||||
_callbacks->setLoggingOn(true);
|
||||
strcpy(reply, " logging on");
|
||||
|
||||
@@ -64,6 +64,8 @@ struct NodePrefs {
|
||||
char owner_info[120];
|
||||
uint8_t rx_boost; // 1 = boosted RX gain (+3dB, +2mA), 0 = power save
|
||||
uint8_t rx_duty_cycle; // 1 = RX duty cycle (power save), 0 = continuous RX
|
||||
uint8_t apc_enabled; // 1 = adaptive power control on, 0 = fixed TX power
|
||||
uint8_t apc_margin; // APC target link margin in dB (6-30, default 16)
|
||||
|
||||
/* ---- Companion-only fields (Zephyr additions, not in Arduino) ---- */
|
||||
uint8_t manual_add_contacts;
|
||||
@@ -124,4 +126,6 @@ static inline void initNodePrefs(NodePrefs* prefs) {
|
||||
prefs->adc_multiplier = 0.0f;
|
||||
prefs->rx_boost = 1; // Default to boosted RX for better sensitivity
|
||||
prefs->rx_duty_cycle = 0; // Default OFF — continuous RX for best reliability
|
||||
prefs->apc_enabled = 0; // Default OFF — fixed TX power
|
||||
prefs->apc_margin = 16; // Default 16 dB target link margin
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
|
||||
#include "TransportKeyStore.h"
|
||||
#include <string.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <psa/crypto.h>
|
||||
|
||||
uint16_t TransportKey::calcTransportCode(const mesh::Packet* packet) const {
|
||||
/* HMAC-SHA256 using mbedTLS */
|
||||
/* HMAC-SHA256 using PSA Crypto */
|
||||
uint8_t hmac[32];
|
||||
uint8_t type = packet->getPayloadType();
|
||||
|
||||
@@ -19,14 +18,27 @@ uint16_t TransportKey::calcTransportCode(const mesh::Packet* packet) const {
|
||||
memcpy(&msg[1], packet->payload, packet->payload_len);
|
||||
size_t msg_len = 1 + packet->payload_len;
|
||||
|
||||
/* Calculate HMAC-SHA256 */
|
||||
mbedtls_md_context_t ctx;
|
||||
mbedtls_md_init(&ctx);
|
||||
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1);
|
||||
mbedtls_md_hmac_starts(&ctx, key, sizeof(key));
|
||||
mbedtls_md_hmac_update(&ctx, msg, msg_len);
|
||||
mbedtls_md_hmac_finish(&ctx, hmac);
|
||||
mbedtls_md_free(&ctx);
|
||||
/* Import HMAC key */
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(&attr, sizeof(key) * 8);
|
||||
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_status_t status = psa_import_key(&attr, key, sizeof(key), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t out_len;
|
||||
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
msg, msg_len, hmac, sizeof(hmac), &out_len);
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extract first 2 bytes as transport code (little-endian, matching Arduino SHA256 finalizeHMAC behavior) */
|
||||
uint16_t code = (uint16_t)hmac[0] | ((uint16_t)hmac[1] << 8);
|
||||
@@ -66,7 +78,9 @@ void TransportKeyStore::getAutoKeyFor(uint16_t id, const char* name, TransportKe
|
||||
|
||||
// calc key for publicly-known hashtag region name (SHA256 hash, first 16 bytes)
|
||||
uint8_t hash[32];
|
||||
mbedtls_sha256((const unsigned char*)name, strlen(name), hash, 0);
|
||||
size_t out_len;
|
||||
psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t*)name, strlen(name),
|
||||
hash, sizeof(hash), &out_len);
|
||||
memcpy(dest.key, hash, sizeof(dest.key));
|
||||
|
||||
putCache(id, dest);
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
diff --git a/zephyr/port/include/boot/mcuboot_config/mcuboot_config.h b/zephyr/port/include/boot/mcuboot_config/mcuboot_config.h
|
||||
index 472ebbc5ab..9cec9f7e12 100644
|
||||
index 07aab9d15b..1338dedfdf 100644
|
||||
--- a/zephyr/port/include/boot/mcuboot_config/mcuboot_config.h
|
||||
+++ b/zephyr/port/include/boot/mcuboot_config/mcuboot_config.h
|
||||
@@ -2,6 +2,10 @@
|
||||
@@ -2,6 +2,9 @@
|
||||
* Copyright (c) 2023 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
+ *
|
||||
+ * ZephCore patch: Added #ifndef guards for MCUBOOT_MAX_IMG_SECTORS,
|
||||
+ * fixed mbedTLS detection (also check CONFIG_BOOT_USE_MBEDTLS), and
|
||||
+ * made MCUBOOT_VALIDATE_PRIMARY_SLOT conditional on Kconfig.
|
||||
+ * ZephCore patch: fixed mbedTLS detection (also check CONFIG_BOOT_USE_MBEDTLS),
|
||||
+ * and made MCUBOOT_VALIDATE_PRIMARY_SLOT conditional on Kconfig.
|
||||
*/
|
||||
|
||||
#ifndef __MCUBOOT_CONFIG_H__
|
||||
@@ -76,8 +80,8 @@
|
||||
@@ -76,8 +79,8 @@
|
||||
* available.
|
||||
*/
|
||||
|
||||
@@ -24,7 +23,7 @@ index 472ebbc5ab..9cec9f7e12 100644
|
||||
#define MCUBOOT_USE_MBED_TLS
|
||||
#else
|
||||
/* MCUboot requires the definition of a crypto lib,
|
||||
@@ -90,7 +94,11 @@
|
||||
@@ -90,7 +93,11 @@
|
||||
* even if no upgrade was performed. This is recommended if the boot
|
||||
* time penalty is acceptable.
|
||||
*/
|
||||
@@ -36,16 +35,3 @@ index 472ebbc5ab..9cec9f7e12 100644
|
||||
|
||||
#ifdef CONFIG_ESP_DOWNGRADE_PREVENTION
|
||||
#define MCUBOOT_DOWNGRADE_PREVENTION 1
|
||||
@@ -114,7 +122,12 @@
|
||||
|
||||
/* Default maximum number of flash sectors per image slot; change
|
||||
* as desirable. */
|
||||
+/* ZephCore patch: allow override via -D or MIN_SECTOR_COUNT from AUTO mode */
|
||||
+#if defined(MIN_SECTOR_COUNT)
|
||||
+#define MCUBOOT_MAX_IMG_SECTORS MIN_SECTOR_COUNT
|
||||
+#elif !defined(MCUBOOT_MAX_IMG_SECTORS)
|
||||
#define MCUBOOT_MAX_IMG_SECTORS 512
|
||||
+#endif
|
||||
|
||||
/* Default number of separately updateable images; change in case of
|
||||
* multiple images. */
|
||||
|
||||
+80
-70
@@ -1,12 +1,10 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* ZephCore Utils - mbedTLS backend for AES-ECB, SHA256, HMAC
|
||||
* ZephCore Utils - PSA Crypto backend for AES-ECB, SHA256, HMAC
|
||||
*/
|
||||
|
||||
#include <mesh/Utils.h>
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <psa/crypto.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
@@ -25,86 +23,87 @@ static uint8_t hexVal(char c)
|
||||
void Utils::sha256(uint8_t *hash, size_t hash_len, const uint8_t *msg, int msg_len)
|
||||
{
|
||||
uint8_t full_hash[32];
|
||||
mbedtls_sha256(msg, (size_t)msg_len, full_hash, 0);
|
||||
size_t out_len;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, msg, (size_t)msg_len,
|
||||
full_hash, sizeof(full_hash), &out_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERR("psa_hash_compute failed: %d", (int)status);
|
||||
memset(hash, 0, hash_len);
|
||||
return;
|
||||
}
|
||||
size_t copy_len = (hash_len < 32) ? hash_len : 32;
|
||||
memcpy(hash, full_hash, copy_len);
|
||||
}
|
||||
|
||||
void Utils::sha256(uint8_t *hash, size_t hash_len, const uint8_t *frag1, int frag1_len, const uint8_t *frag2, int frag2_len)
|
||||
{
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_init(&ctx);
|
||||
mbedtls_sha256_starts(&ctx, 0);
|
||||
mbedtls_sha256_update(&ctx, frag1, (size_t)frag1_len);
|
||||
mbedtls_sha256_update(&ctx, frag2, (size_t)frag2_len);
|
||||
uint8_t full_hash[32];
|
||||
mbedtls_sha256_finish(&ctx, full_hash);
|
||||
mbedtls_sha256_free(&ctx);
|
||||
size_t copy_len = (hash_len < 32) ? hash_len : 32;
|
||||
memcpy(hash, full_hash, copy_len);
|
||||
psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_hash_setup(&op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) goto fail;
|
||||
|
||||
status = psa_hash_update(&op, frag1, (size_t)frag1_len);
|
||||
if (status != PSA_SUCCESS) goto fail;
|
||||
|
||||
status = psa_hash_update(&op, frag2, (size_t)frag2_len);
|
||||
if (status != PSA_SUCCESS) goto fail;
|
||||
|
||||
{
|
||||
uint8_t full_hash[32];
|
||||
size_t out_len;
|
||||
status = psa_hash_finish(&op, full_hash, sizeof(full_hash), &out_len);
|
||||
if (status != PSA_SUCCESS) goto fail;
|
||||
size_t copy_len = (hash_len < 32) ? hash_len : 32;
|
||||
memcpy(hash, full_hash, copy_len);
|
||||
}
|
||||
return;
|
||||
|
||||
fail:
|
||||
LOG_ERR("sha256 (2-frag) failed: %d", (int)status);
|
||||
psa_hash_abort(&op);
|
||||
memset(hash, 0, hash_len);
|
||||
}
|
||||
|
||||
/* AES-ECB using mbedTLS low-level API (PSA doesn't support ECB mode) */
|
||||
static int aes_ecb_encrypt(const uint8_t *key, size_t key_len, const uint8_t *src, int src_len, uint8_t *dest)
|
||||
/* AES-ECB using PSA Crypto (ECB_NO_PADDING) */
|
||||
static int aes_ecb_crypt(const uint8_t *key, size_t key_len, const uint8_t *src, int src_len,
|
||||
uint8_t *dest, bool encrypt)
|
||||
{
|
||||
if (src_len % 16 != 0) {
|
||||
LOG_ERR("src_len=%d not multiple of 16", src_len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_aes_context ctx;
|
||||
mbedtls_aes_init(&ctx);
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attr, key_len * 8);
|
||||
psa_set_key_usage_flags(&attr, encrypt ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_ECB_NO_PADDING);
|
||||
|
||||
int ret = mbedtls_aes_setkey_enc(&ctx, key, key_len * 8);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("setkey failed: %d", ret);
|
||||
mbedtls_aes_free(&ctx);
|
||||
psa_key_id_t key_id;
|
||||
psa_status_t status = psa_import_key(&attr, key, key_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERR("psa_import_key failed: %d", (int)status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Encrypt each 16-byte block */
|
||||
for (int i = 0; i < src_len; i += 16) {
|
||||
ret = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, src + i, dest + i);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("crypt_ecb failed at block %d: %d", i/16, ret);
|
||||
mbedtls_aes_free(&ctx);
|
||||
return -1;
|
||||
}
|
||||
size_t out_len;
|
||||
if (encrypt) {
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
src, (size_t)src_len, dest, (size_t)src_len, &out_len);
|
||||
} else {
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_ECB_NO_PADDING,
|
||||
src, (size_t)src_len, dest, (size_t)src_len, &out_len);
|
||||
}
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
return src_len;
|
||||
}
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
static int aes_ecb_decrypt(const uint8_t *key, size_t key_len, const uint8_t *src, int src_len, uint8_t *dest)
|
||||
{
|
||||
if (src_len % 16 != 0) {
|
||||
LOG_ERR("src_len=%d not multiple of 16", src_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERR("psa_cipher_%s failed: %d", encrypt ? "encrypt" : "decrypt", (int)status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_aes_context ctx;
|
||||
mbedtls_aes_init(&ctx);
|
||||
|
||||
int ret = mbedtls_aes_setkey_dec(&ctx, key, key_len * 8);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("setkey failed: %d", ret);
|
||||
mbedtls_aes_free(&ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Decrypt each 16-byte block */
|
||||
for (int i = 0; i < src_len; i += 16) {
|
||||
ret = mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, src + i, dest + i);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("crypt_ecb failed at block %d: %d", i/16, ret);
|
||||
mbedtls_aes_free(&ctx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
mbedtls_aes_free(&ctx);
|
||||
return src_len;
|
||||
return (int)out_len;
|
||||
}
|
||||
|
||||
int Utils::encrypt(const uint8_t *shared_secret, uint8_t *dest, const uint8_t *src, int src_len)
|
||||
@@ -125,29 +124,40 @@ int Utils::encrypt(const uint8_t *shared_secret, uint8_t *dest, const uint8_t *s
|
||||
dp += CIPHER_BLOCK_SIZE;
|
||||
}
|
||||
int total = (int)(dp - tmp);
|
||||
int n = aes_ecb_encrypt(shared_secret, CIPHER_KEY_SIZE, tmp, total, dest);
|
||||
int n = aes_ecb_crypt(shared_secret, CIPHER_KEY_SIZE, tmp, total, dest, true);
|
||||
return (n > 0) ? n : 0;
|
||||
}
|
||||
|
||||
int Utils::decrypt(const uint8_t *shared_secret, uint8_t *dest, const uint8_t *src, int src_len)
|
||||
{
|
||||
int n = aes_ecb_decrypt(shared_secret, CIPHER_KEY_SIZE, src, src_len, dest);
|
||||
int n = aes_ecb_crypt(shared_secret, CIPHER_KEY_SIZE, src, src_len, dest, false);
|
||||
return (n > 0) ? n : 0;
|
||||
}
|
||||
|
||||
/* HMAC-SHA256 using mbedTLS */
|
||||
/* HMAC-SHA256 using PSA Crypto */
|
||||
static int compute_hmac_truncated(const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t *mac_out, size_t mac_len)
|
||||
{
|
||||
uint8_t full_hmac[32];
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||
if (md_info == nullptr) {
|
||||
LOG_ERR("compute_hmac: SHA256 not available");
|
||||
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
psa_set_key_bits(&attr, key_len * 8);
|
||||
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
|
||||
psa_key_id_t key_id;
|
||||
psa_status_t status = psa_import_key(&attr, key, key_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERR("compute_hmac: import_key failed: %d", (int)status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = mbedtls_md_hmac(md_info, key, key_len, data, data_len, full_hmac);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("compute_hmac: mbedtls_md_hmac failed: %d", ret);
|
||||
uint8_t full_hmac[32];
|
||||
size_t out_len;
|
||||
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
data, data_len, full_hmac, sizeof(full_hmac), &out_len);
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERR("compute_hmac: psa_mac_compute failed: %d", (int)status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -549,6 +549,8 @@ int main(void)
|
||||
companion_mesh.prefs.airtime_factor = 10.0f; /* 10% duty cycle (EU 868 default) */
|
||||
companion_mesh.prefs.rx_duty_cycle = 1; /* Companions: duty cycle ON by default (power save) */
|
||||
companion_mesh.prefs.rx_boost = 1; /* Default: boosted RX (+3dB sensitivity, +2mA) */
|
||||
companion_mesh.prefs.apc_enabled = 0; /* Default: APC off */
|
||||
companion_mesh.prefs.apc_margin = 20; /* Companions: more conservative margin (mobile) */
|
||||
|
||||
/* Load prefs from storage */
|
||||
data_store.loadPrefs(companion_mesh.prefs);
|
||||
|
||||
+5
-1
@@ -4,9 +4,13 @@ manifest:
|
||||
url-base: https://github.com/zephyrproject-rtos
|
||||
|
||||
projects:
|
||||
- name: hal_espressif
|
||||
remote: zephyrproject-rtos
|
||||
revision: e994fd973c2d8eab1ed2c8278c04e841b3a5217a
|
||||
path: modules/hal/espressif
|
||||
- name: zephyr
|
||||
remote: zephyrproject-rtos
|
||||
revision: 17971b7bf45163e0ef202732290f20b3b46f9743
|
||||
revision: 56f8a30c7fd7521e5eeab186b2f425f295376905
|
||||
import: true
|
||||
|
||||
self:
|
||||
|
||||
Reference in New Issue
Block a user