ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_c6link_mdl_service.c File Reference

Portable one-job media service state machine for the ESP32-C6 port. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "ra8_attributes.h"
#include "ra8_c6link_mdl_msg.h"
#include "ra8_c6link_mdl_service_internal.h"
#include "ra8_media_download.pb-c.h"
Include dependency graph for ra8_c6link_mdl_service.c:

Go to the source code of this file.

Data Structures

struct  internal_mdl_next_read_t
 Caller-bounded bytes and metadata returned by one backend pull. More...

Typedefs

typedef struct internal_mdl_next_read_t internal_mdl_next_read_t
 Caller-bounded bytes and metadata returned by one backend pull.

Enumerations

enum  mdl_svc_const_t : uint16_t { k_mdl_decode_align_mask = k_ra8_mdl_decode_align - 1U }
 Rounding mask derived from the arena's published alignment. More...

Functions

static bool internal_mdl_request_field_valid (const char *text, size_t cap)
 Validate one decoded optional request header.
static bool internal_mdl_response_valid (const ra8_mdl_http_response_t *response)
 Validate fixed terminal response metadata returned by a backend.
bool priv_c6link_mdl_decode_allocation_fits (size_t used, size_t len, size_t capacity)
 Decide whether one aligned protobuf allocation fits an arena.
static void * internal_mdl_decode_alloc (void *data, size_t len)
 Allocate one aligned span from a per-dispatch bounded arena.
static void internal_mdl_decode_free (void *data, void *ptr)
 Ignore individual protobuf frees for the linear dispatch arena.
static ra8_err_t internal_mdl_check_response_size (size_t len, size_t response_cap)
 Reject a response that cannot fit before invoking the backend.
static ra8_err_t internal_mdl_pack_accepted (const Ra8__Mdl__Accepted *msg, uint8_t *response, size_t response_cap, size_t *response_len)
 Pack an Accepted response into a bounded caller buffer.
static ra8_err_t internal_mdl_pack_chunk (const Ra8__Mdl__Chunk *msg, uint8_t *response, size_t response_cap, size_t *response_len)
 Pack a Chunk response into a bounded caller buffer.
static bool internal_mdl_start_valid (const Ra8__Mdl__StartRequest *request)
 Validate every generated Start field before backend activation.
static ra8_err_t internal_mdl_dispatch_start (ra8_mdl_service_t *service, ProtobufCAllocator *alloc, const uint8_t *request, size_t request_len, uint8_t *response, size_t response_cap, size_t *response_len)
 Validate and begin one typed-artifact service job.
static ra8_err_t internal_mdl_fail_job (ra8_mdl_service_t *service, ra8_err_t error)
 Cancel and deactivate one backend job after a terminal error.
static ra8_err_t internal_mdl_next_capacity (uint32_t max_data, size_t response_cap)
 Prove the worst-case Chunk for one request fits before backend I/O.
static ra8_err_t internal_mdl_read_next (ra8_mdl_service_t *service, uint32_t max_data, internal_mdl_next_read_t *result)
 Pull and validate one backend response without advancing service state.
static void internal_mdl_build_chunk (const ra8_mdl_service_t *service, internal_mdl_next_read_t *result, Ra8__Mdl__Chunk *out)
 Build one Chunk message from a completed backend pull.
static ra8_err_t internal_mdl_dispatch_next (ra8_mdl_service_t *service, ProtobufCAllocator *alloc, const uint8_t *request, size_t request_len, uint8_t *response, size_t response_cap, size_t *response_len)
 Validate one pull, read bounded bytes, and pack a correlated Chunk.
static ra8_err_t internal_mdl_dispatch_cancel (ra8_mdl_service_t *service, ProtobufCAllocator *alloc, const uint8_t *request, size_t request_len, uint8_t *response, size_t response_cap, size_t *response_len)
 Validate and cancel one correlated active service job.
bool ra8_mdl_service_field_valid_test (const char *text, size_t cap)
 Judge one decoded request header exactly as dispatch does.
bool ra8_mdl_service_response_valid_test (const ra8_mdl_http_response_t *response)
 Judge one backend terminal response exactly as dispatch does.
ra8_err_t ra8_mdl_service_check_size_test (size_t len, size_t response_cap)
 Judge one packed-response length exactly as dispatch does.
ra8_err_t ra8_mdl_service_init (ra8_mdl_service_t *service, const ra8_mdl_service_backend_t *backend)
 Initialise portable service state with a complete backend seam.
