|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Bounded runtime network provisioning parser and UART receiver. More...
#include "ra8_net_provision.h"#include <stddef.h>#include <stdint.h>#include "ra8_attributes.h"#include "ra8_err.h"#include "ra8_secure.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_net_provision_text_byte_t : uint8_t { k_ra8_net_provision_text_printable_min = 0x20U , k_ra8_net_provision_text_delete = 0x7FU } |
| Control-byte boundaries rejected from decoded text fields. More... | |
| enum | ra8_net_provision_hex_t : uint8_t { k_ra8_net_provision_hex_alpha_offset = 10U } |
| Numeric base of hexadecimal alphabet digits. More... | |
Functions | |
| static bool | internal_hex_nibble (uint8_t digit, uint8_t *out) |
| Decode one hexadecimal digit. | |
| static ra8_err_t | internal_decode_field (const uint8_t *line, size_t begin, size_t end, char *output, size_t capacity, size_t *out_length) |
| Decode one bounded hexadecimal field. | |
| static bool | internal_has_no_controls (const char *text, size_t length) |
| Check a decoded text field for C0 and DEL control bytes. | |
| static bool | internal_psk_is_hex (const char *psk) |
| Check whether a decoded 64-byte PSK contains only ASCII hex. | |
| static ra8_err_t | internal_validate_candidate (const ra8_net_credentials_t *candidate) |
| Validate decoded field lengths and string compatibility. | |
| static ra8_err_t | internal_decode_line (const uint8_t *line, size_t line_length, ra8_net_credentials_t *candidate) |
| Decode the three fields between already-validated framing bytes. | |
| static bool | internal_prefix_matches (const uint8_t *line) |
| Check the fixed version prefix without a libc comparison. | |
| void | ra8_net_provision_clear (ra8_net_credentials_t *credentials) |
| Explicitly erase one decoded credential record. | |
| ra8_err_t | ra8_net_provision_parse (const uint8_t *line, size_t line_length, ra8_net_credentials_t *out) |
| Parse one complete version-one ASCII-hex provisioning line. | |
| static ra8_err_t | internal_validate_receiver (const ra8_net_provision_uart_t *uart, uint32_t timeout_ms) |
| Validate the injected receiver dependencies and timeout. | |
| static bool | internal_find_newline (const uint8_t *chunk, size_t length, size_t *newline_offset) |
| Locate a newline in one newly received chunk. | |
| static ra8_err_t | internal_receive_line (const ra8_net_provision_uart_t *uart, uint32_t timeout_ms, uint8_t *line, size_t line_capacity, size_t *line_length) |
| Receive exactly one newline-terminated provisioning record. | |
| ra8_err_t | ra8_net_provision_receive (const ra8_net_provision_uart_t *uart, uint32_t timeout_ms, ra8_net_credentials_t *out) |
| Prompt once and receive one provisioning line within a fixed timeout. | |
Variables | |
| static const uint8_t | s_prefix [k_ra8_net_provision_prefix_bytes] |
| Exact protocol prefix, including the first field separator. | |
| const char | k_ra8_net_provision_ready_prompt [] = "ra8_net_provision: READY v1\r\n" |
| Exact non-secret line emitted before the receiver drains UART input. | |
Bounded runtime network provisioning parser and UART receiver.
Decodes one versioned ASCII-hex record into caller-owned fixed storage and collects that record through injected non-blocking UART operations. Raw and decoded transient storage is explicitly erased on all return paths.
Definition in file ra8_net_provision.c.
| enum ra8_net_provision_hex_t : uint8_t |
Numeric base of hexadecimal alphabet digits.
Converts an alphabet index beginning at A or a into the corresponding nibble value beginning at decimal ten.
| Enumerator | |
|---|---|
| k_ra8_net_provision_hex_alpha_offset | Value represented by A or a. |
Definition at line 73 of file ra8_net_provision.c.
| enum ra8_net_provision_text_byte_t : uint8_t |
Control-byte boundaries rejected from decoded text fields.
Mirrors the host provisioner's text policy so a direct UART sender cannot inject C0 or DEL control bytes into C-string consumers.
| Enumerator | |
|---|---|
| k_ra8_net_provision_text_printable_min | First printable ASCII byte. |
| k_ra8_net_provision_text_delete | ASCII DEL control byte. |
Definition at line 54 of file ra8_net_provision.c.
|
static |
Decode one bounded hexadecimal field.
Processes exactly two input characters per output byte and appends one NUL terminator after the decoded extent.
| [in] | line | Complete provisioning line. |
| [in] | begin | First hex byte of the field. |
| [in] | end | One-past-last hex byte of the field. |
| [out] | output | Destination text buffer. |
| [in] | capacity | Payload capacity, excluding the trailing NUL. |
| [out] | out_length | Decoded payload length. |
| k_ra8_ok | The field decoded completely. |
| k_ra8_err_invalid_size | The encoded extent was odd or too large. |
| k_ra8_err_protocol_error | A character was not hexadecimal. |
Definition at line 133 of file ra8_net_provision.c.
References internal_hex_nibble(), k_ra8_err_invalid_size, k_ra8_err_protocol_error, k_ra8_ok, and RA8_INTERNAL.
Referenced by internal_decode_line().
|
static |
Decode the three fields between already-validated framing bytes.
Finds exactly two field separators, decodes each bounded hex extent into the candidate record, and validates the completed candidate.
| [in] | line | Complete input line. |
| [in] | line_length | Complete input length. |
| [out] | candidate | Cleared candidate record to populate. |
| k_ra8_ok | All three fields decoded and validated. |
| k_ra8_err_invalid_size | A field exceeded its capacity. |
| k_ra8_err_protocol_error | Separator or hex syntax was invalid. |
Definition at line 278 of file ra8_net_provision.c.
References internal_decode_field(), internal_validate_candidate(), k_ra8_err_protocol_error, k_ra8_net_provision_prefix_bytes, k_ra8_net_provision_psk_bytes_max, k_ra8_net_provision_ssid_bytes_max, k_ra8_net_provision_url_bytes_max, k_ra8_ok, ra8_net_credentials::psk, ra8_net_credentials::psk_len, ra8_net_credentials::ssid, ra8_net_credentials::ssid_len, ra8_net_credentials::url, and ra8_net_credentials::url_len.
Referenced by ra8_net_provision_parse().
|
static |
Locate a newline in one newly received chunk.
Performs a forward bounded scan and reports only the first newline, allowing the receiver to reject any bytes that follow one record.
| [in] | chunk | Newly received bytes. |
| [in] | length | Number of bytes in the chunk. |
| [out] | newline_offset | Offset of the first newline when found. |
| true | newline_offset names the first newline. |
| false | No newline was present and newline_offset is zero. |
Definition at line 443 of file ra8_net_provision.c.
Referenced by internal_receive_line().
|
static |
Check a decoded text field for C0 and DEL control bytes.
Scans the caller-bounded decoded extent and stops at the first C0 or DEL byte because downstream network APIs require printable text.
| [in] | text | Decoded text storage. |
| [in] | length | Bytes to examine, excluding the appended terminator. |
| true | No C0 or DEL control byte was present. |
| false | A decoded payload byte was C0 or DEL. |
Definition at line 180 of file ra8_net_provision.c.
References k_ra8_net_provision_text_delete, k_ra8_net_provision_text_printable_min, and RA8_INTERNAL.
Referenced by internal_validate_candidate().
|
static |
Decode one hexadecimal digit.
Accepts decimal and either case of ASCII hexadecimal letters.
| [in] | digit | ASCII byte to decode. |
| [out] | out | Decoded nibble on success. |
| true | out contains a value in 0..15. |
| false | digit was not hexadecimal and out is zero. |
Definition at line 94 of file ra8_net_provision.c.
References k_ra8_net_provision_hex_alpha_offset, and RA8_INTERNAL.
Referenced by internal_decode_field(), and internal_psk_is_hex().
|
static |
Check the fixed version prefix without a libc comparison.
Compares each byte against immutable prefix storage so the caller needs no temporary NUL terminator or unbounded string operation.
| [in] | line | Input line with at least the prefix length. |
| true | The line begins with RA8NET1:. |
| false | At least one prefix byte differed. |
Definition at line 340 of file ra8_net_provision.c.
References k_ra8_net_provision_prefix_bytes, RA8_INTERNAL, and s_prefix.
Referenced by ra8_net_provision_parse().
|
static |
Check whether a decoded 64-byte PSK contains only ASCII hex.
Reuses the protocol nibble classifier for every decoded PSK byte; this distinguishes a raw 256-bit hexadecimal key from passphrases.
| [in] | psk | Decoded PSK text. |
| true | Every byte is ASCII hexadecimal. |
| false | At least one byte is not ASCII hexadecimal. |
Definition at line 207 of file ra8_net_provision.c.
References internal_hex_nibble(), k_ra8_net_provision_psk_bytes_max, and RA8_INTERNAL.
Referenced by internal_validate_candidate().
|
static |
Receive exactly one newline-terminated provisioning record.
Polls the injected UART for at most timeout_ms iterations, rejects bytes after the first newline, and bounds all writes by the supplied line capacity.
| [in] | uart | Validated UART binding. |
| [in] | timeout_ms | Maximum one-millisecond polling iterations. |
| [out] | line | Caller-owned receive buffer. |
| [in] | line_capacity | Writable bytes in line. |
| [out] | line_length | Received bytes through the newline on success. |
| k_ra8_ok | One complete record was received. |
| k_ra8_err_timeout | No complete record arrived before the deadline. |
| k_ra8_err_invalid_size | The record filled the buffer without a newline. |
| k_ra8_err_protocol_error | A read over-reported bytes or included trailing data. |
uart contains non-NULL read and wait callbacks. line and line_length are non-NULL and line_capacity is nonzero. line_length to the complete record size. Definition at line 477 of file ra8_net_provision.c.
References internal_find_newline(), k_ra8_err_invalid_size, k_ra8_err_protocol_error, k_ra8_err_timeout, k_ra8_ok, RA8_INTERNAL, ra8_net_provision_uart::read, and ra8_net_provision_uart::wait_ms.
Referenced by ra8_net_provision_receive().
|
static |
Validate decoded field lengths and string compatibility.
Applies required-field bounds first, then rejects C0 and DEL controls and enforces the hexadecimal rule for 64-byte PSKs.
| [in] | candidate | Fully decoded candidate record. |
| k_ra8_ok | Every field satisfies the version-one contract. |
| k_ra8_err_invalid_size | A required field length was invalid. |
| k_ra8_err_protocol_error | A field contained a control byte or a 64-byte PSK was not hexadecimal. |
Definition at line 235 of file ra8_net_provision.c.
References internal_has_no_controls(), internal_psk_is_hex(), k_ra8_err_invalid_size, k_ra8_err_protocol_error, k_ra8_net_provision_psk_bytes_max, k_ra8_ok, ra8_net_credentials::psk, ra8_net_credentials::psk_len, RA8_INTERNAL, ra8_net_credentials::ssid, ra8_net_credentials::ssid_len, ra8_net_credentials::url, and ra8_net_credentials::url_len.
Referenced by internal_decode_line().
|
static |
Validate the injected receiver dependencies and timeout.
Rejects an absent operation row before any callback can run, then constrains the caller's timeout to the protocol's fixed maximum.
| [in] | uart | UART operation table to validate. |
| [in] | timeout_ms | Requested timeout. |
| k_ra8_ok | Every dependency and bound is valid. |
| k_ra8_err_null_ptr | The table or one row was null. |
| k_ra8_err_invalid_arg | The timeout was outside 1..60000. |
Definition at line 404 of file ra8_net_provision.c.
References k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_net_provision_timeout_ms_max, k_ra8_ok, RA8_INTERNAL, ra8_net_provision_uart::read, ra8_net_provision_uart::wait_ms, and ra8_net_provision_uart::write.
Referenced by ra8_net_provision_receive().
| void ra8_net_provision_clear | ( | ra8_net_credentials_t * | credentials | ) |
Explicitly erase one decoded credential record.
Uses the repository secure-memory primitive so optimization cannot discard the overwrite. A null record is accepted for cleanup paths that do not know whether provisioning completed.
| [in,out] | credentials | Record to erase; null is a no-op. |
Definition at line 350 of file ra8_net_provision.c.
References ra8_secure_memzero().
Referenced by c6_join_worker_entry(), internal_c6_cam_worker_entry(), internal_worker(), ra8_net_provision_parse(), ra8_net_provision_receive(), and wifi_hal_worker_entry().
|
nodiscard |
Parse one complete version-one ASCII-hex provisioning line.
Accepts exactly RA8NET1:<ssid_hex>:<psk_hex>:<url_hex>\n. Each pair of hexadecimal characters decodes to one output byte. SSID is required and at most 32 bytes. PSK is 8..63 bytes, or exactly 64 hexadecimal characters. URL is optional and at most 511 bytes. Decoded C0 and DEL control bytes are rejected because the existing Wi-Fi and media APIs consume printable text.
| [in] | line | Complete line bytes, including the final newline. |
| [in] | line_length | Number of readable bytes at line. |
| [out] | out | Decoded record; cleared before parsing and on every failure. |
| k_ra8_ok | The complete line was valid and decoded. |
| k_ra8_err_null_ptr | line or out was null. |
| k_ra8_err_invalid_size | A line or decoded field exceeded its bound. |
| k_ra8_err_protocol_error | Prefix, separators, newline, or hex syntax was invalid. |
Definition at line 358 of file ra8_net_provision.c.
References internal_decode_line(), internal_prefix_matches(), k_ra8_err_invalid_size, k_ra8_err_null_ptr, k_ra8_err_protocol_error, k_ra8_net_provision_line_bytes_max, k_ra8_net_provision_prefix_bytes, k_ra8_ok, and ra8_net_provision_clear().
Referenced by ra8_net_provision_receive().
|
nodiscard |
Prompt once and receive one provisioning line within a fixed timeout.
Writes k_ra8_net_provision_ready_prompt, then drains the injected non-blocking UART into fixed stack storage. It never echoes input. Every incomplete poll waits one millisecond; therefore timeout_ms is both the poll limit and a lower bound on elapsed wait time. The budget is capped at 60 seconds. The raw line buffer is explicitly zeroed before every return.
| [in] | uart | Complete UART operation table. |
| [in] | timeout_ms | Receive budget in milliseconds, 1..60000. |
| [out] | out | Decoded record; cleared before receive and on every failure. |
| k_ra8_ok | One valid line was received and decoded. |
| k_ra8_err_null_ptr | uart, an operation row, or out was null. |
| k_ra8_err_invalid_arg | timeout_ms was zero or above the fixed cap. |
| k_ra8_err_invalid_size | Input filled the fixed line buffer. |
| k_ra8_err_timeout | No complete line arrived within the budget. |
| k_ra8_err_protocol_error | The complete line was malformed. |
Definition at line 520 of file ra8_net_provision.c.
References internal_receive_line(), internal_validate_receiver(), k_ra8_err_null_ptr, k_ra8_net_provision_line_bytes_max, k_ra8_net_provision_ready_prompt, k_ra8_ok, ra8_net_provision_clear(), ra8_net_provision_parse(), ra8_secure_memzero(), and ra8_net_provision_uart::write.
Referenced by c6_join_worker_entry(), internal_c6_cam_worker_entry(), internal_worker(), and wifi_hal_worker_entry().
| const char k_ra8_net_provision_ready_prompt[] = "ra8_net_provision: READY v1\r\n" |
Exact non-secret line emitted before the receiver drains UART input.
The HIL provisioner waits for this versioned prompt before sending one RA8NET1 line to a freshly flashed credential-free image.
Definition at line 77 of file ra8_net_provision.c.
Referenced by ra8_net_provision_receive().
|
static |
Exact protocol prefix, including the first field separator.
Definition at line 28 of file ra8_net_provision.c.
Referenced by internal_prefix_matches(), internal_temp_name(), internal_temp_name(), internal_temp_name(), and internal_temp_name().