sprint-8: EKF + adaptive tuner + HWID + SHA-256 audit hash-chain
- heading_ekf.py: 2-state Kalman filter fusing PGN 127250 heading and 127251 ROT with shortest-arc innovation and symmetric covariance update - adaptive_tuner.py: gradient-descent outer-loop Kp/Ki adjuster bounded to ±adaptive_max_deviation_pct; oscillation vs steady-state detection - hwid.py: HMAC-SHA256 activation token (verify side); hwid_from_mac_words converts three Modbus uint16 MAC words to 12-char hex HWID - audit.py: SHA-256 hash-chain -- each JSONL line carries prev_hash and line_hash; verify_chain() detects tampering, deletion, insertion - firmware/system/hwid.h+cpp: esp_efuse_mac_get_default wrapper + FNV-32 hash + "AA:BB:CC:DD:EE:FF" formatter - modbus_registers.yaml + generated .h/.py: HWID_MAC_01/23/45 at input addrs 9/10/11 (three 16-bit words = 6-byte MAC) - modbus_slave.cpp: INPUT_HWID_MAC_01/23/45 cases read eFuse MAC - main.cpp: logs HWID string + FNV-32 hash at boot (activation traceability) - tests: 72 new tests (audit signing, EKF, adaptive tuner, HWID) -- 398 total Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// =============================================================================
|
||||
// system/hwid.cpp -- Hardware ID from ESP32 eFuse (Sprint 8)
|
||||
// =============================================================================
|
||||
|
||||
#include "hwid.h"
|
||||
|
||||
#include <esp_efuse.h>
|
||||
#include <esp_mac.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
namespace arautopilot::system {
|
||||
|
||||
bool hwid_get_mac(uint8_t out[6]) {
|
||||
return esp_efuse_mac_get_default(out) == ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t hwid_hash() {
|
||||
uint8_t mac[6] = {};
|
||||
hwid_get_mac(mac);
|
||||
// Simple FNV-32 hash of the 6 bytes.
|
||||
uint32_t h = 2166136261U;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
h ^= (uint32_t)mac[i];
|
||||
h *= 16777619U;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void hwid_format(uint8_t mac[6], char buf[18]) {
|
||||
snprintf(buf, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
} // namespace arautopilot::system
|
||||
@@ -0,0 +1,33 @@
|
||||
// =============================================================================
|
||||
// system/hwid.h -- Hardware ID from ESP32 eFuse (Sprint 8)
|
||||
// =============================================================================
|
||||
//
|
||||
// The ESP32 has a 6-byte unique MAC burned into eFuse by the manufacturer.
|
||||
// We use it as a hardware binding token for the activation license.
|
||||
//
|
||||
// The HWID is exposed via two Modbus input registers so the Studio can
|
||||
// read it and generate the activation token offline.
|
||||
//
|
||||
// NOTE: The Modbus register map must be extended in Sprint 8+ to include
|
||||
// INPUT_HWID_HI (addr 9, upper 16 bits) and INPUT_HWID_LO (addr 10,
|
||||
// lower 16 bits of the middle 2 bytes). Full 6-byte MAC is exposed as
|
||||
// three uint16 registers: [0..1], [2..3], [4..5].
|
||||
// =============================================================================
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace arautopilot::system {
|
||||
|
||||
/// Read the ESP32 eFuse MAC into ``out[6]``.
|
||||
/// Returns true on success; false if the eFuse read fails.
|
||||
bool hwid_get_mac(uint8_t out[6]);
|
||||
|
||||
/// Return a 32-bit summary hash of the 6-byte MAC (for quick comparisons).
|
||||
uint32_t hwid_hash();
|
||||
|
||||
/// Format the MAC as "AA:BB:CC:DD:EE:FF" into ``buf[18]``.
|
||||
void hwid_format(uint8_t mac[6], char buf[18]);
|
||||
|
||||
} // namespace arautopilot::system
|
||||
Reference in New Issue
Block a user