ra8_err_t ra8_mdl_service_dispatch (void *ctx, uint32_t operation, const uint8_t *request, size_t request_len, uint8_t *response, size_t response_cap, size_t *response_len)
 Dispatch Start, Next, or Cancel generated protobuf payloads.

Detailed Description

Portable one-job media service state machine for the ESP32-C6 port.

Decodes one bounded request at a time, delegates body I/O to an injected backend, and packs transactional responses without heap allocation.

Definition in file ra8_c6link_mdl_service.c.

Typedef Documentation

◆ internal_mdl_next_read_t

typedef struct internal_mdl_next_read_t internal_mdl_next_read_t

Caller-bounded bytes and metadata returned by one backend pull.

Enumeration Type Documentation

◆ mdl_svc_const_t

enum mdl_svc_const_t : uint16_t

Rounding mask derived from the arena's published alignment.

Enumerator
k_mdl_decode_align_mask 

Mask used to round sizes.

Definition at line 31 of file ra8_c6link_mdl_service.c.

Function Documentation

◆ internal_mdl_build_chunk()

void internal_mdl_build_chunk ( const ra8_mdl_service_t * service,
internal_mdl_next_read_t * result,
Ra8__Mdl__Chunk * out )
static

Build one Chunk message from a completed backend pull.

Copies protocol, correlation, sequencing, and body fields from service and result into out, adding terminal HTTP metadata only when the pull is complete. Performs no I/O and cannot fail.

Parameters
[in]serviceActive portable service context.
[in]resultBounded backend pull already validated by the caller.
[out]outChunk message populated for packing.
Precondition
service, result, and out are non-null.
result was produced by internal_mdl_read_next for this pull.
Postcondition
out carries the pull's data and, when complete, its terminal metadata.
No allocation or backend I/O occurs.
Note
Not thread-safe for a shared service.
Since
0.1.0

Definition at line 528 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::active_job_id, internal_mdl_next_read_t::bytes, internal_mdl_next_read_t::complete, Ra8__Mdl__Chunk::content_type, ra8_mdl_http_response_t::content_type, Ra8__Mdl__Chunk::data, internal_mdl_next_read_t::digest, Ra8__Mdl__Chunk::etag, ra8_mdl_http_response_t::etag, internal_mdl_next_read_t::got, Ra8__Mdl__Chunk::http_status, Ra8__Mdl__Chunk::job_id, k_ra8_mdl_protocol_version, k_ra8_mdl_sha256_bytes, Ra8__Mdl__Chunk::last_modified, ra8_mdl_http_response_t::last_modified, ra8_mdl_service::next_offset, ra8_mdl_service::next_sequence, Ra8__Mdl__Chunk::offset, Ra8__Mdl__Chunk::protocol_version, ra8__mdl__chunk__init(), RA8__MDL__STATE__STATE_COMPLETE, RA8__MDL__STATE__STATE_DOWNLOADING, RA8_INTERNAL, internal_mdl_next_read_t::response, Ra8__Mdl__Chunk::retry_after, ra8_mdl_http_response_t::retry_after, Ra8__Mdl__Chunk::sequence, Ra8__Mdl__Chunk::sha256, Ra8__Mdl__Chunk::state, Ra8__Mdl__Chunk::status, ra8_mdl_http_response_t::status, internal_mdl_next_read_t::total, and Ra8__Mdl__Chunk::total_bytes.

Referenced by internal_mdl_dispatch_next().

◆ internal_mdl_check_response_size()

ra8_err_t internal_mdl_check_response_size ( size_t len,
size_t response_cap )
static

Reject a response that cannot fit before invoking the backend.

Centralises the no-partial-pack capacity contract.

Parameters
[in]lenRequired packed bytes.
[in]response_capCaller-owned response capacity.
Returns
Capacity status.
Return values
k_ra8_okThe complete response fits.
k_ra8_err_invalid_sizeLength is zero or exceeds capacity.
Precondition
Both values are expressed in bytes.
No backend side effect has occurred for the candidate response.
Postcondition
No state or output buffer is modified.
Success guarantees a bounded pack is possible.
Note
Pure and thread-safe.
Since
0.1.0

Definition at line 169 of file ra8_c6link_mdl_service.c.

References k_ra8_err_invalid_size, k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_mdl_dispatch_cancel(), internal_mdl_next_capacity(), internal_mdl_pack_accepted(), internal_mdl_pack_chunk(), and ra8_mdl_service_check_size_test().

◆ internal_mdl_decode_alloc()

void * internal_mdl_decode_alloc ( void * data,
size_t len )
static

Allocate one aligned span from a per-dispatch bounded arena.

