File
Blob: firmware/platform/include/radio_bridge.h
| 1 | #pragma once |
| 2 | #include <stddef.h> |
| 3 | #include <stdint.h> |
| 4 | |
| 5 | /* Private ABI, implemented in C and imported only by esp32-radio::platform. |
| 6 | * Call with valid pointer/length pairs; no Rust-layout or owned Rust values cross. |
| 7 | * All input bytes are borrowed only for the call. Output storage is caller-owned |
| 8 | * except for explicitly documented borrows from native handles. |
| 9 | * HTTP handles stay on their creating task. See docs/ffi.md for lifetimes. |
| 10 | */ |
| 11 | int32_t radio_board_init(void); |
| 12 | int32_t radio_network_ready(void); |
| 13 | int32_t radio_clock_sync(void); |
| 14 | uint64_t radio_now_us(void); |
| 15 | uint32_t radio_random(void); |
| 16 | uint32_t radio_heap_free(void); |
| 17 | uint32_t radio_stack_free(void); |
| 18 | int32_t radio_led(uint8_t r, uint8_t g, uint8_t b); |
| 19 | int32_t radio_console_byte(void); |
| 20 | void radio_log(const char *message); |
| 21 | uint32_t radio_recovery_attempt(int32_t reset); |
| 22 | void radio_restart(void) __attribute__((noreturn)); |
| 23 | /* Read-only partition access; output is borrowed for this synchronous copy only. */ |
| 24 | size_t radio_music_size(void); |
| 25 | int32_t radio_music_read(size_t offset, uint8_t *out, size_t length); |
| 26 | |
| 27 | /* Synchronous copies: four IPv4 octets and bounded DER certificate/key output. |
| 28 | * Call certificate generation only after Wi-Fi and clock initialization. */ |
| 29 | int32_t radio_ipv4(uint8_t octets[4]); |
| 30 | int32_t radio_certificate_generate(uint8_t *cert, size_t cert_capacity, size_t *cert_length, |
| 31 | uint8_t *key, size_t key_capacity, size_t *key_length); |
| 32 | |
| 33 | /* Crypto calls borrow all buffers synchronously and use ESP-IDF's peripheral locks. |
| 34 | * GCM permits identical input/output buffers; failed authentication clears plaintext. |
| 35 | * Hash state is a pointer-free value snapshot for the pinned S3 mbedTLS port. */ |
| 36 | #define RADIO_CRYPTO_HASH_STATE_BYTES 256 |
| 37 | typedef struct { |
| 38 | const uint8_t *bytes; |
| 39 | size_t length; |
| 40 | } radio_crypto_part; |
| 41 | int32_t radio_crypto_aes_ctr(const uint8_t *key, size_t key_length, const uint8_t iv[16], |
| 42 | const uint8_t *input, size_t length, uint8_t *output, size_t capacity); |
| 43 | int32_t radio_crypto_aes_ecb(const uint8_t *key, size_t key_length, const uint8_t input[16], |
| 44 | uint8_t output[16]); |
| 45 | int32_t radio_crypto_aes_gcm(int32_t decrypt, const uint8_t *key, size_t key_length, |
| 46 | const uint8_t iv[12], const uint8_t *aad, size_t aad_length, |
| 47 | const uint8_t *input, size_t length, uint8_t *output, size_t capacity); |
| 48 | int32_t radio_crypto_sha256(const uint8_t *input, size_t length, uint8_t output[32]); |
| 49 | int32_t radio_crypto_hmac(int32_t bits, const uint8_t *key, size_t key_length, |
| 50 | const radio_crypto_part *parts, size_t count, uint8_t *output, |
| 51 | size_t capacity); |
| 52 | int32_t radio_crypto_hash_init(uint8_t state[RADIO_CRYPTO_HASH_STATE_BYTES], int32_t bits); |
| 53 | int32_t radio_crypto_hash_update(uint8_t state[RADIO_CRYPTO_HASH_STATE_BYTES], const uint8_t *input, |
| 54 | size_t length); |
| 55 | int32_t radio_crypto_hash_finish(const uint8_t state[RADIO_CRYPTO_HASH_STATE_BYTES], |
| 56 | uint8_t *output, size_t capacity); |
| 57 | int32_t radio_crypto_verify_ec(const uint8_t *certificate, size_t certificate_length, |
| 58 | const uint8_t *data, size_t data_length, const uint8_t *signature, |
| 59 | size_t signature_length, int32_t hash_bits); |
| 60 | /* EC private material is borrowed or copied into caller-owned fixed buffers. |
| 61 | * Wi-Fi must be started for hardware entropy. Native contexts never escape. */ |
| 62 | int32_t radio_crypto_key_info(const uint8_t *der, size_t length, int32_t *bits); |
| 63 | int32_t radio_crypto_sign(const uint8_t *der, size_t key_length, const uint8_t *data, |
| 64 | size_t data_length, int32_t hash_bits, uint8_t *output, size_t capacity, |
| 65 | size_t *used); |
| 66 | int32_t radio_crypto_p256_keygen(uint8_t secret[32], uint8_t public_key[65]); |
| 67 | int32_t radio_crypto_p256_shared(const uint8_t secret[32], const uint8_t public_key[65], |
| 68 | uint8_t shared[32]); |
| 69 | |
| 70 | /* Diagnostic-image symbols only. Start/finish on the same task; finish logs |
| 71 | * aggregate native counts/timing after leaving the lock. Return 0 on success. */ |
| 72 | int32_t radio_crypto_profile_start(void); |
| 73 | int32_t radio_crypto_profile_finish(void); |
| 74 | |
| 75 | /* Blocking HTTP callbacks write only C-owned storage. A successful post lends |
| 76 | * exactly *used initialized response bytes until the next post/free on this |
| 77 | * handle. Every transport failure returns NULL/0; end the borrow before |
| 78 | * any mutation or cleanup. Response callbacks finish before the post returns; |
| 79 | * cleanup callbacks complete before the client-owned storage is freed. */ |
| 80 | typedef struct radio_http radio_http; |
| 81 | radio_http *radio_http_open(void); |
| 82 | int32_t radio_http_post(radio_http *http, const char *path, const uint8_t *body, size_t length, |
| 83 | const uint8_t **response, size_t *used); |
| 84 | void radio_http_free(radio_http *http); |
| 85 | |
| 86 | /* Single-task audio analysis. FFT buffers are 4096 float32 values; PCM is |
| 87 | * exactly 1920 int16 values. Native operations retain only C-owned storage. */ |
| 88 | typedef struct radio_dsp radio_dsp; |
| 89 | /* Single-task temperature driver, no callbacks. Sample writes exactly 3 clocks |
| 90 | * (boot/idle0/idle1 us), 6 memory values (free/minimum/largest, internal then PSRAM), |
| 91 | * and 2 sensors (chip milli-Celsius/RSSI; INT32_MIN means unavailable). |
| 92 | * No output pointer is retained. detailed refreshes slow heap diagnostics. */ |
| 93 | typedef struct radio_metrics radio_metrics; |
| 94 | radio_metrics *radio_metrics_open(void); |
| 95 | int32_t radio_metrics_sample(radio_metrics *metrics, uint64_t clocks[3], uint32_t memory[6], |
| 96 | int32_t sensors[2], int32_t detailed); |
| 97 | void radio_metrics_free(radio_metrics *metrics); |
| 98 | int32_t radio_current_core(void); |
| 99 | radio_dsp *radio_dsp_open(void); |
| 100 | void radio_dsp_free(radio_dsp *dsp); |
| 101 | int32_t radio_dsp_reset(radio_dsp *dsp); |
| 102 | int32_t radio_dsp_decode(radio_dsp *dsp, const uint8_t *opus, size_t length); |
| 103 | const int16_t *radio_dsp_pcm(radio_dsp *dsp); |
| 104 | float *radio_dsp_fft_buffer(radio_dsp *dsp); |
| 105 | int32_t radio_dsp_transform(radio_dsp *dsp); |
| 106 | float *radio_analysis_history_alloc(void); |
| 107 | void radio_analysis_history_free(float *history); |
| 108 | |
| 109 | /* Called exactly once by app_main. The Rust release profile aborts on panic. */ |
| 110 | void radio_rust_main(void); |