hxtp-micro
Embedded SDK for ESP32/ESP8266 â Arduino/PlatformIO compatible with zero dynamic memory allocation.
Installationâ
PlatformIOâ
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
hxtp-micro@^1.0.3
knolleary/PubSubClient@^2.8
build_flags =
-DHXTP_RELEASE=1
Arduino Library Managerâ
Search for "hxtp-micro" in Arduino Library Manager.
Quick Startâ
#include <Hxtp.h>
hxtp::Client client;
void setup() {
hxtp::Config config;
config.api_base_url = "https://api.hestialabs.in/v1";
config.device_uuid = "permanent-hw-id";
config.api_key = "YOUR_PORTAL_API_KEY";
config.verify_server = true;
client.begin(config);
// Register capability
client.registerCapability(1, "toggle_led",
[](const char* params, uint32_t len, void* ctx) {
int64_t value = 0;
if (!hxtp::json_get_int64(params, len, "value", &value)) {
return hxtp::CapabilityResult{false, 0};
}
digitalWrite(LED_BUILTIN, value ? HIGH : LOW);
return hxtp::CapabilityResult{true, 0};
}
);
client.connect();
}
void loop() {
client.loop(); // Handles identity generation, claiming, and handshakes
}
Configurationâ
struct Config {
const char* api_base_url; // Hestia Cloud Endpoint
const char* device_uuid; // Permanent hardware identifier
const char* api_key; // Portal bootstrap key
bool verify_server; // TLS verification (recommended)
const char* wifi_ssid; // Optional: pre-configured WiFi
const char* wifi_password; // Optional: pre-configured WiFi
};
Build Profilesâ
| Profile | Description | Use Case |
|---|---|---|
HXTP_RELEASE | Full features, optimized | Production |
HXTP_DEBUG | Verbose errors | Development |
HXTP_LITE | Reduced memory | ESP32 constrained |
HXTP_CONSTRAINED | Minimal | ESP8266 |
State Machineâ
Capabilitiesâ
Register Capabilityâ
client.registerCapability(
id, // Capability ID (1-255)
name, // Name (e.g., "toggle_led")
handler, // Callback function
);
Handler Signatureâ
CapabilityResult handler(
const char* params, // JSON params
uint32_t len, // Params length
void* ctx // User context
);
Return Valueâ
struct CapabilityResult {
bool success; // true = handled
int16_t error; // Error code or 0
};
Zero-Allocation JSONâ
The SDK includes a zero-allocation JSON parser:
// Get string
char buffer[64];
size_t len;
if (hxtp::json_get_string(json, json_len, "key", buffer, sizeof(buffer), &len)) {
// Use buffer
}
// Get int64
int64_t value;
if (hxtp::json_get_int64(json, json_len, "key", &value)) {
// Use value
}
// Get bool
bool flag;
if (hxtp::json_get_bool(json, json_len, "key", &flag)) {
// Use flag
}
// Get raw (nested object)
if (hxtp::json_get_raw(json, json_len, "key", out, out_cap, &len)) {
// Use raw JSON
}
Validation Pipelineâ
The SDK runs a hardened 7-step validation on every incoming message:
| Step | Check | Details |
|---|---|---|
| 1 | Version | Must be "HxTP/3.1" |
| 2 | Timestamp | Freshness window (Âą30s) |
| 3 | Payload Size | Size enforcement |
| 4 | Nonce | Replay protection (ring buffer) |
| 5 | Sequence | Monotonic counter check |
| 6 | Payload Hash | SHA-256 integrity |
| 7 | Signature | Ed25519 verification (Cloud Root) |
Supported Boardsâ
| Board | Platform | Crypto | RAM | Flash |
|---|---|---|---|---|
| ESP32-S3 | espressif32 | mbedTLS | 13.8% | 29.6% |
| ESP32 | espressif32 | mbedTLS | 13.9% | 51.7% |
| NodeMCU | espressif8266 | BearSSL | 39.5% | 39.6% |
| Wemos D1 | espressif8266 | BearSSL | 39.5% | 39.6% |
MQTT Topicsâ
Pattern: hxtp/{tenant_id}/device/{device_id}/{channel}
| Channel | Direction | Purpose |
|---|---|---|
cmd | Inbound | RPC Commands |
cmd_ack | Outbound | Command Acknowledgments |
state | Outbound | State Reporting |
hello | Outbound | Handshake Handlers |
Memory Configurationâ
// Config.h overrides
#define HXTP_NONCE_CACHE_SIZE 64 // Entries (16 for CONSTRAINED)
#define HXTP_FRAME_BUFFER_SIZE 4096 // Bytes (1536 for CONSTRAINED)
#define HXTP_MAX_PAYLOAD_SIZE 16384 // Max payload
#define HXTP_MAX_NONCE_LEN 32 // Max nonce length
FROZEN Canonical Framingâ
The HxTP/3.1 pipe-separated framing is FROZEN. The order of fields is immutable:
version|device_id|tenant_id|client_id|message_id|request_id|sequence_number|timestamp|nonce|message_type|payload_hash
Any change to this sequence or content format will invalidate signatures globally.