Parameters
[in,out]datara8_mdl_decode_arena_t owned by the current dispatch.
[in]lenRequested bytes.
Returns
Allocated span or null when the arena is exhausted.
Return values
nullptrThe aligned request exceeds remaining arena capacity.
Precondition
data is non-null and exclusively owned.
used is no larger than the arena byte capacity.
Postcondition
Success advances used by the aligned size.
Failure leaves used unchanged.
Note
Reentrant for independent arenas.
Since
0.1.0

Definition at line 123 of file ra8_c6link_mdl_service.c.

References ra8_mdl_decode_arena::bytes, k_mdl_decode_align_mask, priv_c6link_mdl_decode_allocation_fits(), RA8_INTERNAL, and ra8_mdl_decode_arena::used.

Referenced by ra8_mdl_service_dispatch().

◆ internal_mdl_decode_free()

void internal_mdl_decode_free ( void * data,
void * ptr )
static

Ignore individual protobuf frees for the linear dispatch arena.

The complete arena is discarded when dispatch returns.

Parameters
[in]dataArena context retained for allocator ABI compatibility.
[in]ptrPreviously returned span retained for allocator ABI compatibility.
Precondition
data identifies the current dispatch arena.
ptr is null or belongs to that arena.
Postcondition
Arena state is unchanged.
No system allocator is invoked.
Note
Reentrant for independent arenas.
Since
0.1.0

Definition at line 148 of file ra8_c6link_mdl_service.c.

References RA8_INTERNAL.

Referenced by ra8_mdl_service_dispatch().

◆ internal_mdl_dispatch_cancel()

ra8_err_t internal_mdl_dispatch_cancel ( ra8_mdl_service_t * service,
ProtobufCAllocator * alloc,
const uint8_t * request,
size_t request_len,
uint8_t * response,
size_t response_cap,
size_t * response_len )
static

Validate and cancel one correlated active service job.

Packs the acknowledgement before asking the backend to release state.

Parameters
[in,out]serviceActive portable service.
[in,out]allocBounded per-dispatch protobuf allocator.
[in]requestPacked CancelRequest.
[in]request_lenValid request bytes.
[out]responseCaller-owned Cancelled bytes.
[in]response_capResponse capacity.
[out]response_lenPacked response length.
Returns
Cancellation status.
Return values
k_ra8_okBackend cancelled and acknowledgement was packed.
k_ra8_err_protocol_errorDecode failed or unknown fields were present.
k_ra8_err_invalid_stateJob correlation is invalid.
k_ra8_err_invalid_sizeAcknowledgement does not fit.
k_ra8_err_validation_failedCodec length and write disagree.
Precondition
All pointers are non-null and one job is active.
alloc owns a fresh bounded arena.
Postcondition
Success deactivates the service.
Backend failure leaves response length zero.
Note
Not thread-safe for a shared service/backend.
Since
0.1.0

Definition at line 649 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::active, ra8_mdl_service::active_job_id, ra8_mdl_service::backend, Ra8__Mdl__CancelRequest::base, ra8_mdl_service_backend::cancel, ra8_mdl_service_backend::ctx, internal_mdl_check_response_size(), Ra8__Mdl__Cancelled::job_id, Ra8__Mdl__CancelRequest::job_id, k_ra8_err_invalid_state, k_ra8_err_protocol_error, k_ra8_err_validation_failed, k_ra8_mdl_protocol_version, k_ra8_ok, Ra8__Mdl__Cancelled::protocol_version, Ra8__Mdl__CancelRequest::protocol_version, ra8__mdl__cancel_request__unpack(), ra8__mdl__cancelled__get_packed_size(), RA8__MDL__CANCELLED__INIT, ra8__mdl__cancelled__pack(), RA8_INTERNAL, and Ra8__Mdl__Cancelled::status.

Referenced by ra8_mdl_service_dispatch().

◆ internal_mdl_dispatch_next()

ra8_err_t internal_mdl_dispatch_next ( ra8_mdl_service_t * service,
ProtobufCAllocator * alloc,
const uint8_t * request,
size_t request_len,
uint8_t * response,
size_t response_cap,
size_t * response_len )
static

Validate one pull, read bounded bytes, and pack a correlated Chunk.

Proves worst-case response capacity before consuming backend bytes.

Parameters
[in,out]serviceActive portable service.
[in,out]allocBounded per-dispatch protobuf allocator.
[in]requestPacked NextRequest.
[in]request_lenValid request bytes.
[out]responseCaller-owned Chunk bytes.
[in]response_capResponse capacity.
[out]response_lenPacked response length.
Returns
Pull status.
Return values
k_ra8_okOne ordered data or terminal response was packed.
k_ra8_err_protocol_errorDecode, unknown fields, or backend fields are incoherent.
k_ra8_err_invalid_stateJob correlation or requested bound is invalid.
k_ra8_err_invalid_sizeWorst-case response does not fit.
Precondition
All pointers are non-null and one job is active.
alloc owns a fresh bounded arena.
Postcondition
Success advances sequence/offset by exactly returned body bytes.
Terminal success deactivates the service job.
Note
Not thread-safe for a shared service/backend.
Since
0.1.0

Definition at line 576 of file ra8_c6link_mdl_service.c.

References Ra8__Mdl__NextRequest::acknowledged_offset, ra8_mdl_service::active, ra8_mdl_service::active_job_id, Ra8__Mdl__NextRequest::base, internal_mdl_next_read_t::complete, internal_mdl_next_read_t::got, internal_mdl_build_chunk(), internal_mdl_fail_job(), internal_mdl_next_capacity(), internal_mdl_pack_chunk(), internal_mdl_read_next(), Ra8__Mdl__NextRequest::job_id, k_ra8_err_invalid_state, k_ra8_err_protocol_error, k_ra8_mdl_chunk_data_max, k_ra8_mdl_protocol_version, k_ra8_ok, Ra8__Mdl__NextRequest::max_bytes, ra8_mdl_service::next_offset, ra8_mdl_service::next_sequence, Ra8__Mdl__NextRequest::protocol_version, ra8__mdl__chunk__init(), ra8__mdl__next_request__unpack(), and RA8_INTERNAL.

Referenced by ra8_mdl_service_dispatch().

◆ internal_mdl_dispatch_start()

ra8_err_t internal_mdl_dispatch_start ( ra8_mdl_service_t * service,
ProtobufCAllocator * alloc,
const uint8_t * request,
size_t request_len,
uint8_t * response,
size_t response_cap,
size_t * response_len )
static

Validate and begin one typed-artifact service job.

Pre-packs the bounded response before allowing backend side effects.

Parameters
[in,out]serviceInitialised portable service.
[in,out]allocBounded per-dispatch protobuf allocator.
[in]requestPacked StartRequest.
[in]request_lenValid request bytes.
[out]responseCaller-owned Accepted bytes.
[in]response_capResponse capacity.
[out]response_lenPacked response length.
Returns
Start status.
Return values
k_ra8_okBackend accepted a correlated job.
k_ra8_err_protocol_errorDecode failed or unknown fields were present.
k_ra8_err_invalid_argVersion or URL is invalid.
k_ra8_err_busyA job is already active.
Precondition
All pointers are non-null and service access is exclusive.
alloc owns a fresh bounded arena.
Postcondition
Success activates exactly one non-zero job id.
Backend failure leaves the service inactive and response length zero.
Note
Not thread-safe for a shared service.
Since
0.1.0

Definition at line 304 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::active, Ra8__Mdl__StartRequest::base, Ra8__Mdl__Accepted::format, Ra8__Mdl__StartRequest::format, Ra8__Mdl__StartRequest::if_modified_since, Ra8__Mdl__StartRequest::if_none_match, internal_mdl_pack_accepted(), internal_mdl_start_valid(), Ra8__Mdl__Accepted::job_id, k_ra8_err_busy, k_ra8_err_invalid_arg, k_ra8_err_protocol_error, k_ra8_mdl_chunk_data_max, k_ra8_mdl_protocol_version, k_ra8_ok, Ra8__Mdl__Accepted::max_chunk_bytes, ra8_mdl_service::next_job_id, Ra8__Mdl__Accepted::protocol_version, RA8__MDL__ACCEPTED__INIT, ra8__mdl__start_request__unpack(), RA8_INTERNAL, Ra8__Mdl__StartRequest::referer, Ra8__Mdl__StartRequest::timeout_ms, Ra8__Mdl__StartRequest::url, and Ra8__Mdl__StartRequest::user_agent.

Referenced by ra8_mdl_service_dispatch().

◆ internal_mdl_fail_job()

ra8_err_t internal_mdl_fail_job ( ra8_mdl_service_t * service,
ra8_err_t error )
static

Cancel and deactivate one backend job after a terminal error.

Best-effort cancellation prevents another pull from observing a partially advanced backend after the service detects a terminal failure.

Parameters
[in,out]serviceActive portable service context.
[in]errorCanonical terminal status to preserve.
Returns
The unchanged caller-supplied terminal status.
Return values
errorThe exact value supplied in error.
Precondition
service is non-null and owns a bound backend.
The backend job is active or may safely accept idempotent cancellation.
Postcondition
The backend cancellation callback was attempted exactly once.
service->active is false regardless of cancellation status.
Note
Cancellation errors cannot replace the protocol/backend root cause.
Since
0.1.0

Definition at line 389 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::active, ra8_mdl_service::backend, ra8_mdl_service_backend::cancel, and ra8_mdl_service_backend::ctx.

Referenced by internal_mdl_dispatch_next(), and internal_mdl_read_next().

◆ internal_mdl_next_capacity()

ra8_err_t internal_mdl_next_capacity ( uint32_t max_data,
size_t response_cap )
static

Prove the worst-case Chunk for one request fits before backend I/O.

Measures a maximally encoded response using caller-requested data length and worst-case protobuf varints and digest fields.

Parameters
[in]max_dataMaximum body bytes permitted for this pull.
[in]response_capCapacity of the caller's packed-response buffer.
Returns
Canonical capacity status.
Return values
k_ra8_okEvery legal response for this pull fits.
k_ra8_err_invalid_sizeWorst-case packed response exceeds capacity.
Precondition
max_data does not exceed k_ra8_mdl_chunk_data_max.
response_cap is the actual writable response capacity.
Postcondition
No backend callback is invoked.
Service and caller buffers are unchanged.
Note
One bounded filler run supplies every length protobuf sizing reads.
Since
0.1.0

Definition at line 413 of file ra8_c6link_mdl_service.c.

References Ra8__Mdl__Chunk::content_type, Ra8__Mdl__Chunk::etag, Ra8__Mdl__Chunk::http_status, internal_mdl_check_response_size(), Ra8__Mdl__Chunk::job_id, k_ra8_mdl_content_type_max, k_ra8_mdl_etag_max, k_ra8_mdl_http_date_max, k_ra8_mdl_http_status_max, k_ra8_mdl_retry_after_max, k_ra8_mdl_sha256_bytes, k_ra8_ok, Ra8__Mdl__Chunk::last_modified, memset(), Ra8__Mdl__Chunk::offset, Ra8__Mdl__Chunk::protocol_version, ra8__mdl__chunk__get_packed_size(), ra8__mdl__chunk__init(), RA8__MDL__STATE__STATE_COMPLETE, RA8__MDL__STATE__STATE_DOWNLOADING, Ra8__Mdl__Chunk::retry_after, Ra8__Mdl__Chunk::sequence, Ra8__Mdl__Chunk::sha256, Ra8__Mdl__Chunk::state, and Ra8__Mdl__Chunk::total_bytes.

Referenced by internal_mdl_dispatch_next().

◆ internal_mdl_pack_accepted()

ra8_err_t internal_mdl_pack_accepted ( const Ra8__Mdl__Accepted * msg,
uint8_t * response,
size_t response_cap,
size_t * response_len )
static

Pack an Accepted response into a bounded caller buffer.

Verifies encoded size before invoking the generated packer.

Parameters
[in]msgValid generated Accepted message.
[out]responseCaller-owned packed bytes.
[in]response_capCapacity of response.
[out]response_lenExact packed length.
Returns
Packing status.
Return values
k_ra8_okResponse was packed exactly.
k_ra8_err_invalid_sizeResponse does not fit.
k_ra8_err_validation_failedCodec length and write disagree.
Precondition
Every pointer is non-null.
response_len is writable and response spans do not overlap msg.
Postcondition
Success sets response_len within capacity.
Failure does not report a successful length.
Note
Reentrant for independent buffers.
Since
0.1.0

Definition at line 195 of file ra8_c6link_mdl_service.c.

References internal_mdl_check_response_size(), k_ra8_err_validation_failed, k_ra8_ok, ra8__mdl__accepted__get_packed_size(), ra8__mdl__accepted__pack(), and RA8_INTERNAL.

Referenced by internal_mdl_dispatch_start().

◆ internal_mdl_pack_chunk()

ra8_err_t internal_mdl_pack_chunk ( const Ra8__Mdl__Chunk * msg,
uint8_t * response,
size_t response_cap,
size_t * response_len )
static

Pack a Chunk response into a bounded caller buffer.

Verifies encoded size before invoking the generated packer.

Parameters
[in]msgValid generated Chunk message.
[out]responseCaller-owned packed bytes.
[in]response_capCapacity of response.
[out]response_lenExact packed length.
Returns
Packing status.
Return values
k_ra8_okResponse was packed exactly.
k_ra8_err_invalid_sizeResponse does not fit.
k_ra8_err_validation_failedCodec length and write disagree.
Precondition
Every pointer is non-null.
response_len is writable and response spans do not overlap msg.
Postcondition
Success sets response_len within capacity.
Failure does not report a successful length.
Note
Reentrant for independent buffers.
Since
0.1.0

Definition at line 230 of file ra8_c6link_mdl_service.c.

References internal_mdl_check_response_size(), k_ra8_err_validation_failed, k_ra8_ok, ra8__mdl__chunk__get_packed_size(), ra8__mdl__chunk__pack(), and RA8_INTERNAL.

Referenced by internal_mdl_dispatch_next().

◆ internal_mdl_read_next()

ra8_err_t internal_mdl_read_next ( ra8_mdl_service_t * service,
uint32_t max_data,
internal_mdl_next_read_t * result )
static

Pull and validate one backend response without advancing service state.

Reads into fixed storage, proves byte/count/offset/terminal invariants, and cancels the job on any backend or protocol failure.

Parameters
[in,out]serviceActive portable service context.
[in]max_dataMaximum permitted body bytes.
[out]resultReceives bounded backend data and derived end offset.
Returns
Canonical backend or protocol status.
Return values
k_ra8_okResult is coherent and ready to pack.
k_ra8_err_protocol_errorBackend metadata violates the wire contract.
otherBackend read failure returned after cancellation.
Precondition
service and result are non-null.
Service owns an active job and max_data fits the result buffer.
Postcondition
Success does not change sequence or offset service state.
Failure attempts cancellation and deactivates the job.
Note
Terminal responses carry no data and must exactly close total length.
Since
0.1.0

Definition at line 479 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::backend, internal_mdl_next_read_t::bytes, internal_mdl_next_read_t::complete, ra8_mdl_service_backend::ctx, internal_mdl_next_read_t::digest, internal_mdl_next_read_t::end_offset, internal_mdl_next_read_t::got, internal_mdl_fail_job(), internal_mdl_response_valid(), k_ra8_err_protocol_error, k_ra8_ok, ra8_mdl_service::next_offset, ra8_mdl_service::next_sequence, ra8_mdl_service_backend::read, internal_mdl_next_read_t::response, ra8_mdl_http_response_t::status, and internal_mdl_next_read_t::total.

Referenced by internal_mdl_dispatch_next().

◆ internal_mdl_request_field_valid()

bool internal_mdl_request_field_valid ( const char * text,
size_t cap )
static

Validate one decoded optional request header.

Requires bounded single-line text so a remote request cannot inject additional ESP-IDF headers.

Parameters
[in]textDecoded protobuf string.
[in]capMaximum extent including NUL.
Returns
Header validity.
Return values
trueText terminates before cap and contains no CR/LF.
falsePointer, bound, termination, or line discipline is invalid.
Precondition
cap is nonzero.
Non-null text belongs to the current decode arena.
Postcondition
No decoded or service state is modified.
True authorizes passing the string to the backend.
Note
Empty strings are valid and mean header absent.
Since
0.1.0

Definition at line 58 of file ra8_c6link_mdl_service.c.

References RA8_INTERNAL, and strnlen().

Referenced by internal_mdl_response_valid(), internal_mdl_start_valid(), and ra8_mdl_service_field_valid_test().

◆ internal_mdl_response_valid()

bool internal_mdl_response_valid ( const ra8_mdl_http_response_t * response)
static

Validate fixed terminal response metadata returned by a backend.

Requires an HTTP-shaped status and independently bounds every selected header before any generated response points at backend storage.

Parameters
[in]responseCandidate status and selected headers.
Returns
Response validity.
Return values
trueStatus is HTTP-shaped and every array is bounded single-line text.
falseStatus or a selected header violates the protocol contract.
Precondition
response is non-null and fully initialized by the backend.
Every array is readable for its declared extent.
Postcondition
No response or service state is modified.
True authorizes protobuf packing of every selected header.
Note
Pure and reentrant.
Since
0.1.0

Definition at line 90 of file ra8_c6link_mdl_service.c.

References ra8_mdl_http_response_t::content_type, ra8_mdl_http_response_t::etag, internal_mdl_request_field_valid(), k_ra8_mdl_http_status_max, k_ra8_mdl_http_status_min, ra8_mdl_http_response_t::last_modified, RA8_INTERNAL, ra8_mdl_http_response_t::retry_after, and ra8_mdl_http_response_t::status.

Referenced by internal_mdl_read_next(), and ra8_mdl_service_response_valid_test().

◆ internal_mdl_start_valid()

bool internal_mdl_start_valid ( const Ra8__Mdl__StartRequest * request)
static

Validate every generated Start field before backend activation.

Checks the protocol version, HTTPS URL, format, timeout, and each optional request header before constructing the portable backend request.

Parameters
[in]requestDecoded generated request.
Returns
Field validity.
Return values
trueVersion, URL, format, timeout, and headers are bounded.
falseAt least one field is absent, malformed, or unsupported.
Precondition
request is non-null and owns decoded string pointers.
The bounded protobuf arena remains live.
Postcondition
No request, service, or backend state is modified.
True authorizes construction of ra8_mdl_request_t.
Note
HTTPS is the only accepted transport scheme.
Since
0.1.0

Definition at line 262 of file ra8_c6link_mdl_service.c.

References Ra8__Mdl__StartRequest::format, Ra8__Mdl__StartRequest::if_modified_since, Ra8__Mdl__StartRequest::if_none_match, internal_mdl_request_field_valid(), k_ra8_mdl_etag_max, k_ra8_mdl_http_date_max, k_ra8_mdl_protocol_version, k_ra8_mdl_referer_max, k_ra8_mdl_timeout_ms_max, k_ra8_mdl_url_max, k_ra8_mdl_user_agent_max, Ra8__Mdl__StartRequest::protocol_version, RA8__MDL__FORMAT__FORMAT_RABOOK, RA8_INTERNAL, Ra8__Mdl__StartRequest::referer, strncmp(), strnlen(), Ra8__Mdl__StartRequest::timeout_ms, Ra8__Mdl__StartRequest::url, and Ra8__Mdl__StartRequest::user_agent.

Referenced by internal_mdl_dispatch_start().

◆ priv_c6link_mdl_decode_allocation_fits()

bool priv_c6link_mdl_decode_allocation_fits ( size_t used,
size_t len,
size_t capacity )

Decide whether one aligned protobuf allocation fits an arena.

Rejects pre-alignment overflow before proving both total and remaining capacity for the fixed eight-byte protobuf alignment.

Parameters
[in]usedBytes already consumed from the arena.
[in]lenRequested allocation length before alignment.
[in]capacityTotal arena byte capacity.
Returns
Whether the aligned request fits without arithmetic overflow.
Return values
trueAlignment and remaining-capacity checks both succeed.
falseLength arithmetic overflows or the request exceeds capacity.
Precondition
All inputs are byte counts representable by size_t.
Alignment is the fixed media-service protobuf alignment.
Postcondition
No state or storage is modified.
True guarantees used + aligned(len) <= capacity.
Note
Pure, reentrant, and exposed only for focused private tests.
Since
0.1.0

Definition at line 101 of file ra8_c6link_mdl_service.c.

References k_mdl_decode_align_mask, and RA8_PRIV.

Referenced by internal_mdl_decode_alloc().

◆ ra8_mdl_service_check_size_test()

ra8_err_t ra8_mdl_service_check_size_test ( size_t len,
size_t response_cap )

Judge one packed-response length exactly as dispatch does.

Forwards unchanged to the module-private capacity predicate every pack path consults before it writes a byte into caller storage.

Parameters
[in]lenPacked length the generated codec reported.
[in]response_capCapacity of the caller's response buffer.
Returns
Canonical capacity status.
Return values
k_ra8_okThe packed response fits and is non-empty.
k_ra8_err_invalid_sizeThe length is zero or exceeds capacity.
Precondition
Both arguments are byte counts representable by size_t.
response_cap is the actual writable response capacity.
Postcondition
No service or caller state is modified.
Success guarantees a following pack of len bytes is in bounds.
Note
Test helper; pure and reentrant.
MC/DC:
The zero-length condition is unreachable through dispatch: every generated response carries a non-default protocol version, so the codec never reports zero. Only this seam can vary it independently of the capacity condition.
Since
0.1.0

Definition at line 700 of file ra8_c6link_mdl_service.c.

References internal_mdl_check_response_size(), and RA8_TEST_HELPER.

◆ ra8_mdl_service_dispatch()

ra8_err_t ra8_mdl_service_dispatch ( void * ctx,
uint32_t operation,
const uint8_t * request,
size_t request_len,
uint8_t * response,
size_t response_cap,
size_t * response_len )
nodiscard

Dispatch Start, Next, or Cancel generated protobuf payloads.

Decodes into the service-owned bounded arena, validates job correlation, and packs exactly one response into caller-owned storage.

Parameters
[in,out]ctxInitialised ra8_mdl_service_t.
[in]operationOne ra8_mdl_rpc_id_t value.
[in]requestPacked generated request bytes.
[in]request_lenValid request bytes.
[out]responseCaller-owned response bytes.
[in]response_capCapacity of response.
[out]response_lenPacked response length.
Returns
Dispatch status.
Return values
k_ra8_okA response was packed successfully.
k_ra8_err_null_ptrA required pointer is null.
k_ra8_err_invalid_argOperation or request fields are invalid.
k_ra8_err_invalid_stateA Start arrived while another job is active.
k_ra8_err_invalid_sizeA fixed request/response bound was exceeded.
k_ra8_err_protocol_errorJob, sequence, or offset did not correlate.
Precondition
ra8_mdl_service_init succeeded for ctx.
No concurrent call uses ctx or its backend.
Postcondition
Success sets response_len no larger than response_cap.
Failure sets response_len to zero after pointer validation.
Note
Synchronous and single-owner.
Since
0.1.0

Definition at line 715 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service::arena, internal_mdl_decode_alloc(), internal_mdl_decode_free(), internal_mdl_dispatch_cancel(), internal_mdl_dispatch_next(), internal_mdl_dispatch_start(), k_ra8_err_not_supported, k_ra8_err_null_ptr, k_ra8_mdl_rpc_cancel, k_ra8_mdl_rpc_next, and k_ra8_mdl_rpc_start.

Referenced by esp_hosted_custom_rpc_sync_handler().

◆ ra8_mdl_service_field_valid_test()

bool ra8_mdl_service_field_valid_test ( const char * text,
size_t cap )

Judge one decoded request header exactly as dispatch does.

Forwards unchanged to the module-private predicate, so a focused test drives the shipped bound and line-discipline logic rather than a copy.

Parameters
[in]textCandidate decoded protobuf string, or null.
[in]capMaximum extent including the terminating NUL.
Returns
Header validity.
Return values
trueText terminates before cap and contains no CR or LF.
falsePointer, bound, termination, or line discipline is invalid.
Precondition
cap is nonzero.
Non-null text is readable for at least cap bytes.
Postcondition
No service or caller state is modified.
True authorizes passing the string to the backend.
Note
Test helper; pure and reentrant.
MC/DC:
The CR/LF decision cannot be driven to its two single-byte vectors through ra8_mdl_service_dispatch, whose decoded strings would each need a distinct hand-packed protobuf request per condition.
Since
0.1.0

Definition at line 690 of file ra8_c6link_mdl_service.c.

References internal_mdl_request_field_valid(), and RA8_TEST_HELPER.

◆ ra8_mdl_service_init()

ra8_err_t ra8_mdl_service_init ( ra8_mdl_service_t * service,
const ra8_mdl_service_backend_t * backend )
nodiscard

Initialise portable service state with a complete backend seam.

Copies the callback table and resets all job correlation fields.

Parameters
[out]serviceCaller-owned service state.
[in]backendComplete backend callback table and context.
Returns
Initialisation status.
Return values
k_ra8_okService is ready to dispatch.
k_ra8_err_null_ptrA pointer, callback, or backend context is null.
Precondition
No request is executing against service.
backend and its context remain valid for the service lifetime.
Postcondition
Success leaves the service inactive and ready for Start.
Failure does not invoke a backend callback.
Note
Not thread-safe with concurrent dispatch on the same service.
Since
0.1.0

Definition at line 705 of file ra8_c6link_mdl_service.c.

References ra8_mdl_service_backend::begin, ra8_mdl_service_backend::cancel, k_ra8_err_null_ptr, k_ra8_ok, and ra8_mdl_service_backend::read.

Referenced by esp_hosted_custom_rpc_sync_handler().

◆ ra8_mdl_service_response_valid_test()

bool ra8_mdl_service_response_valid_test ( const ra8_mdl_http_response_t * response)

Judge one backend terminal response exactly as dispatch does.

Forwards unchanged to the module-private predicate that gates every COMPLETE response before its headers reach the generated packer.

Parameters
[in]responseCandidate status and selected headers.
Returns
Response validity.
Return values
trueStatus is HTTP-shaped and every header is bounded single-line.
falseStatus or a selected header violates the protocol contract.
Precondition
response is non-null and fully initialized.
Every array member is readable for its declared extent.
Postcondition
No service or caller state is modified.
True authorizes protobuf packing of every selected header.
Note
Test helper; pure and reentrant.
MC/DC:
Six conditions needing seven vectors. Reaching them through the public dispatch would require a backend that returns a different single malformed header per pull, which the read seam cannot express one condition at a time.
Since
0.1.0

Definition at line 695 of file ra8_c6link_mdl_service.c.

References internal_mdl_response_valid(), and RA8_TEST_HELPER.